7d2dd1be943f13f2
获得 0 次赞
帮助过0人
#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar tempnumklnum;uchar code table[]={"18B20 OKTL"};char shangxiaxian[2]={-1010};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 xy;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 idat=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; uchartmhtml;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 addchar date){uchar baishige;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 addchar date){uchar baishige;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]={0000};unsigned char datas[]={00000}; //定义数组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(13shangxiaxian[1]); //显示报警上限write_hl1(13shangxiaxian[0]); //显示报警下限} /@@*按键处理函数,用于设置温度报警值*/void key(){if(k1==0) { delay(5); if(k1==0) //温度报警下限加 { shangxiaxian[0]++; if(shangxiaxian[0]==127) shangxiaxian[0]=126; write_hl1(13shangxiaxian[0]); } } if(k2==0) //温度报警下限减 { delay(5); if(k2==0) { shangxiaxian[0]--; if(shangxiaxian[0]==-56) shangxiaxian[0]=-55; write_hl1(13shangxiaxian[0]); } } if(k3==0) //温度报警上限加 { delay(5); if(k3==0) { shangxiaxian[1]++; if(shangxiaxian[1]==127) shangxiaxian[1]=126; write_hl(13shangxiaxian[1]); } } if(k4==0) //温度报警上限减 { delay(5); if(k4==0) { shangxiaxian[1]--; if(shangxiaxian[1]==-56) shangxiaxian[1]=-55; write_hl(13shangxiaxian[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); } } }}