当前位置:文档之家› DS1802HE LCD1602实现万年历和温度显示(不用时间芯片)

DS1802HE LCD1602实现万年历和温度显示(不用时间芯片)

#include<reg52.h>#include<intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="--Figo";//uchar code table1[]="";sbit lcden=P3^4;sbit lcdrs=P3^5;sbit dula=P2^6;sbit wela=P2^7;sbit ds=P1^7;sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;int tempValue;int s_1=1000;unsigned char FunKeyFlag=6,keypress;#define key_vaule1 0x01#define key_vaule2 0x02#define key_vaule3 0x03#define key_vaule4 0x04uchar num;int ms_10=10;int flag=0;int s_1_1=1000;uint sec=55;uint min=9;uint hour=22;uint nian=2014;uint yue=8;uint ri=20;uint xingqi=3;//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms. void delay_wendu(unsigned int i){unsigned int j;while(i--){for(j = 0; j < 125; j++);}}//初始化DS18B20//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动void dsInit(){//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us unsigned int i;ds = 0;i = 100; //拉低约800us, 符合协议要求的480us以上while(i>0) i--;ds = 1; //产生一个上升沿, 进入等待应答状态i = 4;while(i>0) i--;}void dsWait(){unsigned int i;while(ds);while(~ds);//检测到应答脉冲i = 4;while(i > 0) i--;}//向DS18B20读取一位数据//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,//之后DS18B20则会输出持续一段时间的一位数据bit readBit(){unsigned int i;bit b;ds = 0;i++;//延时约8us, 符合协议要求至少保持1usds = 1;i++; i++;//延时约16us, 符合协议要求的至少延时15us以上b = ds;i = 8;while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求return b;}//读取一字节数据, 通过调用readBit()来实现unsigned char readByte()unsigned int i;unsigned char j, dat;dat = 0;for(i=0; i<8; i++){j = readBit();//最先读出的是最低位数据dat = (j << 7) | (dat >> 1);}return dat;}//向DS18B20写入一字节数据void writeByte(unsigned char dat){unsigned int i;unsigned char j;bit b;for(j = 0; j < 8; j++){b = dat & 0x01;dat >>= 1;//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1if(b){ds = 0;i++;i++; //拉低约16us, 符号要求15~60us内ds = 1;i = 8;while(i>0)i--; //延时约64us, 符合写时隙不低于60us要求}else //写"0", 将DQ拉低60us~120usds = 0;i = 8; while(i>0) i--;//拉低约64us, 符号要求ds = 1;i++;i++;//整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了}}//向DS18B20发送温度转换命令void sendChangeCmd()dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化dsWait(); //等待DS18B20应答delay_wendu(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0x44); //写入温度转换命令字Convert T}//向DS18B20发送读取数据命令void sendReadCmd(){dsInit();dsWait();delay_wendu(1);writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0xbe); //写入读取数据令字Read Scratchpad}//获取当前温度值int getTmpValue(){unsigned int tmpvalue;int value; //存放温度数值float t;unsigned char low, high;sendReadCmd();//连续读取两个字节数据low = readByte();high = readByte();//将高低两个字节合成一个整形变量//计算机中对于负数是利用补码来表示的//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的valuetmpvalue = high;tmpvalue <<= 8;tmpvalue |= low;value = tmpvalue;//使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度t = value * 0.0625;//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入//如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度//如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5return value;}void HandleKeyPress() ;void KeyScan() //按键扫描{static unsigned char state=0;unsigned char temp;if (key1==0) temp=key_vaule1;else if (key2==0) temp=key_vaule2;else if (key3==0) temp=key_vaule3;else if (key4==0) temp=key_vaule4;else temp=0;switch (state){case 0: if(temp!=0) state=1;break;case 1: state=2; break;case 2: if(temp!=0) {state=3;keypress=temp;} else state=0; break;case 3: if(temp==0) {HandleKeyPress();state=0;} break;}}void HandleKeyPress() //按键功能的设置{ if (keypress==key_vaule1) //功能键的设置{FunKeyFlag=(FunKeyFlag+1)%7;}else if (keypress==key_vaule2) //第二个按键的设置{switch (FunKeyFlag){case 0:hour++;if(hour>23)hour=0;break;case 1:min++;if(min>59)min=0;break;case 2:sec++;if(sec>59)min=0;break;case 3:ri++;xingqi++;if(ri>30)ri=1;if(xingqi>7)xingqi=1;break;case 4:yue++;if(yue>12)yue=1;break;case 5:nian++;break;}}else if (keypress==key_vaule3) //第三个按键的设置{switch (FunKeyFlag){case 0:hour--;if(hour<0)hour=23;break;case 1:min--;if(min<0)min=59;break;case 2:sec--;if(sec<0)sec=59;break;case 3:ri--;xingqi--;if(ri<1)ri=31;if(xingqi<1)xingqi=1;break;case 4:yue--;if(yue<1)yue=12;break;case 5:nian--;break;}}else if (keypress==key_vaule4) //第四个按键的设置{switch (FunKeyFlag){case 0:hour=0;break;case 1:min=0;break;case 2:sec=0;break;case 3:ri=1;xingqi=1;break;case 4:yue=1;break;case 5:nian=2000;break;}}}void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com){lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date){lcdrs=1;P0=date;flag=1;delay(5);lcden=1;delay(5);lcden=0;}shijian_show(uchar wei,shijian ){uchar shi,ge;shi=shijian/10;ge=shijian%10;write_com(0x80+0x40+wei);write_data(0x30+shi);write_data(0x30+ge);}rili_show(uchar wei,rili ){uchar shi,ge;shi=rili/10;ge=rili%10;write_com(0x80+wei);write_data(0x30+shi);write_data(0x30+ge);}nian_show(uchar wei,shijian ){uchar shi,ge,qian,bai;qian=shijian/1000;bai=shijian%1000/100;shi=shijian%100/10;ge=shijian%10;write_com(0x80+wei);write_data(0x30+qian);write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);}wendu_show(uchar wei,int wendu ) {uchar shi,ge,qian,bai,xiao;qian=wendu/10000;bai=wendu%10000/1000;shi=wendu%1000/100;ge=wendu%100/10;xiao=wendu%10;write_com(0x80+0x40+wei);write_data(0x30+qian);write_data(0x30+bai);write_data(0x30+shi);// write_com(0x80+0x40+wei+1);write_data(0xdf);write_data(0x30+ge);write_data(0x30+xiao);}void init(){P0=0;dula=0;wela=0;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);}void week_show() //星期的显示{write_com(0x80+12);switch (xingqi){case 1:{write_data('M');write_data('o');write_data('n');}break;case 2:{write_data('T');write_data('u');write_data('e');}break;case 3:{write_data('W');write_data('e');write_data('d');}break;case 4:{write_data('T');write_data('h');write_data('u');}break;case 5:{write_data('F');write_data('r');write_data('i');}break;case 6:{write_data('S');write_data('a');write_data('t');}break;case 7:{write_data('S');write_data('u');write_data('n');}break;}}void main(){TMOD = 0x01;TH0 = (65536-1000)/256;TL0 = (65536-1000)%256;EA = 1;ET0 = 1;TR0 = 1;init();while(1){nian_show(1,nian);rili_show(6,yue);rili_show(9,ri);shijian_show(0,hour);shijian_show(3,min);shijian_show(6,sec);write_com(0x80+5);write_data(0x2d);write_com(0x80+8);write_data(0x2d);write_com(0x80+0x40+2);write_data(0x3A);write_com(0x80+0x40+5);write_data(0x3A);week_show();wendu_show(10,tempValue);}}void time() interrupt 1{TH0 = (65536-1000)/256;TL0 = (65536-1000)%256;ms_10--;s_1_1--;if(s_1_1<=0){s_1_1=1000; sendChangeCmd();//显示5次tempValue = getTmpValue(); //计算温度}if(ms_10<=0) //按键扫描{ms_10=10;KeyScan();}s_1--;if(s_1<=0){s_1=1000;sec++;if(sec>59){sec=0;min++;if(min>59){min=0;hour++;if(hour>23){hour=0;ri++;xingqi++;if(xingqi>7){xingqi=1;}if((yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)&&ri>31){ri=1;yue++;}else if(yue==2){if(nian%100!=0){if(nian%4==0){if(ri>29){ri=1;yue++;}}else if(nian%4!=0){if(ri>28){ri=1;yue++;}}}else if(nian%100==0){if(nian%400==0){if(ri>29){ri=1;yue++;}}else if(nian%400!=0){if(ri>28){ri=1;yue++;}}}}else if((yue==4||yue==6||yue==9||yue==11)&&ri>30){ri=1;yue++;}if(yue>12){nian++;yue=1;}}}}}}。

相关主题