单片机源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar i;
- sbit RS=P3^0;
- sbit RW=P3^1;
- sbit E=P3^2;//LCD的RS RW E三个端口的定义
- sbit BF=P2^7;
- sbit d1=P1^0;
- sbit d2=P1^1;//警报定义
- sbit key=P1^5;//总开关控制标志位
- sbit key1=P1^6;//加开关
- sbit key2=P1^7;//减开关
- uchar code t0[]="0000-00-00";
- uchar code t1[]="T:";
- uchar code t2[]="00:00:00";
- uchar code t3[]="Mon ";//清屏显示
- uchar code wendu[]="0123456789";//定义数字,以方便显示温度以及时间
- uchar code weeks[]="Mon Tue Wed Thu Fri Sat Sun ";//定义一到星期天
- sbit DQ = P3^7;//DQ的数据线输入输出口
- uchar Temp;
- void delay(uint z)
- {
- uint x,y;
- for(x=20;x>1;x--)
- for(y=z;y>1;y--);
- }//延迟函数
- bit BusyTest(void)//忙检测指令。对寄存器的操作,如果忙返回1,如果空闲返回0
- {
- bit result;
- RS=0;
- RW=1;//RS=0;RW=1时可以读寄存器的状态
- E=1; //E=1才允许读写
- _nop_(); //空操作,主要作用类似于延迟
- _nop_();
- _nop_();
- _nop_();
- result=BF; //将忙碌标志位赋值给result作为忙检测指令的返回值
- E=0; //将E重新置为低电平
- return result;
- }
- void write_com(uchar com)//写命令
- {
- while(BusyTest()==1); //如果忙就等待
- RS=0;
- RW=0;
- P2=com;
- delay(5);
- E=1;
- delay(5);
- E=0;
- }
- void write_date(uchar date)//写数据
- {
- while(BusyTest()==1); //如果忙就等待
- RS=1;
- RW=0;
- P2=date;
- delay(5);
- E=1;
- delay(5);
- E=0;
- }
- void init_lcd()//初始化
- {
- E=0;
- RW=0;
- write_com(0x38);//LCD初始化设置 (显示模式设置:16X2显示,8位数据接口)
- write_com(0x01);//清屏,将以前的显示清除
- write_com(0x0c);//开显示。无光标,光标不闪烁
- write_com(0x06);//让光标右移,字符不移动
- write_com(0x80);//初始化位置(第一行第一列)
- for(i=0;i<10;i++)
- {
- write_date(t0[i]);
- delay(0);//显示"0000-00-00";
- }
- write_com(0x80+13);
- for(i=0;i<4;i++)
- {
- write_date(t3[i]);//显示"Mon "
- delay(0);
- }
- write_com(0x80+0x40);
- for(i=0;i<8;i++)
- {
- write_date(t2[i]);//显示"00:00:00"
- delay(0);
- }
- write_com(0x80+0x40+10);
- for(i=0;i<2;i++)
- {
- write_date(t1[i]);//显示"T:"
- delay(0);
- }
-
- }
- void tmpDelay(int num)//做延迟用
- {
- while(num--) ;
- }
- void Init_DS18B20()//初始化设置
-
- {
- unsigned char x=0;
- DQ = 1; //先将数据线拉高
- tmpDelay(8);
- DQ = 0; //再将数据从高拉到低 。要求保持480~960us
- tmpDelay(80);//延迟略微在480~960us,以向DS18B20发出一持续的480~960us低电平复位脉冲
- DQ = 1; //释放数据线,将数据线拉高
- tmpDelay(14);//延迟给硬件反应时间
- // x=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在),可有可无
- tmpDelay(20);
- }
- unsigned char ReadOneChar()//读一个字节
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0;
- dat>>=1;
- DQ = 1;
- if(DQ)
- dat|=0x80;
- tmpDelay(4);
-
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)//写一个字节数据
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- tmpDelay(5);
- DQ = 1;
- dat>>=1;
- }
- }
- unsigned int Readtemp()
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();//初始化
-
- WriteOneChar(0xCC); //跳过ROM
- WriteOneChar(0x44); //温度转换
- Init_DS18B20();//初始化,每次执行都要初始化
- WriteOneChar(0xCC); //跳过ROM
- WriteOneChar(0xBE);//存暂存器
- a=ReadOneChar(); //将低两位放在a中
- b=ReadOneChar(); //将高两位放在b中
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.0625;
- t= tt*10+0.5;
- return(t);
- }
- unsigned int num,num1;
- void display()//动态显示
- {
- unsigned int num,num1;
- unsigned int shi,ge,xiaoshu;
-
- num=Readtemp();
- num1=num/10;
-
- /*****温度高于100度或者低于10度时警报器响红灯亮*****/
- if(num1>100)
- {
- d1=0;d2=0;
- }
- else if(num1<10)
- {
- d1=0;d2=0;
- }
- else
- {
- d1=1;d2=1;
- }
- /*********************************************/
- shi=num/100;//温度的十位
- ge=num/10%10;//温度的个位
- xiaoshu=num%10;//温度的小数位
- write_com(0x80+0x40+12);//显示的位置
- write_date(wendu[shi]);//显示十位
- write_com(0x80+0x40+13);//显示的位置
- write_date(wendu[ge]);//显示个位
- write_com(0x80+0x40+14);//显示的位置
- write_date(0x2e);//显示小数点
- write_com(0x80+0x40+15);//显示的位置
- write_date(wendu[xiaoshu]);//显示十位
- }
- unsigned char shis=23,fen=59,miao=50;//定义时分秒
- unsigned int nian=2017,yue=5,ri=24,xingqi=8,k=0;//定义年月日
- void LCD_time()//时间
- {
- /**********年月日*****************/
- write_com(0x80);
- write_date(wendu[nian/1000]);//千位
- write_date(wendu[nian%1000/100]);//百位
- write_date(wendu[nian%100/10]);//十位
- write_date(wendu[nian%10]);//个位
- write_com(0x80+5);
- write_date(wendu[yue/10]);
- write_date(wendu[yue%10]);
- write_com(0x80+8);
- write_date(wendu[ri/10]);
- write_date(wendu[ri%10]);
- /***********星 期****************/
- write_com(0x80+13);
- for(k=0+xingqi;k<4+xingqi;k++)
- {
- write_date(weeks[k]);
- }
- /***********时分秒***************/
- write_com(0x80+0x40);
- write_date(wendu[shis/10]);
- write_date(wendu[shis%10]);
- write_com(0x80+0x40+3);
- write_date(wendu[fen/10]);
- write_date(wendu[fen%10]);
- write_com(0x80+0x40+6);
- write_date(wendu[miao/10]);
- write_date(wendu[miao%10]);
- }
- /*************************************
- 函数功能:秒钟走动时,时,分 年 月 日以及星期的换算
- **************************************/
- void zou()
- {
- if(fen==60)
- {
- fen=0;
- shis++;
- }
- if(shis==24)
- {
- shis=0;
- ri++;
- xingqi+=4;
- if(xingqi==28)
- xingqi=0;
- }
- if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
- {
- if(ri==32)
- {
- ri=1;
- yue++;
- }
- }
- else if(yue==2&&((nian%400==0)||(nian%4==0&&nian%100!=0)))
- {
- if(ri==30)
- {
- ri=1;
- yue++;
- }
- }
-
- else if(yue==4||yue==6||yue==9||yue==11)
- {
- if(ri==31)
- {
- ri=1;
- yue++;
- }
- }
- else
- {
- if(ri==29)
- {
- ri=1;
- yue++;
- }
- }
- if(yue==13)
- {
- yue=1;
- nian++;
- }
- }
- /*******************************************************
- 函数功能:总开关控制调时间的标识为Temp,Temp为1时可调秒
- Temp为2时,调分依次到可调年后Temp重置为0,时间继续走
- *******************************************************/
- void keys()
- {
- if(key==0)
- {
- delay(10);
- if(key==0)
- {
- while(key==0)
- display();
- TR0=0;
- Temp++;
- if(Temp==8)
- {
- Temp=0;
- TR0=1;
- }
- }
- }
- }
- /*定义以下函数*/
- void mins(uchar);
- uchar key_button(uchar Times,Temp);
- uint key_nian(uint Times);
- void key_Temp(uchar Temp);
- uchar key_xingqi(uchar Times);
- uchar Y;
- void main()
- {
- EA=1;
- ET0=1;
- TMOD=0X01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- TR0=1;//时钟的初始化
- init_lcd();//初始化LCD
- d1=1;d2=1;
- while(1)
- {
- display();//温度显示
- zou();//判断时间之间的运算,实现秒钟走可以控制时分,年月日以及星期的换算
- key_Temp(Temp);//根据标识位置确定可以调节那个时间
- keys();//总开关
- LCD_time();//时间显示
- }
- }
- void int0() interrupt 1 //定时器中断1
- {
- unsigned char ms;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- ms++;
- if(ms==20)
- {
- ms=0;
- miao++;
- if(miao==60)
- {
- miao=0;
- fen++;
- }
- }
- }
- /********************************************************/
- void key_Temp(uchar Temp)//实现调节时钟时闪烁的效果,
- {
- switch(Temp)
- {
- case 1:
- Y=5;
- while(Y--){ mins(Temp); miao=key_button(miao,1);keys();}
- Y=5;
- while(Y--){ LCD_time(); miao=key_button(miao,1);keys();}
- break;
- case 2:
- Y=5;
- while(Y--){ mins(Temp); fen=key_button(fen,2);keys();}
- Y=5;
- while(Y--){ LCD_time(); fen=key_button(fen,2);keys();}
- break;
- case 3:
- Y=5;
- while(Y--){ mins(Temp); shis=key_button(shis,3);keys();}
- Y=5;
- while(Y--){ LCD_time(); shis=key_button(shis,3);keys();}
- break;
- case 4:
- Y=5;
- while(Y--){ mins(Temp); xingqi=key_xingqi(xingqi);keys();}
- Y=5;
- while(Y--){ LCD_time(); xingqi=key_xingqi(xingqi);keys();}
- break;
- case 5:
- Y=5;
- while(Y--){ mins(Temp); ri=key_button(ri,Temp);keys();}
- Y=5;
- while(Y--){ LCD_time(); ri=key_button(ri,Temp);keys();}
- break;
- case 6:
- Y=5;
- while(Y--){ mins(Temp); yue=key_button(yue,Temp);keys();}
- Y=5;
- while(Y--){ LCD_time(); yue=key_button(yue,Temp);keys();}
- break;
- case 7:
- Y=5;
- while(Y--){ mins(Temp); nian=key_nian(nian);keys();}
- Y=5;
- while(Y--){ LCD_time(); nian=key_nian(nian);keys();}
- break;
- }
- }
- /********************************************************/
- uchar key_button(uchar Times,Temp)//月、日、时分秒
- {
- if(key1==0)
- {
- delay(10);
- if(key1==0)
- {
- while(key1==0)
- LCD_time();
- Times++;
- if(Temp==3)
- {
- if(Times==24)
- Times=0;
- }
- else if(Temp==1||Temp==2)
- {
- if(Times==60)
- Times=0;
- }
- else if(Temp==5)
- {
- if(Times==32)
- Times=0;
- }
- else if(Temp=6)
- {
- if(Times==13)
- Times=0;
- }
-
-
- }
-
- }
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- while(key2==0)
- display();
- Times--;
- if(Temp==3)
- {
- if(Times==255)
- Times=23;
- }
- else if(Temp==1||Temp==2)
- {
- if(Times==255)
- Times=59;
- }
- else if(Temp==5)
- {
- if(Times==255)
- Times=31;
- }
- else if(Temp==6)
- {
- if(Times==255)
- Times=12;
- }
- }
-
- }
- return Times;
- }
- /********************************************************/
- uint key_nian(uint Times)//年的加减
- {
- if(key1==0)
- {
- delay(10);
- if(key1==0)
- {
- while(key1==0)
- display();
- Times++;
- }
-
- }
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- while(key2==0)
- display();
- Times--;
- if(Times==1980)
- Times=1980;
- }
-
- }
- return Times;
- }
- /********************************************************/
- uchar key_xingqi(uchar Times)//星期的加减
- {
- if(key1==0)
- {
- delay(10);
- if(key1==0)
- {
- while(key1==0)
- display();
- Times+=4;
- if(Times==28)
- Times=0;
- }
-
- }
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- while(key2==0)
- display();
- Times-=4;
- if(Times==-4)
- Times=24;
- }
-
- }
- return Times;
- }
- void mins(uchar Temp)//不显示shijian的动态显示
- {
- /**********年月日*****************/
- write_com(0x80);
- if(Temp==7)
- {
- write_date(' ');
- write_date(' ');
- write_date(' ');
- write_date(' ');
- }
- else
- {
- write_date(wendu[nian/1000]);//千位
- write_date(wendu[nian%1000/100]);//百位
- write_date(wendu[nian%100/10]);//十位
- write_date(wendu[nian%10]);//个位
- }
- write_com(0x80+5);
- if(Temp==6)
- {
- write_date(' ');
- write_date(' ');
- }
- else
- {
- write_date(wendu[yue/10]);
- write_date(wendu[yue%10]);
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
wenduji.zip
(114.92 KB, 下载次数: 31)
|