- #include
- ***it CLK= P1^2;
- ***it DIO= P1^1;
- ***it CE= P1^0;
- ***it SET= P1^4; //设置键
- ***it ADD= P1^5; //加键
- ***it DEC= P1^6; //减键
- ***it ALAM= P1^3; //闹钟输出
- ***it DQ = P3^3; //18B20 I2C通讯口
- ***it xsdxs= P0^7;
- bit xsd;
- bit run_OR_Set=0; //正常走时/设置标志
- bit see_Tempreture=0; //查看温度标志位,=1时查看温度
- bit see_Timer=0; //查看闹钟
- bit zd=1; //整点报时位
- bit sd=0; //设置时闪动 =1时开启闪动
- unsigned char sd_char=0xFF; //闪动时置数
- unsigned char ZDJS=0; //整点计数
- unsigned char countt0; //t0中断计数器
- unsigned char countt1; //t1中断计数器
- unsigned char set_Count=0; //设置计数器,
- unsigned char setNZn=0; //设置闹钟计数器
- unsigned char NZ_hour=0,NZ_minit=1; //闹钟初值
- unsigned char BCD_NZ_hour,BCD_NZ_minit; //
- bit NZ=0; //闹钟标志位置
- unsigned char hour,minit,second,lastsecond;
- unsigned char temp_hour,temp_minit,temp_second;
- unsigned char code LED_DATA[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 共阴
-
- void delay(unsigned int time)
- {
- while(--time);
- }
- //==============================================================================
- //=============================DS18B20==========================================
- //==============================================================================
- unsigned char flag_Negative_number = 0;//负数标志
- //晶振12MHz
- void delay_18B20(unsigned int i)
- {
- while(i--);
- }
- //初始化函数
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ复位
- delay_18B20(4); //稍做延时
- DQ = 0; //单片机将DQ拉低
- delay_18B20(80); //精确延时 大于 480us //100
- DQ = 1; //拉高总线
- delay_18B20(14);
- x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
- delay_18B20(20);
- }
- //读一个字节
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给脉冲信号
- dat>>=1;
- DQ = 1; // 给脉冲信号
- if(DQ)
- dat|=0x80;
- delay_18B20(10);
- }
- return(dat);
- }
- //写一个字节
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay_18B20(10);
- DQ = 1;
- dat>>=1;
- }
- }
- //读取温度
- unsigned int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC); //跳过读序号列号的操作
- WriteOneChar(0x44); //启动温度转换
- Init_DS18B20();
- WriteOneChar(0xCC); //跳过读序号列号的操作
- WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- a=ReadOneChar();
- b=ReadOneChar();
- //启动下一次温度转换
- //Init_DS18B20();
- //WriteOneChar(0xCC); // 跳过读序号列号的操作
- //WriteOneChar(0x44); // 启动温度转换
-
- t=b;
- t<<=8;
- t=t|a;
- flag_Negative_number = 0;
- if(t>0x0fff)
- {
- t=~t+1;
- flag_Negative_number = 0xff;
- }
- //18b20:t=d*0.0625
- tt=t*0.0625;
- t=tt*10+0.5; //有效位到小数点后2位,适用Proteus6.9版本和实物版
- //t = t*5; //有效位到小数点后2位,适用Proteus7以上版本
- return(t);
- }
- //==============================================================================
- //==============================================================================
- //==============================================================================
- //==============================================================================
- //============================DS1302============================================
- //==============================================================================
- unsigned char du1302(unsigned char dizhi)
- {
- unsigned char i,jieguo;
- CLK=0;
- CE=1;
- for(i=0;i<8;i++)
- {
- DIO=dizhi& 0x01;
- CLK=1;CLK=0;
- dizhi=dizhi>>1;
- }
- DIO=1;
- jieguo=0;
- if(DIO==1){jieguo=jieguo|0x80;}
- for(i=0;i<7;i++)
- {
- CLK=1;CLK=0;
- jieguo=jieguo>>1;
- if(DIO==1){jieguo=jieguo| 0x80;}
- }
- CE=0;
- return(jieguo);
- }
- void xie1302(unsigned char dizhi,shuju)
- {
- unsigned char i;
- CE=1;
- for(i=0;i<8;i++)
- {
- DIO=dizhi& 0x01;
- CLK=1;CLK=0;
- dizhi=dizhi>>1;
- }
- for(i=0;i<8;i++)
- {
- DIO=shuju& 0x01;
- CLK=1;CLK=0;
- shuju=shuju>>1;
- }
- CE=0;
- }
- //========================================================================
- //========================================================================
- //========================================================================
- void display(void)
- {
- unsigned int temp;
- if(see_Tempreture==1) //---------------显示温度----------------------
- {
- temp = ReadTemperature();//*5;
-
- if(flag_Negative_number)
- P0 = 0x40;
- else
- P0 = 0x00;
- P2 = 0xBF;
- delay(300);
- P2 = 0xFF;
-
- P0 = LED_DATA[temp/100%10];
- P2 = 0xDF;
- delay(300);
- P2=0xFF;
-
- //P0 = LED_DATA[temp/10%10+10];
- P0 = LED_DATA[temp/10%10];
- P2 = 0xEF;
- delay(300);
- P2=0xFF;
-
- P0 = LED_DATA[temp%10];
- P2 = 0xF7;
- delay(300);
- P2=0xFF;
-
- P0 = 0x58;
- P2 = 0xFB;
- delay(300);
- P2=0xFF;
- }
- else
- {
- if(see_Timer==1) //------------显示闹钟--------------------
- {
- unsigned char D1,D2,D3,D4,D5,D6;
- D1=NZ_hour/10; D2=NZ_hour%10;
- D3=NZ_minit/10; D4=NZ_minit%10;
- D5=0; D6=0;
- if(setNZn==1)
- P0= (LED_DATA[D1]&sd_char); //display hour
- else
- P0= LED_DATA[D1];
- P2= 0x7F;
- delay(300);
- P2= 0xFF;
- if(setNZn==1)
- P0= ((LED_DATA[D2]|0x80)&sd_char);
- else
- P0= LED_DATA[D2]|0x80;
- //xsdxs=xsd;
- P2= 0xBF;
- delay(300);
- P2= 0xff;
-
- if(setNZn==2)
- P0= (LED_DATA[D3]&sd_char); //display minit
- else
- P0= LED_DATA[D3];
- P2= 0xDF;
- delay(300);
- P2=0xff;
- if(setNZn==2)
- P0= (LED_DATA[D4]&sd_char);
- else
- P0= LED_DATA[D4];
- P2= 0xEF;
- delay(300);
- P2=0xff;
-
- P0= LED_DATA[D5]; //display second
- P2= 0xF7;
- delay(300);
- P2=0xff;
- P0= LED_DATA[D6];
- P2= 0xFB;
- delay(300);
- P2=0xff;
- }
- else //--------------------显示时间-----------------
- {
- unsigned char D1,D2,D3,D4,D5,D6;
- if(run_OR_Set==1)
- second=0x00;
- else
- second= du1302(0x81);
- minit= du1302(0x83);
- hour= du1302(0x85);
- if(second!=lastsecond){xsd=!xsd;}
- lastsecond=second;
- D1=hour>>4; D2=hour&0x0f;
- D3=minit>>4; D4=minit&0x0f;
- D5=second>>4; D6=second&0x0f;
- if(set_Count==1)
- P0= (LED_DATA[D1]&sd_char); //display hour
- else
- P0= LED_DATA[D1];
- P2= 0x7F;
- delay(300);
- P2= 0xFF;
- if(set_Count==1)
- P0= ((LED_DATA[D2]|0x80)&sd_char);
- else
- P0= LED_DATA[D2]|0x80;
- //xsdxs=xsd;
- P2= 0xBF;
- delay(300);
- P2= 0xff;
-
- if(set_Count==2)
- P0= (LED_DATA[D3]&sd_char); //display minit
- else
- P0= LED_DATA[D3];
- P2= 0xDF;
- delay(300);
- P2=0xff;
- if(set_Count==2)
- P0= (LED_DATA[D4]&sd_char);
- else
- P0= LED_DATA[D4];
- P2= 0xEF;
- delay(300);
- P2=0xff;
-
- P0= LED_DATA[D5]; //display second
- P2= 0xF7;
- delay(300);
- P2=0xff;
- P0= LED_DATA[D6];
- P2= 0xFB;
- delay(300);
- P2=0xff;
- }
- }
- }
- void key_Scan(void)
- {
- if(SET==0) //SET键按下
- {
- display(); //调用显示,用于延时消抖
- if(SET==0)
- {
- TR1=0; //停止闹钟
- NZ=0;
- if(see_Tempreture==0)
- {
- if(see_Timer==0)
- {
- setNZn=0;
- second=0x00;
- run_OR_Set=1; //开启设置标志
- xie1302( 0x8E, 0x00);
- xie1302( 0x80, 0x80); //时钟停止走时
- xie1302( 0x8E, 0x80);
- set_Count++;
- TR0=1; //开启定时器0
- if(set_Count==3)
- {
- run_OR_Set=0; //关闭设置标志位
- set_Count=0; //设置计数器清零,
- TH0=0x3C;
- TL0=0xB0;
- TR0=0; //关闭定时器0
- sd=0; //关闭闪动
- sd_char=0xFF;
- xie1302( 0x8E, 0x00);
- xie1302( 0x80, 0x00); //时钟启动
- xie1302( 0x8E, 0x80);
- }
- }
- else
- {
- set_Count=0;
- setNZn++;
- TR0=1;
- if(setNZn==3)
- {
- setNZn=0;
- NZ=1; //开启闹钟
- BCD_NZ_hour=(((NZ_hour/10)<<4)+(NZ_hour%10)); //将闹钟时间转换为BCD数
- BCD_NZ_minit=(((NZ_minit/10)<<4)+(NZ_minit%10));
- TH0=0x3C;
- TL0=0xB0;
- TR0=0;
- sd=0;
- sd_char=0xFF;
- }
- }
- }
- }
- do
- display();
- while(!SET);
- }
- if(ADD==0)
- {
- display(); //调用显示,用于延时消抖
- if(ADD==0)
- {
- if(TR1==1)
- {
- TR1=0;
- ALAM=1;
- }
- else
- {
- if(see_Tempreture==0)
- {
- if(set_Count==0)
- {
- if(setNZn==0)
- {
- see_Timer=~see_Timer; //开启查看闹钟功能
- see_Tempreture=0;
- }
- if(setNZn==1)
- {
- NZ_hour++;
- if(NZ_hour==24)
- NZ_hour=0;
- }
- if(setNZn==2)
- {
- NZ_minit++;
- if(NZ_minit==60)
- NZ_minit=0;
- }
- }
-
- if(set_Count==1) //调小时
- {
- hour++;
- if((hour&0x0f)>=10) //控制十进制进位
- {
- hour=hour+0x10;
- hour=hour&0xf0;
- }
-
- if(hour>=0x24) //1302内部以16进制保存数据
- hour=0;
-
- xie1302( 0x8E, 0x00); //将转换后的小时数据写入1302
- xie1302( 0x80, 0x80);
- xie1302( 0x84,hour);
- xie1302( 0x8E, 0x80);
-
- }
- if(set_Count==2) //调分钟
- {
- minit++;
- if((minit&0x0f)>=0x0A) //十进制进位
- {
- minit=minit+0x10;
- minit=minit&0xf0;
- }
- if(minit>=0x60)
- minit=0;
-
- xie1302( 0x8E, 0x00);
- xie1302( 0x80, 0x80);
- xie1302( 0x82,minit);
- xie1302( 0x8E, 0x80);
- }
- }
- }
- }
- do
- display();
- while(!ADD);
- }
- if(DEC==0)
- {
- display(); //调用显示,用于延时消抖
- if(DEC==0)
- {
- if(set_Count==0)
- {
- if(setNZn==0)
- {
- see_Tempreture=~see_Tempreture; //当在非设置状态下可以查看温度
- see_Timer=0;
- }
- if(setNZn==1)
- {
- if(NZ_hour==0)
- NZ_hour=24;
- NZ_hour--;
- }
- if(setNZn==2)
- {
- if(NZ_minit==0)
- NZ_minit=60;
- NZ_minit--;
- }
- }
-
- if(set_Count==1) //调小时
- {
- if((hour&0x0f)>0x00)
- hour--;
- else
- {
- if((hour&0xf0)>0x00)
- {
- hour=hour-0x10;
- hour=hour+0x09;
- }
- else
- hour=0x23;
- }
-
- xie1302( 0x8E, 0x00);
- xie1302( 0x80, 0x80);
- xie1302( 0x84,hour);
- xie1302( 0x8E, 0x80);
- }
- if(set_Count==2) //调分钟
- {
- if((minit&0x0f)>0x00)
- minit--;
- else
- {
- if((minit&0xf0)>0x00)
- {
- minit=minit-0x10;
- minit=minit+0x09;
- }
- else
- minit=0x59;
- }
-
- xie1302( 0x8E, 0x00);
- xie1302( 0x80, 0x80);
- xie1302( 0x82,minit);
- xie1302( 0x8E, 0x80);
- }
-
- }
- do
- display();
- while(!DEC);
- }
- }
- main()
- {
- unsigned char temp_second;
- xie1302( 0x90, 0xa5);
- Init_DS18B20();
- delay(5000);
- TMOD=0x11;
- TH0=0x3C;
- TL0=0xB0;
- TH1=0x3C;
- TL1=0xB0;
- EA=1;
- ET0=1;
- ET1=1;
- TR0=0;
- TR1=0;
- while(1)
- {
- key_Scan();
- display();
- if(NZ==1)
- {
- if((hour==BCD_NZ_hour)&&(minit==BCD_NZ_minit)&&(second==0))
- TR1=1;
- if(minit==(BCD_NZ_minit+1))
- {
- TR1=0;
- ALAM=1;
- }
- }
-
- if((minit==0x00)&&(second==0x00)) //整点
- {
- TR1=1;
- temp_second=second;
- }
-
- if((minit==0x00)&&(second==hour))
- {
- TR1=0;
- ALAM=1;
- }
- }
- }
- void Initime0(void) interrupt 1
- {
- TH0=0x3C;
- TL0=0xB0;
- TR0=1;
- countt0++;
- if(countt0==5)
- {
- countt0=0;
- sd=!sd;
- if(sd==1)
- sd_char=0x00;
- else
- sd_char=0xFF;
- }
- }
- void Initime1(void) interrupt 3
- {
- TH1=0x3C;
- TL1=0xB0;
- countt1++;
- TR1=1;
- if(countt1==10)
- {
- countt1=0;
- ALAM=~ALAM;
- }
- key_Scan();
- }
复制代码
|