基于51单片机的温度监控设计,并通过按键可以调节温度的上下限。
并在Proteus上仿真成功,温度测量通过18b20,显示在1602的显示屏上。
希望给大家带来参考。
单片机源程序如下:
- #include <reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define DQ P3&0x07
- sbit DQ0=P3^0;
- sbit DQ1= P3^1;
- //sbit DQ2= P3^2;
- sbit key0=P1^0;
- sbit key1=P1^1;
- sbit key2=P1^2;
- sbit BEEP=P3^6;//蜂鸣器器驱动线
- uchar presence;//检测18b20是否插好
- sbit LCD_RS=P2^0;
- sbit LCD_RW=P2^1;
- sbit LCD_E=P2^2;
- uchar code cdis1[]={"WWW.RICHMCU.COM"};
- uchar code cdis2[]={"WENDU: _ C"};
- uchar code cdis3[]={"DS18B20ERROR"};
- uchar code cdis4[]={"PLEASE CHECK"};
- unsigned char code mytab[8]={0x0c,0x12,0x12,0x0C,0x00,0x00,0x00,0x00};
- void beep();
- uint wd0=0,wd1=0,wd2=0;
- uchar dat0,dat1,dat2;
- uchar min=10;
- uchar max=50;
- #define delayNOP();{_nop_();_nop_();_nop_();_nop_();};
- /**************************************/
- void delay1(int ms)
- {
- unsigned char y ;
- while(ms--)
- {
- for(y = 0 ; y<250 ; y++)
- {
- _nop_() ;
- _nop_() ;
- _nop_() ;
- _nop_() ;
- }
- }
- }
- /******************************************************************/ /*检查LCD忙状态 */
- /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
- /******************************************************************/
- bit lcd_busy()
- {
- bit result ;
- LCD_RS = 0 ;
- LCD_RW = 1 ;
- LCD_E = 1 ;
- delayNOP() ;
- result = (bit)(P0&0x80) ;
- LCD_E = 0 ;
- return(result) ;
- }
- /*写指令数据到LCD */
- /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
- /*******************************************************************/
- void lcd_wcmd(uchar cmd)
- {
- while(lcd_busy()) ;
- LCD_RS = 0 ;
- LCD_RW = 0 ;
- LCD_E = 0 ;
- _nop_() ;
- _nop_() ;
- P0 = cmd ;
- delayNOP() ;
- LCD_E = 1 ;
- delayNOP() ;
- LCD_E = 0 ;
- }
- /*******************************************************************/
- /*写显示数据到LCD */
- /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
- /*******************************************************************/
- void lcd_wdat(uchar dat)
- {
- while(lcd_busy()) ;
- LCD_RS = 1 ;
- LCD_RW = 0 ;
- LCD_E = 0 ;
- P0 = dat ;
- delayNOP() ;
- LCD_E = 1 ;
- delayNOP() ;
- LCD_E = 0 ;
- delay1(1);
- }
- /* LCD初始化设定 */
- /*******************************************************************/
- void lcd_init()
- {
- delay1(15) ;
- lcd_wcmd(0x01) ; //清除LCD的显示内容
- lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据
- delay1(5) ;
- lcd_wcmd(0x38) ;
- delay1(5) ;
- lcd_wcmd(0x38) ;
- delay1(5) ;
- lcd_wcmd(0x0c) ; //显示开,关光标
- delay1(5) ;
- lcd_wcmd(0x06) ; //移动光标
- delay1(5) ;
- lcd_wcmd(0x01) ; //清除LCD的显示内容
- delay1(5) ;
- }
- void writetab()
- {
- unsigned char i ;
- lcd_wcmd(0x40) ; //写CGRAM
- for (i = 0 ; i< 8 ; i++)
- lcd_wdat(mytab[ i ]) ;
- }
- void dis_string(uchar dir,uchar a[])
- {
- uchar i=0;
- lcd_wcmd(dir);
- while(a[i]!='\0')
- {
- lcd_wdat(a[i]);
- i++;
- }
- }
- /*us级延时函数 */
- /*******************************************************************/
- void Delay(unsigned int num)
- {
- while( --num ) ;
- }
- /*初始化ds1820 */
- /*******************************************************************/ uchar Init_DS18B20(void)
- {
- DQ0 = 1 ; //DQ复位
- DQ1 = 1 ;
- //DQ2 = 1 ;
- Delay(10) ; //稍做延时
- DQ0 = 0 ; //单片机将DQ拉低
- DQ1 = 0 ;
- //DQ2 = 0 ;
- Delay(100) ; //精确延时 大于 480us
- DQ0 = 1 ; //拉高总线
- DQ1 = 1 ;
- //DQ2 = 1 ;
- Delay(8) ;
- presence =DQ;
- Delay(100) ;
- DQ0 = 1 ;
- DQ1 = 1 ;
- //DQ2 = 1 ;
- return(presence) ; //返回信号,表示初始化成功,否则表示初始化失败
- }
- /* 读一个字节 */
- /*******************************************************************/
- void ReadOneChar(void)
- {
- unsigned char i = 0 ;
- dat0 = 0 ;
- dat1 = 0 ;
- dat2 = 0 ;
- for (i = 8 ; i > 0 ; i--)
- {
- DQ0 = 0 ; // 给脉冲信号
- DQ1 = 0 ;
- //DQ2 = 0 ;
- dat0 >>= 1 ;
- dat1 >>= 1 ;
- dat2 >>= 1 ;
- DQ0 = 1 ; // 给脉冲信号
- DQ1 = 1 ;
- //DQ2 = 1 ;
- Delay(1);
- if(DQ0)
- dat0 |= 0x80 ;
- if(DQ1)
- dat1 |= 0x80 ;
- //if(DQ2)
- dat2 |= 0x80 ;
- Delay(6) ;
- }
- }
- /* 写一个字节 */
- /*******************************************************************/
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i = 0 ;
- for (i = 8 ; i > 0 ; i--)
- {
- DQ0 = 0 ;
- DQ1 = 0 ;
- //DQ2 = 0 ;
- DQ0 = dat&0x01 ;
- DQ1 = dat&0x01 ;
- //DQ2 = dat&0x01 ;
- Delay(6) ;
- DQ0 = 1 ;
- DQ1 = 1 ;
- //DQ2 = 1 ;
- dat>>=1 ;
- }
- }
- /* 读取温度 */
- /*******************************************************************/
- void Read_Temperature(void)
- {
- Init_DS18B20() ;
- WriteOneChar(0xCC) ; // 跳过读序号列号的操作
- WriteOneChar(0x44) ; // 启动温度转换
- Init_DS18B20() ;
- WriteOneChar(0xCC) ; //跳过读序号列号的操作
- WriteOneChar(0xBE) ; //读取温度寄存器
- ReadOneChar() ; //温度低8位
- wd0=dat0;
- wd1=dat1;
- wd2=dat2;
- ReadOneChar() ; //温度高8位
- wd0=wd0+256*dat0;
- wd1=wd1+256*dat1;
- wd2=wd2+256*dat2;
- wd0=wd0*0.625;
- wd1=wd1*0.625;
- wd2=wd2*0.625;
- }
- void display_tem()
- {
- BEEP=1;
- if(presence&0x01) //presence最低位为1说明0号测温度传感器没有正常工作。
- dis_string(0x80,"T0 ERROR");
- else
- {
- dis_string(0x80,"T0:");
- lcd_wdat(wd0%1000/100+48) ;
- lcd_wdat(wd0%100/10+48) ;
- lcd_wdat('.') ;
- lcd_wdat(wd0%10+48) ;
- writetab() ; //自定义字符写入CGRAM
- lcd_wcmd(0x87);
- lcd_wdat(0x00) ; //显示自定义字符
- if((wd0>max*10)|(wd0<min*10))
- BEEP=0;
- }
- /*if(presence&0x02) //presence中间位为1说明1号测温度传感器没有正常工作。
- dis_string(0x88,"T1 ERROR");
- else
- {
- dis_string(0x88,"T1:");
- lcd_wdat(wd1%1000/100+48) ;
- lcd_wdat(wd1%100/10+48) ;
- lcd_wdat('.') ;
- lcd_wdat(wd1%10+48) ;
- writetab() ; //自定义字符写入CGRAM
- lcd_wcmd(0x8f);
- lcd_wdat(0x00) ; //显示自定义字符
- if((wd1>max*10)|(wd1<min*10))
- BEEP=0;
- }
- if(presence&0x04) //presence最高位为1说明2号测温度传感器没有正常工作。
- dis_string(0xc0,"T2 ERROR");
- else
- {
- dis_string(0xc0,"T2:");
- lcd_wdat(wd2%1000/100+48) ;
- lcd_wdat(wd2%100/10+48) ;
- lcd_wdat('.') ;
- lcd_wdat(wd2%10+48) ;
- writetab() ; //自定义字符写入CGRAM
- lcd_wcmd(0x8f);
- lcd_wdat(0x00) ; //显示自定义字符
- if((wd2>max*10)|(wd2<min*10))
- BEEP=0;
- }*/
- }
- uchar set_tem(uchar dat)
- {
- while(1)
- {
- lcd_wcmd(0xc8);
- lcd_wdat(dat/10+48) ;
- lcd_wdat(dat%10+48) ;
- if(key1==0)
- delay1(10);
- if(key1==0)
- {
- while(key1==0);
- dat++;
- }
- if(key2==0)
- delay1(10);
- if(key2==0)
- {
- while(key2==0);
- dat--;
- }
- if(key0==0)
- delay1(5);
- if(key0==0)
- break;
- }
- return dat;
- }
- /* 主函数 */
- /************************************/
- void main()
- {
- uchar flage=0;
- lcd_init() ;
- while(1)
- {
- if(key0==0)
- {
- delay1(5);
- if(key0==0)
- {
- flage++;
- if(flage==3)
- flage=0;
- }
- }
- Read_Temperature() ;
- switch(flage)
- {
- case 0: display_tem();break;
- case 1:
- lcd_init();
- dis_string(0x80,"set min tem");
- dis_string(0xc0,"min tem:");
- min=set_tem(min) ;
- break;
- case 2:
- lcd_init();
- dis_string(0x80,"set max tem");
- dis_string(0xc0,"max tem:");
- max=set_tem(max) ;
- break;
- default: display_tem();break;
-
- }
- }
-
- }
复制代码
所有资料51hei提供下载:
温度监控.zip
(75.3 KB, 下载次数: 52)
|