|
電路原理圖如下:
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
元件清單:
Comment Description Designator
10uF 電容 C1
20 電容 C2, C3
發(fā)光二極管 D1
SMG04_1 數(shù)碼管 DS1
紅外熱釋電 人體感應(yīng)傳感器 P1
Header 2 電源接口 P2, P3
9012 三極管 Q1, Q2, Q3, Q4, Q5
1K 電阻 R1, R2, R3, R8, R9, R10, R11, R12
1K 電阻 R4, R5, R6, R7, R15
1K 電阻 R13
10K 電阻 R14, R16
SW-PB 按鍵 S1, S2, S3, S4
sw-灰色 電源開關(guān) SW1
單片機(jī) 單片機(jī) U1
DS18B20 溫度傳感器 U2
12M 晶振 Y1
單片機(jī)源程序如下:
- #include <reg52.h> //調(diào)用單片機(jī)頭文件
- #define uchar unsigned char //無(wú)符號(hào)字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無(wú)符號(hào)整型 宏定義 變量范圍0~65535
- //數(shù)碼管段選定義 0 1 2 3 4 5 6 7 8 9
- uchar code smg_du[]={0x28,0xe4,0x42,0x72,0xe5,0xa8,0x41,0x77,0x20,0xa0,
- 0x60,0x25,0x39,0x26,0x31,0x71,0xff}; //斷碼
- //數(shù)碼管位選定義
- uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};
- uchar dis_smg[8] = {0};
- uchar smg_i = 3; //顯示數(shù)碼管的個(gè)位數(shù)
- sbit dq = P2^4; //18b20 IO口的定義
- sbit hw = P2^5;
- uchar miao = 30;
- uchar flag_en;
- bit flag_lj_en; //按鍵連加使能
- bit flag_lj_3_en; //按鍵連3次連加后使能 加的數(shù)就越大了
- uchar key_time,key_value; //用做連加的中間變量
- bit key_500ms ;
- sbit pwm = P2^3;
- uchar f_pwm_l ; //越小越慢
- uint temperature ; //
- bit flag_200ms ;
- uchar menu_1; //菜單設(shè)計(jì)的變量
- uint t_high = 200,t_low = 100; //溫度上下限報(bào)警值
- /***********************1ms延時(shí)函數(shù)*****************************/
- void delay_1ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<120;j++);
- }
- /***********************小延時(shí)函數(shù)*****************************/
- void delay_uint(uint q)
- {
- while(q--);
- }
- /***********************數(shù)碼顯示函數(shù)*****************************/
- void display()
- {
- static uchar i;
- i++;
- if(i >= smg_i)
- i = 0;
- P1 = 0xff; //消隱
- P3 = smg_we[i]; //位選
- P1 = dis_smg[i]; //段選
- }
- /***********************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; //把總線拿高 釋放總線
- }
- /*************寫18b20內(nèi)的數(shù)據(jù)***************/
- void write_18b20(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- { //寫數(shù)據(jù)是低位開始
- dq = 0; //把總線拿低寫時(shí)間隙開始
- dq = dat & 0x01; //向18b20總線寫數(shù)據(jù)了
- delay_uint(5); // 60us
- dq = 1; //釋放總線
- dat >>= 1;
- }
- }
- /*************讀取18b20內(nèi)的數(shù)據(jù)***************/
- uchar read_18b20()
- {
- uchar i,value;
- for(i=0;i<8;i++)
- {
- dq = 0; //把總線拿低讀時(shí)間隙開始
- value >>= 1; //讀數(shù)據(jù)是低位開始
- dq = 1; //釋放總線
- if(dq == 1) //開始讀寫數(shù)據(jù)
- value |= 0x80;
- delay_uint(5); //60us 讀一個(gè)時(shí)間隙最少要保持60us的時(shí)間
- }
- return value; //返回?cái)?shù)據(jù)
- }
- /*************讀取溫度的值 讀出來(lái)的是小數(shù)***************/
- uint read_temp()
- {
- uint value;
- 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ā)出讀取暫存器命令
-
- low = read_18b20(); //讀溫度低字節(jié)
- value = read_18b20(); //讀溫度高字節(jié)
- value <<= 8; //把溫度的高位左移8位
- value |= low; //把讀出的溫度低位放到value的低八位中
- value *= 0.625; //轉(zhuǎn)換到溫度值 小數(shù)
- return value; //返回讀出的溫度 帶小數(shù)
- }
- /*************定時(shí)器0初始化程序***************/
- void time_init()
- {
- EA = 1; //開總中斷
- TMOD = 0X21; //定時(shí)器0、定時(shí)器1工作方式1
- ET0 = 1; //開定時(shí)器0中斷
- TR0 = 1; //允許定時(shí)器0定時(shí)
- ET1 = 1; //開定時(shí)器0中斷
- TR1 = 1; //允許定時(shí)器0定時(shí)
- }
- /********************獨(dú)立按鍵程序*****************/
- uchar key_can; //按鍵值
- void key() //獨(dú)立按鍵程序
- {
- static uchar key_new;
- key_can = 20; //按鍵值還原
- P2 |= 0x07;
- if((P2 & 0x07) != 0x07) //按鍵按下
- {
- if(key_500ms == 1) //連加
- {
- key_500ms = 0;
- key_new = 1;
- }
- delay_1ms(1); //按鍵消抖動(dòng)
- if(((P2 & 0x07) != 0x07) && (key_new == 1))
- { //確認(rèn)是按鍵按下
- key_new = 0;
- switch(P2 & 0x07)
- {
- case 0x06: key_can = 1; break; //得到k2鍵值
- case 0x04: key_can = 2; break; //得到k3鍵值
- case 0x02: key_can = 3; break; //得到k4鍵值
- }
- flag_lj_en = 1; //連加使能
- }
- }
- else
- {
- if(key_new == 0)
- {
- key_new = 1;
- flag_lj_en = 0; //關(guān)閉連加使能
- flag_lj_3_en = 0; //關(guān)閉3秒后使能
- key_value = 0; //清零
- key_time = 0;
- key_500ms = 0;
- }
- }
- }
- /****************按鍵處理數(shù)碼管顯示函數(shù)***************/
- void key_with()
- {
- if(key_can == 1) //設(shè)置鍵
- {
- f_pwm_l = 30;
- menu_1 ++;
- if(menu_1 >= 3)
- {
- menu_1 = 0;
- smg_i = 3; //數(shù)碼管顯示3位
- }
- }
- if(menu_1 == 1) //設(shè)置高溫報(bào)警
- {
- smg_i = 4; //數(shù)碼管顯示4位
- if(key_can == 2)
- {
- if(flag_lj_3_en == 0)
- t_high ++ ; //按鍵按下未松開自動(dòng)加三次
- else
- t_high += 10; //按鍵按下未松開自動(dòng)加三次之后每次自動(dòng)加10
- if(t_high > 990)
- t_high = 990;
- }
- if(key_can == 3)
- {
- if(flag_lj_3_en == 0)
- t_high -- ; //按鍵按下未松開自動(dòng)減三次
- else
- t_high -= 10; //按鍵按下未松開自動(dòng)減三次之后每次自動(dòng)減10
- if(t_high <= t_low)
- t_high = t_low + 1;
- }
- dis_smg[0] = smg_du[t_high % 10]; //取小數(shù)顯示
- dis_smg[1] = smg_du[t_high / 10 % 10] & 0xdf; //取個(gè)位顯示
- dis_smg[2] = smg_du[t_high / 100 % 10] ; //取十位顯示
- dis_smg[3] = 0x64; //H
- }
- if(menu_1 == 2) //設(shè)置低溫報(bào)警
- {
- smg_i = 4; //數(shù)碼管顯示4位
- if(key_can == 2)
- {
- if(flag_lj_3_en == 0)
- t_low ++ ; //按鍵按下未松開自動(dòng)加三次
- else
- t_low += 10; //按鍵按下未松開自動(dòng)加三次之后每次自動(dòng)加10
- if(t_low >= t_high)
- t_low = t_high - 1;
- }
- if(key_can == 3)
- {
- if(flag_lj_3_en == 0)
- t_low -- ; //按鍵按下未松開自動(dòng)減三次
- else
- t_low -= 10; //按鍵按下未松開自動(dòng)加三次之后每次自動(dòng)加10
- if(t_low <= 10)
- t_low = 10;
- }
- dis_smg[0] = smg_du[t_low % 10]; //取小數(shù)顯示
- dis_smg[1] = smg_du[t_low / 10 % 10] & 0xdf; //取個(gè)位顯示
- dis_smg[2] = smg_du[t_low / 100 % 10] ; //取十位顯示
- dis_smg[3] = 0x3D; //L
- }
- }
- /****************風(fēng)扇控制函數(shù)***************/
- void fengshan_kz()
- {
- if(flag_en == 1)
- {
- if(temperature >= t_high) //風(fēng)扇全開
- {
- TR1 = 1;
- pwm = 0;
- }
- else if((temperature < t_high) && (temperature >= t_low)) //風(fēng)扇緩慢
- {
- f_pwm_l = 60;
- TR1 = 1;
- }
- else if(temperature < t_low) //關(guān)閉風(fēng)扇
- {
- TR1 = 0;
- pwm = 1;
- }
- }
- }
-
- /****************主函數(shù)***************/
- void main()
- {
- static uchar value;
- time_init(); //初始化定時(shí)器
- temperature = read_temp(); //先讀出溫度的值
- delay_1ms(650);
- temperature = read_temp(); //先讀出溫度的值
- dis_smg[0] = smg_du[temperature % 10]; //取溫度的小數(shù)顯示
- dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個(gè)位顯示
- dis_smg[2] = smg_du[temperature / 100 % 10] ; //取溫度的十位顯示
- while(1)
- {
- key(); //按鍵程序
- if(key_can < 10)
- {
- key_with(); //設(shè)置報(bào)警溫度
- }
- if(flag_200ms == 1) //200ms 處理一次溫度程序
- {
- flag_200ms = 0;
- temperature = read_temp(); //先讀出溫度的值
- if(menu_1 == 0)
- {
- smg_i = 3;
- dis_smg[0] = smg_du[temperature % 10]; //取溫度的小數(shù)顯示
- dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個(gè)位顯示
- dis_smg[2] = smg_du[temperature / 100 % 10] ; //取溫度的十位顯示
- }
- fengshan_kz(); //風(fēng)扇控制函數(shù)
- value ++;
- if(value >= 4)
- {
- value = 0;
- if(miao != 0)
- {
- miao --; //時(shí)間減1
- }
- if(miao == 0)
- flag_en = 0;
- }
- if(hw == 1) //感應(yīng)到人
- {
- miao = 30;
- flag_en = 1;
- }
- }
- display(); //數(shù)碼管顯示函數(shù)
- }
- }
- /*************定時(shí)器0中斷服務(wù)程序***************/
- void time0_int() interrupt 1
- {
- static uchar value; //定時(shí)2ms中斷一次
- TH0 = 0xf8;
- TL0 = 0x30; //2ms
- value++;
- if(value >= 150)
- {
- value = 0;
- flag_200ms = 1;
- }
- if(flag_lj_en == 1) //按下按鍵使能
- {
- key_time ++;
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
智能溫控風(fēng)扇設(shè)計(jì).7z
(2.31 MB, 下載次數(shù): 81)
2020-12-15 20:44 上傳
點(diǎn)擊文件名下載附件
|
|