#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}sbit HI_LED=P2^3; //高温,低温白净闪烁LEDsbit LO_LED=P2^6;sbit DQ=P3^3; //DS18B20数据线sbit BEEP=P3^7; //报警sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit K1=P1^7; //正常显示温度,越界时报警sbit K2=P1^4; //显示报警温度sbit K3=P1^1; //查看ROM CODEuchar code RomCodeStr[]={"-- ROM CODE --"};uchar RomCode[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //64位ROM CODE uchar code Temp_Disp_Title[] ={"Current Temp: "};uchar Current_Temp_Display_Buffer[]={"TEMPE: "};uchar code Temperature_Char[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00}; //温度示字符uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"};uchar Alarm_HI_LO_STR[]={"Hi: Lo: "};uchar temp_data[2]={0x00,0x00};uchar temp_alarm[2]={0x00,0x00};uchar display[5]={0x00,0x00,0x00,0x00,0x00,}; //温度值uchar display1[3]={0x00,0x00,0x00}; //温度报警值uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}; //温度小数位对照表//.......................................................//报警温度上下限(取值范围:-128~+127)(DS18B20温度范围为:-55~+125)//数组中前一位为高温值,后一位为低温值//此处类型注意设为char,否则不能进行有符号数的比较char Alarm_Temp_HL[2]={70,-20};//............................................................uchar CurrentT=0; //当前读取温度整数部分uchar Temp_Value[]={0x00,0x00};//从DS18B20读取的温度值uchar Display_Digit[]={0,0,0,0};//待显示的各温度数位bit HI_Alarm=0,LO_Alarm=0; //高低温报警标志bit DS18B20_IS_OK=1; //传感器正常标志uint Time0_Count=0; //定时器延时累加//...........................//延时//...........................void DelayXus(int x){uchar i;while(x--)for(i=0;i<200;i++);}//.......................................//忙检测bit LCD_Busy_Check(){bit LCD_Status;RS=0;//寄存器选择RW=1;//读状态寄存器EN=1;//开始读DelayXus(1);LCD_Status=(bit)(P0&0x80) ;EN=0;return LCD_Status;}//写LCD指令void Write_LCD_Command(uchar cmd){while((LCD_Busy_Check()&0x80)==0x80); //忙等待RS=0; //写选择命令寄存器RW=0; //写EN=0;P0=cmd; EN=1; DelayXus(1); EN=0;}//向LCD写数据void Write_LCD_Data(uchar dat){while((LCD_Busy_Check()&0x80)==0x80); //忙等待RS=1;RW=0;EN=0;P0=dat;EN=1; DelayXus(1); EN=0;}//设置液晶显示位置void Set_LCD_POS(uchar pos){Write_LCD_Command(pos |0x80);}//LCD初始化void LCD_Initialise(){Write_LCD_Command(0x38);DelayXus(1);Write_LCD_Command(0x01); //清屏DelayXus(1);Write_LCD_Command(0x06); //字符进入模式:屏幕不动,字符后移DelayXus(1);Write_LCD_Command(0x0C); //显示开,关光标DelayXus(1);}//...............................................//..........................................//自定义字符写CGRAM//..................................void Write_NEW_LCD_Char(){uchar i;Write_LCD_Command(0x40); //写CGRAMfor(i=0;i<8;i++)Write_LCD_Data(Temperature_Char[i]); //写入温度符号}//............................................//延时//........................................................void Delay(uint num){while(--num);}//...............................................//初始化DS18B20//...............................................uchar Init_DS18B20(){uchar status;DQ=1;Delay(8);DQ=0;Delay(90);DQ=1;Delay(8);status=DQ;Delay(100);DQ=1;return status; //初始化成功时返回0 }//...............................................//读一节//...............................................uchar ReadOneByte(){uchar i,dat=0;DQ=1;_nop_();for(i=0;i<8;i++){DQ=0;dat>>=1;DQ=1;_nop_(); _nop_();if(DQ) dat |=0x80;Delay(30);DQ=1;}return dat;}//...............................................//写一字节//...............................................void WriteOneByte(uchar dat){uchar i;for(i=0;i<8;i++){DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;}}//...............................................//读取温度值//...............................................void Read_Temperature(){if(Init_DS18B20()==1) //DS18B20故障DS18B20_IS_OK=0;else{WriteOneByte(0xCC); //跳过序列号WriteOneByte(0x44); //启动温度转换Init_DS18B20();WriteOneByte(0xCC); //跳过序列号WriteOneByte(0xBE); //读取温度寄存器Temp_Value[0]=ReadOneByte(); //温度低8位Temp_Value[1]=ReadOneByte(); //温度高8位Alarm_Temp_HL[0]=ReadOneByte(); //报警温度THAlarm_Temp_HL[1]=ReadOneByte(); //报警温度TLDS18B20_IS_OK=1;}}//...............................................//设置DS18B20温度报警值//...............................................void Set_Alarm_Temp_Value(){Init_DS18B20();WriteOneByte(0xCC); //跳过序列号WriteOneByte(0x4E); //将设定的温度报警值写入DS18B20WriteOneByte(Alarm_Temp_HL[0]); //写THWriteOneByte(Alarm_Temp_HL[1]); //写TLWriteOneByte(0x7F); //12位精度Init_DS18B20();WriteOneByte(0xCC); //跳过序列号WriteOneByte(0x48); //温度报警值存入DS18B20 }//......................................................//在LCD上显示当前温度//.....................................................void Display_Temperature(){uchar i;uchar t=150; //延时值uchar ng=0; //负数标识char Signed_Current_Temp;//如果为负数则取反加1,并设置负数标识if((Temp_Value[1]&0xF8)==0xF8){Temp_Value[1]=~Temp_Value[1];Temp_Value[0]=~Temp_Value[0]+1;if(Temp_Value[0]==0x00) Temp_Value[1]++;ng=1; //设负数标识}//查表得到温度小数部分Display_Digit[0]=df_Table[Temp_Value[0]&0x0F];//获取温度整数部分(无符号)CurrentT=((Temp_V alue[0]&0xF0)>>4)|((Temp_Value[1]&0x07)<<4);//有符号的当前温度值,注意此处定义为char, 其值可为-128~+127Signed_Current_Temp=ng?-CurrentT:CurrentT;//高低温报警标志设置(与定义为char类型的Alarm_Temp_HL比较,这样可区分正负比较)HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?1:0;LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?1:0;//将整数部分分解为三位待显示数字Display_Digit[3]=CurrentT/100;Display_Digit[2]=CurrentT%100/10;Display_Digit[1]=CurrentT%10;//刷新LCD显示缓冲Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';Current_Temp_Display_Buffer[10]='.';Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0';Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0';Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0';//高位为0时不显示if(Display_Digit[3]==0) Current_Temp_Display_Buffer[7]=' ';//高位为0且次高位为0时,次高位不显示if(Display_Digit[2]==0&&Display_Digit[3]==0)Current_Temp_Display_Buffer[8]=' ';//负数符号显示恰当位置if (ng){if(Current_Temp_Display_Buffer[8]==' ')Current_Temp_Display_Buffer[8]='_';elseif(Current_Temp_Display_Buffer[7]==' ')Current_Temp_Display_Buffer[7]='_';elseCurrent_Temp_Display_Buffer[6]='_';}//在第一行显示标题Set_LCD_POS(0X00);for(i=0;i<16;i++) Write_LCD_Data( Temp_Disp_Title[i]);//在第二行显示当前温度Set_LCD_POS(0X40);for(i=0;i<16;i++) Write_LCD_Data(Current_Temp_Display_Buffer[i]); //显示温度符号Set_LCD_POS(0X4D);Write_LCD_Data(0x00);Set_LCD_POS(0X4E);Write_LCD_Data('C');}//.....................................//定时器中断,控制报警声音//.................................void T0_INT() interrupt 1{TH0=-1000/256;TL0=-1000%256;BEEP=!BEEP;if(++Time0_Count==400){Time0_Count=0;if(HI_Alarm) HI_LED=~HI_LED; else HI_LED=0;if(LO_Alarm) LO_LED=~LO_LED; else LO_LED=0;TR0=0;}}//...............................................//ROM CODE转换与显示//.....................................................void Display_Rom_Code(){uchar i,t;Set_LCD_POS(0x40);for(i=0;i<8;i++){t=((RomCode[i]&0xF0)>>4);if(t>9) t+=0x37;else t+='0';Write_LCD_Data(t); //高位数显示t=RomCode[i]&0x0F;if(t>9) t+=0x37;else t+='0';Write_LCD_Data(t); //低位数显示}}//..................................//读64位序列码//...............................void Read_Rom_Code(){uchar i;Init_DS18B20();WriteOneByte(0x33); //读序列码for (i=0;i<8;i++) RomCode[i]=ReadOneByte();}//.........................................//显示ROM CODE//...............................void Display_RomCode(){uchar i;Set_LCD_POS(0x00);for(i=0;i<16;i++) //显示标题Write_LCD_Data(RomCodeStr[i]);Read_Rom_Code(); //读64位序列码Display_Rom_Code(); //显示64位ROM CODE }//.......................................//显示报警温度//...............................................void Disp_Alarm_Temperature(){uchar i,ng;//显示Alarm_Temp_HL数组中的报警温度值//由于Alarm_Temp_HL类型为char,故可以直接进行正负比较//高温报警值.........................ng=0;if(Alarm_Temp_HL[0]<0) //如果为负数则取反加1{Alarm_Temp_HL[0]=~Alarm_Temp_HL[0]+1;ng=1;}//分解高温各数位到待显示串中Alarm_HI_LO_STR[4]=Alarm_Temp_HL[0]/100+'0';Alarm_HI_LO_STR[5]=Alarm_Temp_HL[0]/10%10+'0';Alarm_HI_LO_STR[6]=Alarm_Temp_HL[0]%10+'0';//屏蔽高位不显示的0if(Alarm_HI_LO_STR[4]=='0') Alarm_HI_LO_STR[4]=' ';if(Alarm_HI_LO_STR[4]==' '&& Alarm_HI_LO_STR[5]=='0') Alarm_HI_LO_STR[5]=' ';//"-"符号显示if (ng){if (Alarm_HI_LO_STR[5]==' ') Alarm_HI_LO_STR[5]='-';elseif(Alarm_HI_LO_STR[4]==' ') Alarm_HI_LO_STR[4]='-';elseAlarm_HI_LO_STR[3]='-';}//低温报警值ng=0;if(Alarm_Temp_HL[1]<0) //如果为负数则取反加1{Alarm_Temp_HL[1]=~Alarm_Temp_HL[1]+1;ng=1;}//分解低温各数位到待显示串中Alarm_HI_LO_STR[12]=Alarm_Temp_HL[1]/100+'0';Alarm_HI_LO_STR[13]=Alarm_Temp_HL[0]/10%10+'0'; Alarm_HI_LO_STR[14]=Alarm_Temp_HL[0]%10+'0';//屏蔽高位不显示的0if(Alarm_HI_LO_STR[12]=='0') Alarm_HI_LO_STR[12]=' ';if(Alarm_HI_LO_STR[12]==' '&& Alarm_HI_LO_STR[13]=='0') Alarm_HI_LO_STR[13]=' ';//"-"符号显示if (ng){if (Alarm_HI_LO_STR[13]==' ') Alarm_HI_LO_STR[13]='-';elseif(Alarm_HI_LO_STR[12]==' ') Alarm_HI_LO_STR[12]='-';elseAlarm_HI_LO_STR[11]='-';}//显示高低温报警温度值Set_LCD_POS(0x00); //显示标题for (i=0;i<16;i++) Write_LCD_Data(Alarm_Temp[i]);Set_LCD_POS(0x40); //显示高低温for (i=0;i<16;i++) Write_LCD_Data(Alarm_HI_LO_STR[i]);}//................................//主函数//..................................void main(){uchar Current_Operation=1; //默认当前操作为显示温度LCD_Initialise();IE=0x82;TMOD=0x01;TH0=-1000/256;TL0=-1000%256;TR0=0;HI_LED=0;LO_LED=0;Set_Alarm_Temp_Value();Read_Temperature();Delay(50000);Delay(50000);while(1){if (K1==0) Current_Operation=1;if (K2==0) Current_Operation=2;if (K3==0) Current_Operation=3;switch (Current_Operation){case 1://正常显示当前温度,越界时报警Read_Temperature();if( DS18B20_IS_OK){if (HI_Alarm==1 || LO_Alarm==1) TR0=1;else TR0=0;Display_Temperature();}DelayXus(100);break;case 2: //显示报警温度上下限Read_Temperature();Disp_Alarm_Temperature();DelayXus(100);break;case 3: //显示DS18B20 ROM CODEDisplay_RomCode();DelayXus(50);break;}}}。