· 1.本設計基于STC89C51/52(與AT89S51/52、AT89C51/52通用,可任選)單片機 · 2.采用DS18B20溫度傳感器測溫,74HC573驅動數碼管顯示溫度和風扇的檔位。 · 3.共3個按鍵:設置、加、減。按一下設置可以設置上限,再按下設置下限,均可以按鍵加減調整。 · 4.利用PWM調速,當溫度低于下限時,風扇不轉動,當溫度處于上、下限之間時1檔轉動(50%的轉速),當溫度超過上限時,全速轉動。 使用說明: 一共3個按鍵:設置、加、減 按下設置鍵的時候才可以加減。 按一下設置鍵,是設置溫度的上限,再按下設置鍵,是設置溫度的下限,再按下設置鍵是退出并保存。 元件清單: 1) 7*9萬用板 2) 風扇 3) STC89C51單片機 4) 74hc573 5) 40腳IC座 6) 20腳IC座 7) 0.56四位一體共陰數碼管 8) 10k電阻*3 9) 1k電阻*2 10) 103排阻 11) DS18B20 12) 10uf電容 13) 12M晶振 14) 30pf瓷片電容*2 15) 8550三極管 16) 8050三極管 17) 3p排針 18) 按鍵*3 19) DC電源接口 20) 自鎖開關 21) 導線若干 22) 焊錫若干
23) 電源線或電池盒+DC電源插頭 - <font color="#000000">#include<reg51.h>
- #include<intrins.h> //包含頭文件
- #define uchar unsigned char
- #define uint unsigned int //宏定義
- ////////////////////
- sbit dj=P1^0;//電機控制端接口
- sbit DQ=P1^6;//溫度傳感器接口
- //////////按鍵接口/////////////////////////////////
- sbit key1=P3^5;//設置溫度
- sbit key2=P3^6;//溫度加
- sbit key3=P3^7;//溫度減
- //////////////////////////////////////////////////////
- sbit w1=P2^4;
- sbit w2=P2^5;
- sbit w3=P2^6;
- sbit w4=P2^7; //數碼管的四個位
- /////共陰數碼管段選//////////////////////////////////////////////
- uchar table[22]=
- {0x3F,0x06,0x5B,0x4F,0x66,
- 0x6D,0x7D,0x07,0x7F,0x6F,
- 0x77,0x7C,0x39,0x5E,0x79,0x71,
- 0x40,0x38,0x76,0x00,0xff,0x37};//'-',L,H,滅,全亮,n 16-21
- uint wen_du; //溫度變量
- uint shang,xia; //對比溫度暫存變量
- uchar dang;//檔位顯示
- uchar flag;
- uchar d1,d2,d3;//顯示數據暫存變量
- void delay(uint ms) //延時函數,大約延時25us
- {
- uchar x;
- for(ms;ms>0;ms--)
- for(x=10;x>0;x--);
- }
- /***********ds18b20延遲子函數(晶振12MHz )*******/
- void delay_18B20(uint i)
- {
- while(i--);
- }
- /**********ds18b20初始化函數**********************/
- void Init_DS18B20()
- {
- uchar x=0;
- DQ=1; //DQ復位
- delay_18B20(8); //稍做延時
- DQ=0; //單片機將DQ拉低
- delay_18B20(80); //精確延時 大于 480us
- DQ=1; //拉高總線
- delay_18B20(14);
- x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- delay_18B20(20);
- }
- /***********ds18b20讀一個字節**************/
- uchar ReadOneChar()
- {
- uchar i=0;
- uchar dat=0;
- for (i=8;i>0;i--)
- {
- DQ=0; // 給脈沖信號
- dat>>=1;
- DQ=1; // 給脈沖信號
- if(DQ)
- dat|=0x80;
- delay_18B20(4);
- }
- return(dat);
- }
- /*************ds18b20寫一個字節****************/
- void WriteOneChar(uchar dat)
- {
- uchar i=0;
- for (i=8;i>0;i--)
- {
- DQ=0;
- DQ=dat&0x01;
- delay_18B20(5);
- DQ=1;
- dat>>=1;
- }
- }
- /**************讀取ds18b20當前溫度************/
- void ReadTemperature()
- {
- uchar a=0;
- uchar b=0;
- uchar t=0;
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳過讀序號列號的操作
- WriteOneChar(0x44); // 啟動溫度轉換
- delay_18B20(100); // this message is wery important
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
- delay_18B20(100);
- a=ReadOneChar(); //讀取溫度值低位
- b=ReadOneChar(); //讀取溫度值高位
- wen_du=((b*256+a)>>4); //當前采集溫度值除16得實際溫度值
- }
- void display()//顯示溫度
- {
- w1=0;P0=table[d1];delay(10); //第1位
- P0=0x00;w1=1;delay(1);
-
- w2=0;P0=table[16];delay(10);//第2位
- P0=0x00;w2=1;delay(1);
- w3=0;P0=table[d2]; delay(10);//第3位
- P0=0x00;w3=1;delay(1);
- w4=0;P0=table[d3];delay(10);//第4位
- P0=0x00;w4=1;delay(1);
- }
- void zi_keyscan()//自動模式按鍵掃描函數
- {
- if(key1==0) //設置鍵按下
- {
- delay(30); //延時去抖
- if(key1==0)flag=1; //再次判斷按鍵,按下的話進入設置狀態
- while(key1==0);//松手檢測 //按鍵釋放
- }
- while(flag==1) //進入設置上限狀態
- {
- d1=18;d2=shang/10;d3=shang%10; //顯示字母H 和上限溫度值
- display(); //調用顯示函數
- if(key1==0) //判斷設置鍵是否按下
- {
- delay(30); //延時去抖
- if(key1==0)flag=2; //按鍵按下,進入設置下限模式
- while(key1==0);//松手檢測
- }
- if(key2==0) //加鍵按下
- {
- delay(30); //延時去抖
- if(key2==0) //加鍵按下
- {
- shang+=5; //上限加5
- if(shang>=100)shang=100; //上限最大加到100
- }while(key2==0);//松手檢測
- }
- if(key3==0) //減鍵按下
- {
- delay(30); //延時去抖
- if(key3==0) //減鍵按下
- {
- shang-=1; //上限減1
- if(shang<=10)shang=10; //上限最小減到10
- }while(key3==0);//松手檢測
- }
- }
- while(flag==2) //設置下限
- {
- d1=17;d2=xia/10;d3=xia%10; //顯示字母L 顯示下限溫度值
- display(); //以下注釋同上
- if(key1==0)
- {
- delay(30);
- if(key1==0)flag=0;
- while(key1==0);//松手檢測
- }
- if(key2==0)
- {
- delay(30);
- if(key2==0)
- {
- xia+=5;
- if(xia>=95)xia=95;
- }while(key2==0);//松手檢測
- }
- if(key3==0)
- {
- delay(30);
- if(key3==0)
- {
- xia-=1;
- if(xia<=0)xia=0;
- }while(key3==0);//松手檢測
- }
- }
- }
- void zi_dong()//自動溫控模式
- {
- uchar i;
- d1=dang;d2=wen_du/10;d3=wen_du%10; //顯示檔位,顯示當前溫度值
- zi_keyscan();//按鍵掃描函數
- display(); //調用顯示函數
- if(wen_du<xia){dj=0;dang=0;}//低于下限 檔位為0 電機停止
- if((wen_du>=xia)&&(wen_du<=shang))//溫度大于下限,小于上限 1擋
- {
- dang=1; //檔位置1
- for(i=0;i<3;i++){dj=0;display();zi_keyscan();} //PWM通過延時得到
- for(i=0;i<6;i++){dj=1;display();zi_keyscan();}
- }
- if(wen_du>shang){dj=1;dang=2;}//高溫全速
- }
- void main() //主函數
- {
- uchar j;
- dj=0; //電機開
- shang=30;
- xia=20; //初始上下限值
- for(j=0;j<80;j++) //先讀取溫度值,防止開機顯示85
- ReadTemperature();
- while(1) //進入while循環
- {
- ReadTemperature(); //讀取溫度值
- for(j=0;j<100;j++)zi_dong();//自動溫控模式
- }
- }</font>
復制代碼
|