基于51單片機控制的數(shù)字溫度控制系統(tǒng)
單片機源程序如下:
- #include <reg52.h> // 包含頭文件
- #include <intrins.h>
- #define uchar unsigned char // 以后unsigned char就可以用uchar代替
- #define uint unsigned int // 以后unsigned int 就可以用uint 代替
- sbit DQ = P1^1; // DS18B20傳感器的引腳定義
- sbit w1 = P2^4; // 數(shù)碼管第1位的控制引腳
- sbit w2 = P2^5; // 數(shù)碼管第2位的控制引腳
- sbit w3 = P2^6; // 數(shù)碼管第3位的控制引腳
- sbit w4 = P2^7; // 數(shù)碼管第4位的控制引腳
- sbit Buzzer = P1^0; // 蜂鳴器引腳
- sbit JdqLow = P2^0; // 溫度過低繼電器控制(加熱)
- sbit JdqHig = P2^1; // 溫度過高繼電器控制(降溫)
- sbit LedLow = P2^2; // 溫度低指示燈
- sbit LedHig = P2^3; // 溫度高指示燈
- sbit KeySet = P3^2; // 設(shè)置按鍵
- sbit KeyDown = P3^3; // 減按鍵
- sbit KeyUp = P3^4; // 加按鍵
- /* 數(shù)碼管的顯示值: 0 1 2 3 4 5 6 7 8 9 - */
- uchar code Array1[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40 };
- /* 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. */
- uchar code Array2[]={ 0xBf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef };
- uchar Buff[4]; // 顯示緩沖區(qū)
- uchar ShowID=1; // 當前顯示的是哪一個數(shù)碼管
- int AlarmLow=150; // 默認報警的溫度下限值是15度
- int AlarmHig=300; // 默認報警的溫度上限值是30度
- /*********************************************************/
- // 毫秒級的延時函數(shù),time是要延時的毫秒數(shù)
- /*********************************************************/
- void DelayMs(uint time)
- {
- uint i,j;
- for(i=0;i<time;i++)
- for(j=0;j<112;j++);
- }
- /*********************************************************/
- // 延時15微秒
- /*********************************************************/
- void Delay15us(void)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*********************************************************/
- // 復(fù)位DS18B20(初始化)
- /*********************************************************/
- void DS18B20_ReSet(void)
- {
- uchar i;
- DQ=0;
- i=240;
- while(--i);
- DQ=1;
- i=30;
- while(--i);
- while(~DQ);
- i=4;
- while(--i);
- }
- /*********************************************************/
- // 向DS18B20寫入一個字節(jié)
- /*********************************************************/
- void DS18B20_WriteByte(uchar dat)
- {
- uchar j;
- uchar btmp;
-
- for(j=0;j<8;j++)
- {
- btmp=0x01;
- btmp=btmp<<j;
- btmp=btmp&dat;
-
- if(btmp>0) // 寫1
- {
- DQ=0;
- Delay15us();
- DQ=1;
- Delay15us();
- Delay15us();
- Delay15us();
- Delay15us();
- }
- else // 寫0
- {
- DQ=0;
- Delay15us();
- Delay15us();
- Delay15us();
- Delay15us();
- DQ=1;
- Delay15us();
- }
- }
- }
- /*********************************************************/
- // 讀取溫度值
- /*********************************************************/
- int DS18B20_ReadTemp(void)
- {
- uchar j;
- int b,temp=0;
- DS18B20_ReSet(); // 產(chǎn)生復(fù)位脈
- DS18B20_WriteByte(0xcc); // 忽略ROM指令
- DS18B20_WriteByte(0x44); // 啟動溫度轉(zhuǎn)換指令
- DS18B20_ReSet(); // 產(chǎn)生復(fù)位脈
- DS18B20_WriteByte(0xcc); // 忽略ROM指令
- DS18B20_WriteByte(0xbe); // 讀取溫度指令
- for(j=0;j<16;j++) // 讀取溫度數(shù)量
- {
- DQ=0;
- _nop_();
- _nop_();
- DQ=1;
- Delay15us();
- b=DQ;
- Delay15us();
- Delay15us();
- Delay15us();
- b=b<<j;
- temp=temp|b;
- }
-
- temp=temp*0.0625*10; // 合成溫度值并放大10倍
-
- return (temp); // 返回檢測到的溫度值
- }
- /*********************************************************/
- // 定時器初始化
- /*********************************************************/
- void TimerInit()
- {
- TMOD = 0x01; // 使用定時器0,工作方式1
- TH0 = 248; // 給定時器0的TH0裝初值
- TL0 = 48; // 給定時器0的TL0裝初值
- ET0 = 1; // 定時器0中斷使能
- EA = 1; // 打開總中斷
- TR0 = 1; // 啟動定時器0
- }
- /*********************************************************/
- // 顯示溫度值
- /*********************************************************/
- void ShowTemp(int dat)
- {
- if(dat<0) // 負號
- {
- Buff[0]=Array1[10];
- dat=0-dat;
- }
- else // 百位
- {
- Buff[0]=Array1[dat/1000];
- }
-
- Buff[1]=Array1[dat%1000/100]; // 十位
- Buff[2]=Array2[dat%100/10]; // 個位
- Buff[3]=Array1[dat%10]; // 小數(shù)后一位
- }
- /*********************************************************/
- // 報警判斷
- /*********************************************************/
- void AlarmJudge(int dat)
- {
- if(dat<AlarmLow) // 判斷溫度是否過低
- {
- LedLow=0; // 溫度低指示燈亮
- LedHig=1; // 溫度高指示燈滅
- JdqLow=0; // 溫度過低的繼電器閉合(開始加熱)
- JdqHig=1; // 溫度過高的繼電器斷開(停止降溫)
- Buzzer=0; // 蜂鳴器報警
- }
- else if(dat>AlarmHig) // 判斷溫度是否過高
- {
- LedLow=1; // 溫度低指示燈滅
- LedHig=0; // 溫度高指示燈亮
- JdqLow=1; // 溫度過低的繼電器斷開(停止加熱)
- JdqHig=0; // 溫度過高的繼電器閉合(開始降溫)
- Buzzer=0; // 蜂鳴器報警
- }
- else // 溫度正常
- {
- LedLow=1; // 溫度低指示燈滅
- LedHig=1; // 溫度高指示燈滅
- JdqLow=1; // 溫度過低的繼電器斷開(停止加熱)
- JdqHig=1; // 溫度過高的繼電器斷開(停止降溫)
- Buzzer=1; // 蜂鳴器停止報警
- }
- }
- /*********************************************************/
- // 按鍵掃描
- /*********************************************************/
- void KeyScanf()
- {
- if(KeySet==0) // 如果設(shè)置按鍵被按下
- {
- /* 設(shè)置溫度下限 */
- LedLow=0; // 點亮綠色燈(代表當前正在設(shè)置溫度下限)
- LedHig=1; // 熄滅紅色燈
- Buzzer=1; // 關(guān)閉蜂鳴器
- ShowTemp(AlarmLow); // 顯示溫度下限值
- DelayMs(10); // 延時去抖
- while(!KeySet); // 等待按鍵釋放
- DelayMs(10); // 延時去抖
-
- while(1)
- {
- if(KeyDown==0) // 如果“減”按鍵被按下
- {
- if(AlarmLow>-550) // 判斷當前溫度下限是否大于-55度
- {
- AlarmLow--; // 溫度下限值減去0.1度
- ShowTemp(AlarmLow); // 刷新顯示改變后的溫度下限值
- DelayMs(200); // 延時
- }
- }
-
- if(KeyUp==0) // 如果“加”按鍵被按下
- {
- if(AlarmLow<1250) // 判斷當前溫度下限是否小于125度
- {
- AlarmLow++; // 溫度下限值加上0.1度
- ShowTemp(AlarmLow); // 刷新顯示改變后的溫度下限值
- DelayMs(200); // 延時
- }
- }
-
- if(KeySet==0) // 如果“設(shè)置”按鍵被按下
- {
- break; // 退出溫度下限值的設(shè)置,準備進入上限值的設(shè)置
- }
- }
-
- /* 設(shè)置溫度上限 */
- LedLow=1; // 熄滅綠色燈
- LedHig=0; // 點亮紅色燈(代表當前正在設(shè)置溫度上限)
- ShowTemp(AlarmHig); // 顯示溫度上限值
- DelayMs(10); // 延時去抖
- while(!KeySet); // 等待按鍵釋放
- DelayMs(10); // 延時去抖
-
- while(1)
- {
- if(KeyDown==0) // 如果“減”按鍵被按下
- {
- if(AlarmHig>-550) // 判斷當前溫度上限是否大于-55度
- {
- AlarmHig--; // 溫度上限值減去0.1度
- ShowTemp(AlarmHig); // 刷新顯示改變后的溫度上限值
- DelayMs(200); // 延時
- }
- }
-
- if(KeyUp==0) // 如果“加”按鍵被按下
- {
- if(AlarmHig<1250) // 判斷當前溫度上限是否小于125度
- {
- AlarmHig++; // 溫度上限值加上0.1度
- ShowTemp(AlarmHig); // 刷新顯示改變后的溫度上限值
- DelayMs(200);
- }
- }
-
- if(KeySet==0) // 如果“設(shè)置”按鍵被按下
- {
- break; // 準備退出設(shè)置模式
- }
- }
-
- /* 退出設(shè)置模式 */
- LedLow=1; // 熄滅綠燈
- LedHig=1; // 熄滅紅燈
- DelayMs(10); // 延時去抖
- while(!KeySet); // 等待按鍵釋放
- DelayMs(10); // 延時去抖
- }
- }
- /*********************************************************/
- // 主函數(shù)
- /*********************************************************/
- void main()
- {
- int temp;
- uchar i;
-
- TimerInit(); // 定時器0的初始化(數(shù)碼管的動態(tài)掃描)
-
- Buff[0]=Array1[0]; // 剛上電顯示4個0
- Buff[1]=Array1[0];
- Buff[2]=Array1[0];
- Buff[3]=Array1[0];
-
- for(i=0;i<8;i++) // 由于傳感器剛上電讀出的溫度不穩(wěn)定,因此先進行幾次溫度的讀取并丟棄
- {
- DS18B20_ReadTemp();
- DelayMs(120);
- }
-
- while(1)
- {
- EA=0; // 屏蔽中斷
- temp=DS18B20_ReadTemp(); // 讀取溫度值
- EA=1; // 恢復(fù)中斷
-
- ShowTemp(temp); // 顯示溫度值
-
- AlarmJudge(temp); // 判斷是否需要報警
-
- for(i=0;i<100;i++) // 延時并進行按鍵掃描
- {
- KeyScanf();
- DelayMs(10);
- }
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
程序(Keil版).zip
(47.54 KB, 下載次數(shù): 117)
2018-7-16 12:24 上傳
點擊文件名下載附件
|