基于51單片機的溫度監控設計,并通過按鍵可以調節溫度的上下限。
并在Proteus上仿真成功,溫度測量通過18b20,顯示在1602的顯示屏上。
希望給大家帶來參考。
51hei.png (45.55 KB, 下載次數: 54)
下載附件
2020-4-16 00:53 上傳
仿真圖.png (31.99 KB, 下載次數: 56)
下載附件
2020-4-15 20:31 上傳
單片機源程序如下:
- #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)
2020-4-15 20:30 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|