系統(tǒng)主要設(shè)計(jì)了一個(gè)基于單片機(jī)的風(fēng)扇溫控儀,以單片機(jī)和DS18B20 傳感器為核心,具有溫度顯示和控制風(fēng)扇轉(zhuǎn)速功能DS18B20 傳感器,將檢測(cè)到的溫度轉(zhuǎn)化為數(shù)字信號(hào),單片機(jī)對(duì)輸入的數(shù)字信號(hào)進(jìn)行分析處理,當(dāng)溫度高于上限值時(shí),風(fēng)扇全速旋轉(zhuǎn);當(dāng)溫度低于下限時(shí),風(fēng)扇停轉(zhuǎn);當(dāng)溫度處于上限值與下限 之間時(shí),風(fēng)扇轉(zhuǎn)速越慢,。圖1 所示為系統(tǒng)設(shè)計(jì)結(jié)構(gòu)框圖。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (16.08 KB, 下載次數(shù): 48)
下載附件
2021-5-14 03:14 上傳
電路原理圖如下:
51hei.png (34.05 KB, 下載次數(shù): 51)
下載附件
2021-5-14 03:16 上傳
單片機(jī)源程序如下:
- #include <reg52.h>
- #include <stdio.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit dq=P3^6;
- sbit w4=P2^6;
- sbit w3=P2^4;
- sbit w2=P2^2;
- sbit w1=P2^0;
- sbit dp=P0^7;
- sbit fs=P3^7;//風(fēng)扇接口
- sbit key_shezhi=P1^5;
- sbit key_jia=P1^6;
- sbit key_jian=P1^7;
- uchar flag_0;
- uint t_max=250,t_max_1=300;
- uint count=0;
- int wendu,t;
- uchar speed; //速度變量
- void delay(uint z) //延時(shí)函數(shù)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /********************************/
- void pro()//按鍵處理函數(shù)
- {
- if(key_shezhi==0)
- {
- delay(10);
- if(key_shezhi==0)
- {
- flag_0++;
- if(flag_0>=3)
- flag_0=0;
- while(!key_shezhi) ;
- }
- }
- }
- /**********************************/
- uchar code table[]={
- 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0xbf//0 1 2 3......7 8 9 的字形碼
- };
- uchar code table1[]={
- 0xc7,0x89 // L H 的字形碼
- };
- uint temp,mm;uchar i;float f_temp;
- /***********************小延時(shí)函數(shù)*****************************/
- void delay_uint(uint q)
- {
- while(q--);
- }
- /*******************************************************
- /***********************18b20初始化函數(shù)*****************************/
- void init_18b20()
- {
- bit q;
- dq = 1; //把總線拿高
- delay_uint(1); //15us
- dq = 0; //給復(fù)位脈沖
- delay_uint(80); //750us
- dq = 1; //把總線拿高 等待
- delay_uint(10); //110us
- q = dq; //讀取18b20初始化信號(hào)
- delay_uint(20); //200us
- dq = 1; //把總線拿高 釋放總線
- }
- /*************寫(xiě)18b20內(nèi)的數(shù)據(jù)***************/
- void write_18b20(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- { //寫(xiě)數(shù)據(jù)是低位開(kāi)始
- dq = 0; //把總線拿低寫(xiě)時(shí)間隙開(kāi)始
- dq = dat & 0x01; //向18b20總線寫(xiě)數(shù)據(jù)了
- delay_uint(5); // 60us
- dq = 1; //釋放總線
- dat >>= 1;
- }
- }
- /*************讀取18b20內(nèi)的數(shù)據(jù)***************/
- uchar read_18b20()
- {
- uchar i,wendu;
- for(i=0;i<8;i++)
- {
- dq = 0; //把總線拿低讀時(shí)間隙開(kāi)始
- wendu >>= 1; //讀數(shù)據(jù)是低位開(kāi)始
- dq = 1; //釋放總線
- if(dq == 1) //開(kāi)始讀寫(xiě)數(shù)據(jù)
- wendu |= 0x80;
- delay_uint(5); //60us 讀一個(gè)時(shí)間隙最少要保持60us的時(shí)間
- }
- return wendu; //返回?cái)?shù)據(jù)
- }
- /*************讀取溫度的值 讀出來(lái)的是小數(shù)***************/
- uint read_temp()
- {
- uint wendu;
- uchar low; //在讀取溫度的時(shí)候如果中斷的太頻繁了,就應(yīng)該把中斷給關(guān)了,否則會(huì)影響到18b20的時(shí)序
- init_18b20(); //初始化18b20
- write_18b20(0xcc); //跳過(guò)64位ROM
- write_18b20(0x44); //啟動(dòng)一次溫度轉(zhuǎn)換命令
- delay_uint(50); //500us
- init_18b20(); //初始化18b20
-
- write_18b20(0xcc); //跳過(guò)64位ROM
- write_18b20(0xbe); //發(fā)出讀取暫存器命令
-
- EA = 0;
- low = read_18b20(); //讀溫度低字節(jié)
- wendu = read_18b20(); //讀溫度高字節(jié)
- EA = 1;
- wendu <<= 8; //把溫度的高位左移8位
- wendu |= low; //把讀出的溫度低位放到value的低八位中
- wendu *= 0.625; //轉(zhuǎn)換到溫度值 小數(shù)
- return wendu; //返回讀出的溫度 帶小數(shù)
- }
- void display0()
- {
- P0=0xff;//消隱
- w1=0; //選通第一位數(shù)碼管
- if(speed>5) //如果speed的值>5則檔位顯示speed-5,比如speed=6,則顯示1檔
- P0=table[speed-5];//顯示檔位
- else //否則speed的值如果小于5,則顯示0檔
- P0=table[0];//顯示檔位
- delay(2);//延遲一會(huì)
- w1=1;//關(guān)閉第一位數(shù)碼管
-
- P0=0xff;//第二位數(shù)碼管的顯示原理及方法同上
- w2=0;
- P0=0xbf;//顯示-
- delay(2);
- w2=1;
-
- P0=0xff;
- w3=0;
- P0=table[wendu/100];//顯示溫度十位
- delay(2);
- w3=1;
-
- P0=0xff;
- w4=0;
- P0=table[wendu%100/10];//顯示溫度各位
- delay(2);
- w4=1;
- }
- void zi_dong()//自動(dòng)溫控模式
- {
- // 此函數(shù)的目的是將上限和下限的差值平均為5份,每一份對(duì)應(yīng)一個(gè)速度值 14-25
- if(wendu<t_max) //溫度小于下限
- speed=0; //速度0檔
- else if(wendu>=t_max&&(wendu<(uint)((t_max_1-t_max)/4+t_max))) //溫度大于下限并且小于(上限減去下限)除以4加下限
- speed=6; //6檔 14-16.75 14-15
- else if((wendu>=(uint)((float)(t_max_1-t_max)/4+t_max))&&(wendu<(uint)((float)(t_max_1-t_max)/2+t_max))) //溫度大于 (上限減去下限)除以4加下限 并且小于(上限減去下限)除以2加下限
- speed=7; //7檔 16-19.5 16-18
- else if((wendu>=(uint)(t_max_1-t_max)/2+t_max)&&(wendu<(uint)((float)((float)(t_max_1-t_max)/4)*3+t_max))) //溫度大于 (上限減去下限)除以2加下限 并且小于(上限減去下限)除以4乘以3加下限
- speed=8; //8檔 19-22.25 19-21
- else if((wendu>=(uint)((float)((float)(t_max_1-t_max)/4)*3+t_max))&&wendu<t_max_1) //溫度大于 (上限減去下限)除以4乘以3加下限 并且小于上限
- speed=9; //9檔 22-24 22-24
- else if(wendu>=t_max_1) //大于上限
- speed=10; //10檔 >25
- }
- /***************************************/
- void fengshan()
- {
- uchar m;
- if(m<speed) //m值小于speed
- fs=0; //打開(kāi)風(fēng)扇
- else if(m>=speed) //否則
- fs=1; //關(guān)閉風(fēng)扇
- m++; //m加
- if(m>=10) //m極愛(ài)到10,也就是2ms
- m=0;
- }
- /**************************************/
- /**************************************/
- void display1()
- {
- P0=0xff;//消隱
- w1=0;//選通第一位數(shù)碼管
- P0=table1[0];//顯示 L
- delay(2);//延遲一會(huì)
- w1=1;//關(guān)閉第一位數(shù)碼管
-
- P0=0xff;//第二位數(shù)碼管顯示方法及原理同上
- w2=0;
- P0=0xbf;//顯示 -
- delay(2);
- w2=1;
-
- P0=0xff;
- w3=0;
- P0=table[t_max/100];//顯示設(shè)置下限值的十位
- delay(2);
- w3=1;
-
- P0=0xff;
- w4=0;
- P0=table[t_max%100/10];//顯示設(shè)置下限值的個(gè)位
- delay(2);
- w4=1;
- }
- /**************************************/
- void display2()
- {
- P0=0xff;
- w1=0;
- P0=table1[1];//顯示 H
- delay(2);
- w1=1;
-
- P0=0xff;
- w2=0;
- P0=0xbf;//顯示 -
- delay(2);
- w2=1;
-
- P0=0xff;
- w3=0;
- P0=table[t_max_1/100];//顯示設(shè)置上限值得十位
- delay(2);
- w3=1;
-
- P0=0xff;
- w4=0;
- P0=table[t_max_1%100/10];//顯示設(shè)置上限值得個(gè)位
- delay(2);
- w4=1;
- }
- /***************************************/
- void shezhi()
- {
- if(flag_0==1)//flag_0==0時(shí),為正常顯示。等于1時(shí),為設(shè)置下限位值。等2時(shí)為設(shè)置上限為置
- {
- if(key_jia==0)//當(dāng)設(shè)置下限位值時(shí),按下加鍵
- {
- delay(10);//延遲消抖
- if(key_jia==0)//確認(rèn)加鍵已按下
- {
- t_max=t_max+10;//對(duì)下限位值每次加10
- if(t_max>=t_max_1) //防止低溫度高于高溫度//如果下限位值設(shè)置時(shí)超過(guò)了上限位置
- t_max=t_max_1-10; //則讓下限位值-10
- while(!key_jia);//松手檢測(cè)
- }
- }
- if(key_jian==0)//如果鍵鍵按下了,同上
- {
- delay(10);
- if(key_jian==0)
- {
- t_max=t_max-10;
- while(!key_jian);
- }
- }
- }
- if(flag_0==2)//對(duì)上限位設(shè)置時(shí)
- {
- if(key_jia==0)
- {
- delay(10);
- if(key_jia==0)
- {
- t_max_1=t_max_1+10;
- while(!key_jia);
- }
- }
- if(key_jian==0)
- {
- delay(10);
- if(key_jian==0)
- {
- t_max_1=t_max_1-10;
- if(t_max_1<=t_max) //防止高溫度小于低溫度
- t_max_1=t_max+10;
- while(!key_jian);
- }
- }
- }
- }
- void display()
- {
- if(flag_0==0)//flag_0==0時(shí),為正常顯示。等于1時(shí),為設(shè)置下限位值。等2時(shí)為設(shè)置上限為置
- display0();//正常顯示
- else if(flag_0==1)
- display1();//設(shè)置下限時(shí)的顯示
- else if(flag_0==2)
- display2(); //設(shè)置上限時(shí)的顯示
- }
- void main()
- {
- while(1)
- {
-
- read_18b20();//讀取溫度傳感器中的數(shù)據(jù)
-
- t=read_temp();//把讀出的數(shù)據(jù)賦給t
- if(t>=0&&t<=1250) //溫度合法范圍,不在這個(gè)范圍就是沒(méi)有獲取到合適的值
- {
- wendu=t;
- }
- pro();//按鍵處理
- display();//顯示處理
- shezhi();//設(shè)置按鍵處理
- fengshan();//風(fēng)扇處理
- zi_dong();//自動(dòng)擋風(fēng)扇處理
- }
- }
復(fù)制代碼
51hei.png (8.43 KB, 下載次數(shù): 56)
下載附件
2021-5-14 03:16 上傳
全部資料51hei下載地址:
小風(fēng)扇.7z
(269.68 KB, 下載次數(shù): 36)
2021-5-13 22:53 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|