由温度决定风扇转速
溫度控制風扇轉速
代碼中LCD和18B20完全是照搬的百度上網友的代碼,但不記得具體搬的是哪里了?!瓕Σ黄鹪髡摺?/p>
DIY的2.1音響,由于作的功放箱子體積有限,芯片溫度較高,底噪時能到60度,須要加風扇,心太大,買的風扇轉速太高,太吵,為了使溫度受控而風扇不要太吵,百度到處找,終于搞出這個小程序;
使用芯片: STC89C52RC
 顯示硬件: LCD1602;
 溫度硬件:18B20
 風扇硬件: 臺達,12V0.4A 4線的,即±兩線,方波輸出線,PWM轉速控制線;
運行效果:PWM頻率81Hz,PWM Duty 寬度可調,風扇轉速隨便溫度上升而上升,當然風扇噪聲也跟著變大,全速的時候,即Duty為10的時候,占空比用示波器看是90%樣子。應選用不那么暴力的風扇。12V0.4A左右即可。電流越大,噪聲越大。
程序代碼如下,可直接使用。
#include<reg52.h> #include<intrins.h> #define uchar unsigned char typedef unsigned char uint8; typedef unsigned int uint16; typedef unsigned long uint32;sfr P4 = 0xe8; sbit led1 = P4^0; sbit led2 = P3^7; sbit rs=P2^4; sbit rw=P2^5; sbit e=P2^6; sbit dq=P1^0; sbit pwm=P1^2;uint8 d[16]=" Internal Temp "; uint8 num[10]="0123456789"; uint8 a,c,temp;char time,RDD,speed;void delay(uint16 i) {while(i--); } void wrc(uint8 c) {delay(1000);rs=0;rw=0;e=0;P0=c;e=1;delay(10);e=0; } void wrd(uint8 dat) {delay(1000);rs=1;rw=0;e=0;P0=dat;e=1;delay(10);e=0;rs=0; } void lcdinit() {delay(10);wrc(0x38);wrc(0x38);wrc(0x38);wrc(0x06);wrc(0x0c);wrc(0x01); } void ds18b20init() //18b20的初始化 {dq=1;delay(1);dq=0;delay(80);dq=1;delay(5);dq=0;delay(20);dq=1;delay(35); } void ds18b20wr(uint8 dat) //18b20寫數據 {uint8 i;for(i=0;i<8;i++){dq=0;dq=dat&0x01;dat>>=1;delay(8);//在時序上只有這一塊對時序要求最準確,他的時間必須大于15usdq=1;delay(1);} } uint8 ds18b20rd() //18b20讀數據 {uint8 value,i;for(i=0;i<8;i++) {dq=0;value>>=1;dq=1;if(dq==1)value|=0x80;delay(8);//在這一塊也對時間要求特別準確,整段程序必須大于60us }return value; } uint8 readtemp() //讀取溫度內需要復位的 {uint8 b;ds18b20init(); //初始化ds18b20wr(0xcc); //發送忽略ROM指令ds18b20wr(0x44); //發送溫度轉換指令delay(100);ds18b20init(); //初始化ds18b20wr(0xcc); //發送忽略ROM指令ds18b20wr(0xbe); //發讀暫存器指令a=ds18b20rd(); //溫度的低八位b=ds18b20rd(); //溫度的高八位b<<=4; //ssss s***;s為標志位s=0表示溫度值為正數,s=1溫度值為負數c=b&0x80; //溫度正負標志位確認b+=(a&0xf0)>>4;a=a&0x0f; //溫度的小數部分return b; } void display() {uint16 i,k;float dio;dio=a*0.0625;k=dio*10000;//取小數點后兩位有效數字wrc(0x80);//+0x00);for(i=0;i<16;i++){wrd(d[i]);}wrc(0x80+0x43);if(c==0x80) //讀取到負溫度即為補碼,要將其轉換成源碼{wrd('-');temp=temp-1;temp=(~temp)|0x80;//負數的補碼即為反碼+1;而負數的反碼為其源碼取反,除了符號位;正數的補碼等于正數的反碼等于正數的源碼} else{wrd('+');temp=(temp);} wrd(num[temp/100]);wrd(num[temp%100/10]);wrd(num[temp%100%10]);wrd('.');wrd(num[k/1000]);wrd(num[k%1000/100]);wrd(0xdf);wrd('C'); }void time0init() //定時器0初始化 {TMOD=0x02;TH0=0xFC;TL0=0x18; //1msTR0=1;EA=1;ET0=1; }void time1init() //定時器0初始化 {TMOD=0x01;TH1=0xFB;TL1=0xAE; //1msTR1=1;EA=1;ET1=1; }void TempSpeed() //根據溫度,設定風扇轉速; {if(28>temp && temp>=20){speed=1;} //比如:當溫度大于等于20度,同時,小于28度時,風扇僅10%全速;else if(30>temp && temp>=28){speed=2;}else if(31>temp && temp>=30){speed=4;}else if(32>temp && temp>=31){speed=6;}else if(50>temp && temp>=32){speed=8;}else if(temp>=50){speed=10;} }void main() {time0init();time1init();lcdinit();PT0 = 1;speed=1;while(1); }void time0()interrupt 1 {EA = 0;//關閉定時器0;TR1 = 1;//開啟定時器1;TH0 = 0xFC;TL0 = 0x18;TR1 = 0;//關閉定時器1;EA = 1;//開啟定時器0;time++;if(time>10){time = 0;}if(time<(speed)){pwm = 1;led1 = 1;led2 = 1;}else{pwm = 0;led1 = 0;led2 = 0;} }void time1()interrupt 3 {EA = 0;TH1 = 0Xfb;TL1 = 0Xae;EA = 1;RDD++;if(RDD>=10){RDD=0;}if(RDD<5){temp=readtemp();}else{display();TempSpeed();} }總結
 
                            
                        - 上一篇: Hadoop实战: 论坛点击流日志分析
- 下一篇: QT布局以及使用QSS
