18b20数码管实现过温报警与LCD显示

需积分: 10 1 下载量 90 浏览量 更新于2024-09-14 收藏 4KB TXT 举报
本文档主要介绍了如何使用18b20温度传感器、1602液晶屏以及51单片机(如STC89C52)实现一个过温报警系统。系统通过串口通信将18b20采集到的温度数据传输到上位机,并在LCD上实时显示温度值。当温度超过预设的警告区间时,会触发亮灯和蜂鸣器报警功能。 1. **硬件连接与初始化**: - 使用P2.2引脚作为DS(Data Select)数码管数据线,P2.6引脚作为段选线(Data Line A),P2.7引脚作为公共端(Com),P2.3引脚控制蜂鸣器,P3.4引脚EN(Enable)和P3.5引脚RS(Register Select)分别用于1602液晶屏的使能和指令线。 - 在程序开始时,需要初始化LCD,通过Write_LCD_Command函数发送0x01(清屏)、0x38(设置16x2字符尺寸)和0x0c(显示模式设置)命令,以及0x06(两行显示,第一行显示温度)来配置屏幕。 2. **温度传感器与读取**: - 使用18b20作为温度传感器,该设备通常通过I2C或单总线方式连接到51单片机。程序中未直接提供这部分代码,但假设有一个函数获取并转换温度值,存储在`uinttemp`或`f_temp`变量中。 3. **温度范围警报**: - 定义了两个警告下限`warn_l1`(100℃)和`warn_l2`(90℃),以及两个警告上限`warn_h1`(400℃)和`warn_h2`(420℃)。当温度超过这些阈值时,会触发报警功能。 - 通过比较当前温度值,如果超出警告范围,程序会控制LED灯(led0, led1, led2, led3)的状态来表示警告级别。 4. **LCD显示与报警指示**: - 温度数据显示函数`Write_LCD_Data()`用来将`LCD_Temp_title`和`LCD_Temp`数组中的字符写入LCD的相应位置,显示格式为"Temperature: "和实际温度值。 - 当温度超过警告值时,除了在LCD上显示,还会通过点亮特定的LED灯(如:低于警告下限亮led0,高于警告下限亮led1和led2,超过上限亮led3)以及触发蜂鸣器(通过`beep`引脚)进行报警。 5. **延时与控制函数**: - 提供了`delay()`函数,通过嵌套循环实现简单的定时延时,用于在液晶屏和LED操作之间插入适当的时间间隔。 6. **串口通信**: - 文档中没有明确提到如何通过串口通信将温度数据发送到上位机,但这是整个系统的一个关键部分,通常会用到UART或其他串行通信协议,比如通过发送ASCII码或其他自定义协议将温度值发送出去。 这个项目是基于51单片机的智能仪表应用,利用18b20温度传感器、1602液晶屏和串口通信技术,设计了一个能够实时显示温度并具备过温报警功能的系统。通过编程实现了数据采集、处理和显示,以及与上位机的交互。
2015-06-06 上传
代码:#include //用AT89C51时就用这个头文件 //#include //用华邦W78E58B时必须用这个头文件 #include #include #include #include #include #include #include "LCD1602.h" ////液晶显示头文件 //sbit DQ = P3^4; //定义DQ引脚为P3.4 sbit mode=P1^3; sbit add=P1^4; sbit sub=P1^5; sbit power=P1^7; unsigned char TH=50,TL=20; unsigned char t[2],*pt; //用来存放温度值,测温程序就是通过这个数组与主函数通信的 unsigned char TempBuffer1[9]={0x2b,0x31,0x32,0x32,0x2e,0x30,0x30,0x43,'\0'}; //显示实时温度,上电时显示+125.00C unsigned char TempBuffer0[17]={0x54,0x48,0x3a,0x2b,0x31,0x32,0x35,0x20, 0x54,0x4c,0x3a,0x2b,0x31,0x32,0x34,0x43,'\0'}; //显示温度上下限,上电时显示TH:+125 TL:+124C unsigned char code dotcode[4]={0,25,50,75}; /***因显示分辨率为0.25,但小数运算比较麻烦,故采用查表的方法******* 再将表值分离出十位和个位后送到十分位和百分位********************/ void covert0( unsigned char TH, unsigned char TL) //将温度上下限转换为LCD显示的数据 { if(TH>0x7F) //判断正负,如果为负温,将其转化为其绝对值 { TempBuffer0[3]=0x2d; //0x2d为"-"的ASCII码 TH=~TH; TH++; } else TempBuffer0[3]=0x2b; //0x2B为"+"的ASCII码 if(TL>0x7f) { TempBuffer0[11]=0x2d; //0x2d为"-"的ASCII码 TL=~TL+1; } else TempBuffer0[11]=0x2b; //0x2B为"+"的ASCII码 TempBuffer0[4]=TH/100+0x30; //分离出TH的百十个位 if( TempBuffer0[4]==0x30) TempBuffer0[4]=0xfe; //百位数消隐 TempBuffer0[5]=(TH0)/10+0x30; //分离出十位 TempBuffer0[6]=(TH0)+0x30; //分离出个位 TempBuffer0[12]=TL/100+0x30; //分离出TL的百十个位 if( TempBuffer0[12]==0x30) TempBuffer0[12]=0xfe; //百位数消隐 TempBuffer0[13]=(TL0)/10+0x30; //分离出十位 TempBuffer0[14]=(TL0)+0x30; //分离出个位 } void covert1(void) //将温度转换为LCD显示的数据 { unsigned char x=0x00,y=0x00; t[0]=*pt; pt++; t[1]=*pt; if(t[1]>0x07) //判断正负温度 { TempBuffer1[0]=0x2d; //0x2d为"-"的ASCII码 t[1]=~t[1]; /*下面几句把负数的补码*/ t[0]=~t[0]; /* 换算成绝对值*********/ x=t[0]+1; /***********************/ t[0]=x; /***********************/ if(x>255) /**********************/ t[1]++; /*********************/ } else TempBuffer1[0]=0x2b; //0xfe为变"+"的ASCII码 t[1]<>=4; //右移4位 x=x&0x0f; //和前面两句就是取出t[0]的高四位 t[1]=t[1]|x; //将高低字节的有效值的整数部分拼成一个字节 if(t[1]>TH) { power=0; } if(t[1]>=2; //左移两位,以便查表 x=t[0]; y=dotcode[x]; //查表换算成实际的小数 TempBuffer1[5]=y/10+0x30; //分离出十分位 TempBuffer1[6]=y+0x30; //分离出百分位 } void delay(unsigned char i) { while(i--); } main() { bit flag1=0; bit flag2=0; //下一步扩展时可能通过这两个变量,调节上下限 power=0; //测温函数返回这个数组的头地址 while(1) { if(mode==0) { if(add==1) { flag1=0; } if(add==0&&flag1==0) { TL++; flag1=1; } if(sub==1) { flag2=0; } if(sub==0&&flag2==0&&TL>20) { TL--; flag2=1; } } if(mode==1) { if(add==1) { flag1=0; } if(add==0&&flag1==0&&TH<50) { TH++; flag1=1; } if(sub==1) { flag2=0; } if(sub==0&&flag2==0) { TH--; flag2=1; } } pt=ReadTemperature(TH,TL,0x3f); //上限温度-22,下限-24,分辨率10位,也就是0.25C //读取温度,温度值存放在一个两个字节的数组中, delay(100); covert1(); covert0(TH,TL); LCD_Initial(); //第一个参数列号,第二个为行号,为0表示第一行 //为1表示第二行,第三个参数为显示数据的首地址 LCD_Print(0,0,TempBuffer0); LCD_Print(0,1,"Cur_Temp:"); LCD_Print(10,1,TempBuffer1); } }