|
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar temp,num,klnum;
- uchar code table[]={"18B20 OKTL"};
- char shangxiaxian[2]={-10,10};
- char a;
- sbit k1=P1^0;
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit k4=P1^3;
- sbit LCD_RW=P2^5;
- sbit lcdrs=P2^6;
- sbit lcden=P2^7;
- sbit Beep=P3^0;
- sbit led=P3^1;
- sbit DQ=P3^7; /*液晶显示屏的延时程序*/
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- } /*温度传感器的延时程序*/
- void Delay1(uint y)
- {
- uint x;
- for( ;y>0; y--)
- {
- for(x=110;x>0;x--);
- }
- } /*蜂鸣器,18B20写数据函数的延时程序*/
- void delay2(uint a)
- {
- while(--a);
- } /*温度传感器初始化函数*/
- void init_18B20()
- {
- DQ=1;
- delay2(8);
- DQ=0;
- delay2(90);
- DQ=1;
- _nop_();
- _nop_();
- delay2(100);
- DQ=1;
- } /*温度传感器写字节命令函数*/
- void DS18B20xiezijie(uchar date)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0; //在写入一位数据之前先把总线拉低
- DQ=date&0x01; //写入一个数据,从最低位开始写
- delay2(5); //延时
- DQ=1; //将总线拉高,等待第二位数据写入
- date>>=1; //右移一位,写入第二位数据
- }
- } /*温度传感器读字节命令函数*/
- uchar DS18B20duzijie()
- {
- uchar i,dat=0;
- DQ=1;
- _nop_();
- for(i=0;i<8;i++)
- {
- DQ=0; //先将总线拉低
- _nop_();
- _nop_();
- dat>>=1;
- DQ=1; //然后释放总线
- _nop_(); //延时一下等待数据稳定
- _nop_();
- if(DQ)
- dat|=0x80; //读取数据,从最低位开始读取
- delay2(30); //读取完之后等待一下,再接着读取下一个数
- DQ=1;
- }
- return dat; //返回所读到的温度
- } /*写温度转换命令函数*/
- void DS18B20ChangTemp()
- {
- init_18B20();
- Delay1(1);
- DS18B20xiezijie(0xcc); //跳过ROM操作命令
- DS18B20xiezijie(0x44); //温度转换命令
- } /*读温度命令函数*/
- void DS18B20ReadTempCom()
- {
- init_18B20();
- Delay1(1);
- DS18B20xiezijie(0xcc); //跳过ROM操作命令
- DS18B20xiezijie(0xbe); //发送读取温度命令
- } /*读温度函数*/
- int DS18B20ReadTemp()
- {
- inttemp=0;
- uchartmh,tml;
- DS18B20ChangTemp(); //先写入转换命令
- DS18B20ReadTempCom(); //然后等待转换完成后发送读取温度命令
- tml=DS18B20duzijie(); //读取温度值共16位,先读低字节
- tmh=DS18B20duzijie(); //再读高字节
- temp=tmh;
- temp<<=8;
- temp|=tml;
- return temp; /*液晶屏写指令函数*/
- }
- void write_com(uchar com)
- {
- lcdrs=0;
- lcden=0;
- LCD_RW=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- } /*液晶屏写指令函数*/
- void write_com2(int com)
- {
- lcdrs=0;
- LCD_RW=0;
- lcden=0;
- delay(5);
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- P0=(com&0x0f)<<4;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- } /*液晶屏写数据命令函数*/
- void write_data(char date)
- {
- lcdrs=1;
- LCD_RW=0;
- lcden=0;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- lcdrs=1;
- LCD_RW=0;
- lcden=0;
- P0=(date&0x0f)<<4; //一次写入4位
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- } /*液晶屏初始化函数*/
- void init()
- {
- lcden=0;
- write_com(0x28);
- write_com2(0x28);
- write_com2(0x0c);
- write_com2(0x06);
- write_com2(0x01);
- write_com2(0x80);
- } /*报警上下线处理函数*/
- void write_hl(uchar add,char date)
- {
- uchar bai,shi,ge;
- if(date<0){date=-date;}
- bai=date/100;
- shi=date%100/10;
- ge=date%100%10;
- write_com2(0x80+0x40+add);
- write_date(0x30+bai);
- write_date(0x30+shi);
- write_date(0x30+ge);
- } /*报警上下线处理函数*/
- void write_hl1(uchar add,char date)
- {
- uchar bai,shi,ge;
- if(date<0){date=-date;}
- bai=date/100;
- shi=date%100/10;
- ge=date%100%10;
- write_com2(0x80+add);
- write_date(0x30+bai);
- write_date(0x30+shi);
- write_date(0x30+ge);
- } /*液晶屏显示函数,显示温度值*/
- void Lcdxianshi(int temp)
- {
- uchar sz[4]={0,0,0,0};
- unsigned char datas[]={0,0,0,0,0}; //定义数组
- float tp;
- if(temp<0) //当温度值为负数
- {
- write_com2(0x80+0x40); //写地址80表示初始地址
- write_data('-'); //显示负
- temp=temp-1; //因为读取的温度是实际温度的补码,所以减一,再取反求出原码
- temp=~temp;
- tp=temp;
- temp=tp*0.0625*100+0.5
- }
- else
- {
- write_com2(0x80+0x40); //写地址80表示初始地址
- write_data('+'); //显示正
- tp=temp; //因为数据处理有小数点,所以将温度赋给一个浮点型变量,如果温度是正,那么正数的原码就是补码本身
- temp=tp*0.0625*100+0.5;
- }
- datas[0]=temp/1000; //百位
- datas[1]=tem%10000/1000; //十位
- datas[2]=temp%1000/100; //个位
- datas[3]=temp%100/10; //小数
- write_com2(0x80+0x40+1);
- write_data('0'+datas[0]);
- write_com2(0x80+0x40+2);
- write_data('0'+datas[1]);
- write_com2(0x80+0x40+3);
- write_data('0'+datas[2]);
- write_com2(0x80+0x40+4);
- write_data('.');
- write_com2(0x80+0x40+5);
- write_data('0'+datas[3]);
- a=(datas[0]*100+datas[1]*10+datas[2]); //用于温度的比较值
- write_hl(13,shangxiaxian[1]); //显示报警上限
- write_hl1(13,shangxiaxian[0]); //显示报警下限
- } /*按键处理函数,用于设置温度报警值*/
- void key()
- {
- if(k1==0)
- {
- delay(5);
- if(k1==0) //温度报警下限加
- {
- shangxiaxian[0]++;
- if(shangxiaxian[0]==127)
- shangxiaxian[0]=126;
- write_hl1(13,shangxiaxian[0]);
- }
- }
- if(k2==0) //温度报警下限减
- {
- delay(5);
- if(k2==0)
- {
- shangxiaxian[0]--;
- if(shangxiaxian[0]==-56)
- shangxiaxian[0]=-55;
- write_hl1(13,shangxiaxian[0]);
- }
- }
- if(k3==0) //温度报警上限加
- {
- delay(5);
- if(k3==0)
- {
- shangxiaxian[1]++;
- if(shangxiaxian[1]==127)
- shangxiaxian[1]=126;
- write_hl(13,shangxiaxian[1]);
- }
- }
- if(k4==0) //温度报警上限减
- {
- delay(5);
- if(k4==0)
- {
- shangxiaxian[1]--;
- if(shangxiaxian[1]==-56)
- shangxiaxian[1]=-55;
- write_hl(13,shangxiaxian[1]);
- }
- }
- }
- void main()
- {
- intb;
- init();
- led=0;
- for(num=0;num<11;num++) //让液晶屏显示“18B20 OK TL”
- {
- write_data(table[num]);
- delay(20);
- }
- write_com2(0x80+0x40+9);
- write_data('T');
- write_com2(0x80+0x40+10);
- write_data('H');
- while(1)
- {
- key();
- Lcdxianshi(Ds18B20ReadTemp());
- delay(100);
- if(shangxiaxian[0]<0)
- {
- write_com2(0x80+12);
- write_data('-');
- }
- else
- {
- write_com2(0x80+12);
- write_data('+');
- }
- if(shangxiaxian[1]<0)
- {
- write_com2(0x80+0x40+12);
- write_data('-');
- }
- else
- {
- write_com2(0x80+0x40+12);
- write_data('+');
- }
- if(a>shangxiaxian[1]) //判断温度值与报警值的大小
- {
- write_com2(0x80+0x40+6);
- write_data('<');
- write_com2(0x80+0x40+7);
- write_data('L');
- }
- if(a>=shangxiaxian[0]&&a<=shangxiaxian[1]) //判断温度值与报警值的大小
- {
- write_com2(0x80+0x40+6);
- write_data('');
- write_com2(0x80+0x40+7);
- write_data('!');
- }
- if(a>shangxiaxian[0]||a>shangxiaxian[1]) //如果温度值在报警值之外,蜂鸣器响
- {
- for(b=0;b<1000;b++)
- {Beep=1;led=1;
- delay2(20);
- Beep=0;led=0;
- delay0(20);
- }
- }
- }
- }
复制代码
|
-
1.png
(118.67 KB, 下载次数: 57)
-
0.png
(120.94 KB, 下载次数: 37)
|