- #include<reg52.h> //包含reg52.h库文件
- #include<i2c.h>
- #include<math.h> //包含绝对值函数
- #define uint unsigned int //宏定义uint
- #define uchar unsigned char //宏定义uchar
- sbit lcden=P2^7; //液晶使能端
- sbit lcdrw=P2^5;
- sbit lcdrs=P2^6; //液晶数据命令选择端选择写数据还是写命令
- sbit DQ = P3^7; //通过DQ口读取温度值
- sbit s1=P1^1; //选择按键
- sbit s2=P1^2; //加按键
- sbit s3=P1^3; //减按键
- sbit s4=P1^4;
- sbit beep=P1^0; //蜂鸣器
- uchar temp_value,num=0,fig,s1num,figh,figl,t; //设置全局无符号字符型变量
- char h,l; //设置全局有符号字符型变量
- void delay(uint z); //申明延时程序
- void init(); //申明LCD初始化程序
- void write_com(uchar com); //申明写命令程序
- void write_data(uchar date); //申明写数据程序
- void keyscan(); //申明按键扫描程序
- void write_hl(uchar add,char date); //申明设置的最高低温度值在LCD上显示程序
- void write_temp_value(uchar add,char date); //申明温度值在LCD上显示程序
- void delay_18B20(unsigned int i); //申明延时程序
- void Init_DS18B20(void); //申明DS18B20初始化程序
- unsigned char ReadOneChar(void); //申明ds18b20读一个字节
- void WriteOneChar(uchar dat); //申明ds18b20读一个字节
- void ReadTemp(void); //申明读取ds18b20当前温度
- void comp();
- void main()
- {
- init(); //LCD初始化
- Init_DS18B20(); //DS18B20初始化
- while(1) //大循环
- { if(s1==0||s1num>=1)
- { keyscan(); //按键扫描
- }
- else{ ReadTemp(); //读取温度值
- write_temp_value(0,temp_value); //LCD显示温度值
- }
- comp();
- }
- }
- void delay(uint z) //延时程序
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void init() //LCD初始化程序
- { lcden=0;
- lcdrw=0;
- write_com(0x38); //设置16x2 显示5x7 点阵,8 位数据接口
- write_com(0x0c); //设置开始显示不显示光标
- write_com(0x06); //写一个字符后地址指针加1
- write_com(0x01); //显示清零数据指针清零
- write_com(0x80); //将数据指针第一行第一个字处,
-
- write_com(0x80+9); //定义当前指针位置
- write_data('H'); //写入
- write_data(':'); //写入
- write_data('+'); //写入
- write_data('5'); //写入
- write_data('0'); //写入
- write_data(0xdf); //写入°
- write_data('C'); //写入C
- write_com(0x80+9+0x40); //定义当前指针位置
- write_data('L'); //写入
- write_data(':'); //写入
- write_data('-'); //写入
- write_data('1'); //写入
- write_data('0'); //写入
- write_data(0xdf); //写入°
- write_data('C'); //写入C
- h=0x32;
- l=0-0x0a; //h=45
- beep=1;
- beep=1;
- figh=0; //给正确初始值,便于上电比较
- figl=1; //给正确初始值,便于上电比较
- }
- void write_com(uchar com) //写命令程序
- { lcdrs=0; //设置为写入命令
- P0=com; //将命令赋给P0 口
- delay(5); //延时
- lcden=1; //打开LCD使能,输入一个高脉冲
- delay(5); //延时
- lcden=0; //置低完成高脉冲
- }
- void write_data(uchar date) //写数据程序
- { lcdrs=1; //设置为写入数据
- P0=date; //将数据赋给P0 口
- delay(5); //延时
- lcden=1; //打开LCD使能,输入一个高脉冲
- delay(5); //延时
- lcden=0; //置低完成高脉冲
- }
- void write_temp_value(uchar add,char date) //读取的温度值在LCD上显示程序
- { uchar bai,shi,ge,xiao;
- bai=date/100;
- shi=date%100/10;
- ge=date%10; //分离出百,十,个位数
- date=date&0x0f;
- xiao=date*0.0625;
- if((bai|shi)==0) //如果百十都等于0
- shi=0x70; //十赋值0x70,以便十位写入空字符,write_data(0x30+shi),参考1602字符图形码
- if(bai==0)
- bai=0x70;
- write_com(0x80+add); //设置当前光标位置,准备写数据
-
- if(fig==0&&shi!=0x70) //如果温度为负且十位不等于0(如果十位等于0,shi=0x70)
- { write_data('-'); //在百位写入负号
- write_data(0x30+shi); //写入十位数据
- }
- if(fig==0&&shi==0x70) //如果温度为负且百十位都等于0
- { write_data(0x30+0x70); //在百位写入一个空字符
- write_data('-'); //在十位写入负号
- }
- if(fig==1)write_data(0x30+bai); //温度正,写入百位数据
- if(fig==1)write_data(0x30+shi); //温度正,写入十位数据
- write_data(0x30+ge); //写入个位数据
- write_data('.');
- write_data(((xiao*10))%10+'5');
- write_data(0xdf); //写入°
- write_data('C'); //写入C
-
- }
- void write_hl(uchar add,char date) //设置的高低温度值在LCD上显示程序
- { uchar bai,shi,ge;
- bai=date/100;
- shi=date%100/10;
- ge=date%10; //分离出百,十,个位数
- write_com(0x80+add); //设置当前光标位置,准备写数据
-
- if(t==1&&shi!=0) //如果温度为负且十位不等于0(如果十位等于0,shi=0x70) 负数:百位第1种情况,写-
- { write_data('-');} //在百位写入负号
- if(t==1&&shi==0) //如果温度为负且百十位都等于0 负数:百位第2种情况,写空
- { write_data(0x30+0x70); //在百位写入一个空字符
- write_data('-'); //在十位写入负号 负数:十位第1种情况,写-
- }
- if(t==1&&shi!=0) //如果温度为负且十不等于0 负数:十位第2种情况,写数
- {write_data(0x30+shi);} //在十位写入数据
- if(t==0&&bai==0&&shi!=0) //否则温度为正,如果bai=0且shi!=0 正数:百位第1种情况,写+
- {write_data('+');} //在百位写入+
- if(t==0&&bai==0&&shi==0) //否则温度为正,如果bai=0且shi=0 正数:百位第2种情况,写空
- {write_data(0x30+0x70);} //在百位写入一个空字符
- if(t==0&&bai!=0)
- {write_data(0x30+bai);} //否则百位为正不等于0,写入百位数 正数:百位第3种情况,写数
- if(t==0&&bai==0&&shi==0&&ge!=0) //如果百十等于0,个不等于0 正数:十位第1种情况,写+
- {write_data('+');} //在十位写入+
- if(t==0&&bai==0&&shi==0&&ge==0) //如果百十个都等于0
- {write_data(' ');} //在十位写入空字符 正数:十位第2种情况,写空
- if(t==0&&shi!=0)
- {write_data(0x30+shi);} //在十位写入数 正数:十位第3种情况,写数
- write_data(0x30+ge); //写入个位数据
- }
- /***********ds18b20子程序*************************/
- /***********ds18b20延迟子函数(晶振12MHz )*******/
- void delay_18B20(unsigned int i)
- {
- while(i--);
- }
- /**********ds18b20初始化函数**********************/
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ复位
- delay_18B20(8); //稍做延时
- DQ = 0; //单片机将DQ拉低
- delay_18B20(80); //精确延时 大于 480us
- DQ = 1; //拉高总线
- delay_18B20(14);
- x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
- delay_18B20(20);
- }
- /***********ds18b20读一个字节**************/
- unsigned char ReadOneChar(void)
- {
- uchar i=0;
- uchar dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给脉冲信号
- dat>>=1;
- DQ = 1; // 给脉冲信号
- if(DQ)
- dat|=0x80;
- delay_18B20(4);
- }
- return(dat);
- }
- /*************ds18b20写一个字节****************/
- void WriteOneChar(uchar dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay_18B20(5);
- DQ = 1;
- dat>>=1;
- }
- }
- /**************读取ds18b20当前温度************/
- void ReadTemp(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned char t=0;
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳过读序号列号的操作
- WriteOneChar(0x44); // 启动温度转换
- delay_18B20(100); // this message is very important
- Init_DS18B20();
- WriteOneChar(0xCC); //跳过读序号列号的操作
- WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- delay_18B20(100);
- a=ReadOneChar(); //读取温度值低位
- b=ReadOneChar(); //读取温度值高位
- // a=0xff; //测试无法读取-16度的问题
- // b=0xfe;
- temp_value=b<<4; //temp_value=b左移动4位 , 转换成10进制
- temp_value+=(a&0xf0)>>4; //temp_value=temp_value+((a&0xf0)>>4) 转换成10进制
- fig=0x01; //设置fig=1温度正
- if(temp_value>0x7f) //如果temp_value大于0x7f,即为负数区,参考DS18B20datasheet
- {fig=0; //设置fig=0温度负,以便判断显示
- a=~a+1; //将读取的温度转换成10进制数
- b=~b;
- temp_value=b<<4; //temp_value=b左移动4位 , 转换成10进制
- temp_value+=(a&0xf0)>>4; //temp_value=temp_value+((a&0xf0)>>4) 转换成10进制
- }
- }
- void keyscan() //按键扫描
- { if(s1==0) //如果s1按下,执行下面程序
- { delay(5); // 延时一会
- if(s1==0) //如果s1确实按下,执行下面程序
- { s1num++; //s1num自加1
- while(!s1); //如果s1松开,执行下面程序,否则一直停在这
- if(s1num==1) //如果s1只按一次,执行下面
- {
- write_com(0x80+13); //设置当前指针位置
- write_com(0x0f); //写入光标闪烁命令
- }
- if(s1num==2) //如果s1按2次,执行下面
- {
- write_com(0x80+0x40+13); //设置当前指针位置,光标闪
- }
- if(s1num==3) //如果s1按3次,执行下面
- { s1num=0; //s1num清0
- write_com(0x0c); //写入光标不闪烁命令
- }
- }
- }
-
- if(s2==0) //如果s2按下,执行下面程序
- { delay(5); //延时
- if(s2==0); //如果s2按下,执行下面程序
- {
- while(!s2); //如果s2松开,执行下面程序,否则一直停在这
- if(s1num==1) //如果光标在h的位置闪烁,执行下面程序
- { h++; //h加1
- if(h==127) //=127清0
- h=0;
- figh=0; //设置figh=0,符号为正
- t=figh; //赋值给t,以便液晶显示
- if(h<=-1) //如果h为负数
- {figh=1; //设置figh=0
- t=figh; //赋值给t,以便液晶显示
- h=abs(h); //h取绝对值
- write_hl(11,h); //h写入LCD
- h=0-h; //把h变回原来的负数
- }
- else{write_hl(11,h);} //否则h写入LCD
- write_com(0x80+13); //光标在温度值位置闪烁
- }
- if(s1num==2) //如果光标在l的位置闪烁,执行下面程序
- { l++;
- if(l==127)
- l=0;
- figl=0;
- t=figl;
- if(l<=-1)
- {figl=1;
- t=figl;
- l=abs(l);
- write_hl(0x40+11,l);
- l=0-l;
- }
- else{write_hl(0x40+11,l);}
- write_com(0x80+0x40+13);
- }
- }
- }
- if(s3==0) //如果s3按下,执行下面程序
- { delay(5); //延时
- if(s3==0);
- {
- while(!s3); //s3松开后,执行下面程序
- if(s1num==1) //如果光标在h的位置闪烁,执行下面程序
- { h--; //h自减1
- if(h==-55) //如果h=-55清0
- h=0;
- figh=0; //设置figh=0,温度值为正
- t=figh; //赋值给t,以便液晶显示
- if(h<=-1) //如果h温度值为负数
- {figh=1; //设置figh=1
- t=figh; //赋值给t,以便液晶显示
- h=abs(h); //h取绝对值
- write_hl(11,h); //h写入LCD
- h=0-h; //把h变回原来的负数
- }
- else{write_hl(11,h);} //否则h写入LCD
- write_com(0x80+13); //光标在温度值位置闪烁
- }
- if(s1num==2)
- { l--;
- if(l==-55)
- h=0;
- figl=0;
- t=figl;
- if(l<=-1)
- {figl=1;
- t=figl;
- l=abs(l);
- write_hl(0x40+11,l);
- l=0-l;
- }
- else{write_hl(0x40+11,l);}
- write_com(0x80+0x40+13);
- }
- }
- }
- }
- void comp() //温度值报警程序
- {if(fig==1&&temp_value>=h) //如果读取温度值为正
- beep=0;
- if(fig==1&&temp_value<=h) //如果读取温度值为正
- beep=1;
- if(fig==0) //如果读取温度值为负
- { if(figh==0) //如果设置最高值温度值为正
- beep=1;
- if(figh==1) //如果设置最高值温度值为负
- {h=abs(h);
- if(temp_value<=h)
- beep=0;
- if(temp_value>=h)
- beep=1;
- h=-h;
- }
- }
- if(fig==1&&temp_value<=l)
- beep=0;
- if(fig==1&&temp_value>=l)
- beep=1;
- if(fig==0)
- { if(figl==0)
- beep=0;
- if(figl==1)
- {l=abs(l);
- if(temp_value>=l)
- beep=0;
- if(temp_value<=l)
- beep=1;
- l=-l;
- }
- }
- }
- void Keypros()
- {
- if(s1==0)
- {
- delay(1000); //消抖处理
- if(s1==0)
- {
- At24c02Write(1,num); //在地址1内写入数据num
- }
- while(!s1);
- }
- if(s2==0)
- {
- delay(1000); //消抖处理
- if(s2==0)
- {
- num=At24c02Read(1); //读取EEPROM地址1内的数据保存在num中
- }
- while(!s2);
- }
- if(s3==0)
- {
- delay(100); //消抖处理
- if(s3==0)
- {
- num++; //数据加1
- if(num>255)num=0;
- }
- while(!s3);
- }
- if(s4==0)
- {
- delay(1000); //消抖处理
- if(s4==0)
- {
- num=0; //数据清零
- }
- while(!s4);
- }
- }
复制代码 |