該溫度檢測器,使用了10米線長的DS18b20溫度傳感器和51開發板,傳感器由于使用長距離的接線,所以需增加上拉電阻。使用Lcd1602顯示溫度和所設置的上限報警值,可使用矩陣鍵盤設置上限報警的溫度值,報警系統包括:LED燈由黃變紅,同時電機轉動散熱。
制作出來的實物圖如下:
IMG_20180304_150226.jpg (1.26 MB, 下載次數: 79)
下載附件
整體裝置(基于開發板)
2018-3-4 15:19 上傳
IMG_20180304_150244.jpg (767.73 KB, 下載次數: 67)
下載附件
顯示情況
2018-3-4 15:19 上傳
單片機源程序如下:
- #include "reg52.h"
- #include "temp.h" //包含ds18b20的相關函數
- #include "lcd.h" //包含Lcd的相關函數
- #define GPIO_KEY P1 //薄膜按鍵接口
- typedef unsigned int u16; //對數據類型進行聲明定義
- typedef unsigned char u8;
- void LcdWriteCom(uchar com); //選擇Lcd屏寫入位置的函數
- void LcdWriteData(uchar dat); //在Lcd屏進行寫入數據操作的函數
- void LcdInit(); //Lcd初始化函數
- sbit LED_yello=P3^5; //LED黃色正極
- sbit LED_red=P3^6; //LED紅色正極
- sbit K3=P3^2; //設置按鍵
- int Ceiling=27; //初始上限值
- u8 LcdplayData[16]={'T','e','m','p',':',' ',' ',0,0,0,0,'.',0,0,'`','C'};
- u8 sz[16]="Please input: ";
- u8 shezhi[16]={'C','e','i','l','i','n','g',':',' ','2','7','`','C',' ',' ',' '};
- void Delay_ms(unsigned int ms)//延時函數,延時1ms
- {
- int j;
- for(;ms>0;ms--)
- for(j=140;j>0;j--);
- }
- /*******************************************************************************
- * 函 數 名 : datapros()
- * 函數功能 : 溫度讀取處理轉換函數
- * 輸 入 : temp
- * 輸 出 : 無
- *******************************************************************************/
- int datapros(int temp)
- {
- float tp;
- int t;
- if(temp< 0) //當溫度值為負數
- {
- LcdplayData[7] ='-'; //正負位為-
- //因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼
- temp=temp-1;
- temp=~temp;
- tp=temp;
- temp=tp*0.0625*100+0.5;
- //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
- //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
- //算加上0.5,還是在小數點后面。
-
- }
- else
- {
- LcdplayData[7] ='+';
- tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
- //如果溫度是正的那么,那么正數的原碼就是補碼它本身
- temp=tp*0.0625*100+0.5;
- //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
- //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
- //算加上0.5,還是在小數點后面。
- }
- t=temp;
- LcdplayData[8] = temp / 10000+48; //提取各位
- LcdplayData[9] = temp % 10000 / 1000+48;
- LcdplayData[10] = temp % 1000 / 100+48;
- LcdplayData[12] = temp % 100 / 10+48;
- LcdplayData[13] = temp % 10+48;
- return t;
- }
- /*******************************************************************************
- * 函數名 :LcdDisplay()
- * 函數功能 :Lcd1602顯示函數
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void LcdDisplay()
- {
- LcdWriteCom(0x87);
- LcdWriteData(LcdplayData[7]); //寫入+-號
- LcdWriteData(LcdplayData[8]=='0' ? ' ':LcdplayData[8]); //輸出整數部分
- LcdWriteData(LcdplayData[9]=='0' ? ' ':LcdplayData[9]); //若是0,不輸出
- LcdWriteData(LcdplayData[10]);
- LcdWriteCom(0x8c);
- LcdWriteData(LcdplayData[12]); //輸出小數部分
- LcdWriteData(LcdplayData[13]);
- // Delay_ms(100);
- /*
- SBUF = '0'+m; //將接收到的數據放入到發送寄存器
- while (!TI); //等待發送數據完成
- TI = 0; //發送完成標志位清零
- */
- }
- void xinxi()//輸出兩行中的固定信息
- {
- u8 i;
- LcdWriteCom(0x01);//清屏
- LcdWriteCom(0x80);//輸出第一行的
- for (i=0;i<7;i++)
- {
- LcdWriteData(LcdplayData[i]);
- }
- LcdWriteCom(0x8b);
- LcdWriteData(LcdplayData[11]);
- LcdWriteCom(0x8e);
- LcdWriteData(LcdplayData[14]);
- LcdWriteData(LcdplayData[15]);
- LcdWriteCom(0xc0);//輸出第二行的
- for (i=0;i<16;i++)
- {
- if (i==8&&shezhi[8]=='0') shezhi[8]=' ';
- LcdWriteData(shezhi[i]);
- }
- }
- void zdkg() // 中斷開關
- {
- EA=1;
- IT0=1;
- EX0=1;
- }
- void Int0() interrupt 0 //外部中斷0的中斷函數
- {
- u8 i,j,KeyValue;
- u16 key=0;
- if(K3==0)
- {
- Delay_ms(10);//消抖
- if(K3==0)
- {
- LcdWriteCom(0x80);
- for (i=0;i<16;i++)//輸出提示信息
- {
- LcdWriteData(sz[i]);
- }
- while (K3==0) ;//等待松手,必須確保第一次按下后已松手
- while (1)
- {
- j=0;
- GPIO_KEY=0x0f;
- while (GPIO_KEY==0x0f) //等待按下鍵盤
- {
- if (K3==0)
- {
- Delay_ms(10);
- if (K3==0)
- {
- while (K3==0) ;//等待松手,必須確保第2次按下后已松手
- goto over; //若再次按下K3按鍵,則設置完畢,可以跳出中斷
- }
- }
- }
- if (GPIO_KEY!=0x0f)//讀取按鍵是否按下
- {
- Delay_ms(10);//延時消抖
- if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
- {
- //測試列
- GPIO_KEY=0X0f;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=3;break;
- }
- //測試行
- GPIO_KEY=0Xf0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue+0;break;
- case(0Xb0): KeyValue=KeyValue+4;break;
- case(0Xd0): KeyValue=KeyValue+8;break;
- case(0Xe0): KeyValue=KeyValue+12;break;
- }
- while((j<40)&&(GPIO_KEY!=0xf0)) //松手檢測
- {
- Delay_ms(10);
- j++;
- }
- switch (KeyValue)
- {
- //key計算最新鍵入的值,Ceiling存放最新鍵入的值
- case 0:key=key*10+1;Ceiling=key;break;//鍵入1
- case 1:key=key*10+2;Ceiling=key;break;//鍵入2
- case 2:key=key*10+3;Ceiling=key;break;//鍵入3
- case 3:Ceiling++;key=0;break; //按“A”,則加1,同時變量key要清零
- case 4:key=key*10+4;Ceiling=key;break;//鍵入4
- case 5:key=key*10+5;Ceiling=key;break;//鍵入5
- case 6:key=key*10+6;Ceiling=key;break;//鍵入6
- case 7:Ceiling--;key=0;break; //按“B”,則減1,同時變量key要清零
- case 8:key=key*10+7;Ceiling=key;break;//鍵入7
- case 9:key=key*10+8;Ceiling=key;break;//鍵入8
- case 10:key=key*10+9;Ceiling=key;break;//鍵入9
- case 11:break;
- case 12:key=Ceiling=0;break; //按“*”,則所有清零
- case 13:key=key*10+0;Ceiling=key;break;//鍵入0
- case 14:break;
- case 15:break; //“C”“D”“#”無操作
- }
- shezhi[8] = Ceiling % 1000 / 100+48;
- shezhi[9] = Ceiling % 100 / 10+48;
- shezhi[10] = Ceiling % 10+48;
- LcdWriteCom(0xc8);
- LcdWriteData(shezhi[8]=='0' ? ' ':shezhi[8]); //顯示設置的上限值
- LcdWriteData(shezhi[9]=='0' ? ' ':shezhi[9]);
- LcdWriteData(shezhi[10]);
- }
- }
- }
- }
- }
- over: xinxi(); //跳出中斷前重新輸出屏幕固定信息
- }
- /*******************************************************************************
- * 函 數 名 : main
- * 函數功能 : 主函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void main()
- {
- u16 temp;
- LED_red=0;
- LED_yello=1;
- LcdInit();//初始化Lcd
- zdkg(); //打開中斷
- xinxi(); //輸出屏幕固定信息
- while(1)
- {
- temp=datapros(Ds18b20ReadTemp()); //數據處理函數
- LcdDisplay(); //Lcd顯示函數
- if (temp>=Ceiling*100) LED_red=1,LED_yello=0; //超限報警(LED燈變紅)
- else LED_red=0,LED_yello=1;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
Ds18B20溫度檢測器(Lcd顯示、矩陣鍵盤設置上限報警、報警系統(LED燈亮、電機轉動散熱).rar
(2.04 MB, 下載次數: 52)
2018-3-4 15:23 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|