|
日前幫忙修的 擴大機發現溫度太高4~50度,怕他太早"鳳還巢" 就想要幫他裝散熱風扇,網路找了一下電路 好像都不太理想,不是零件不在手上就是轉起來不太順(那時候沒想到用 OP比較器) 一心就是想要"簡單",沒想到就沒完沒了,又要零件少,又要手頭的零件,又要控速,...
最後,好像沒有比較省,只是也學到了不少東西就是了
不知道為何原因 220uF/25V電容器居然變成 22歐姆,所以加裝了一個二極體,不知道有沒有效果!!
電晶體的放大率好像不能太小!! 我還加了一個10K電阻提升,萬一MCU不動作還可以一值轉動散熱(要是輸出一值為LOW也就沒有效果了) ..
10K電阻配合10K/25度的 NTC 熱敏電阻(薄膜式)效果還不錯,溫度 20度開始轉動,希望 每提高1度 佔空比差2%(後來好像變成 4%,程式寫錯了) 溫度到45度以上就全速了...
浮點運算遇到一些問題,如同 XIAOLABA 大之前的提示,這一方面還要多琢磨琢磨.... 程式大家看看有錯請不吝指導.
//#include<STC15F204EA.h>
//#include<intrins.h>
/* 20140208 最簡單的pwm 溫度對應風扇轉速,實驗結果風扇最低電壓為6v 也就是應該要 50;50 的脈波比
因此設定20度以下風扇不轉,當超過20度風扇開始轉動輸出7v 然後溫度每增加1度時候佔空比增加2%
Fire=1 ON 吹風 需要接上10K 拉上電阻 提升轉動力
Fire=0 OFF 停止
*/
#include <reg52.h>
#include<intrins.h>
sfr ADC_CONTR = 0xBC;
sfr ADC_RES = 0xBD;
sfr ADC_RESL = 0xBE;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sfr P1ASF = 0x9D;
sbit Fire = P3^4;
unsigned char FON,FOFF,Tdif;
unsigned int code tempresist[]={27421,26200,25042,23942,22899,21908,20966,20071,19221,18411,17642,16909,16212,15548,14916,14313,13739,13192,12669,12171,11696,11242,10809,10395,10000,9622,9260,8915,8585,8269,7966,7677,7400,7134,6880 ,6636,6403,6179,5964,5758,5560,5371,5189,5114,4846,4685,4530,5381,4238,4100,3968,3841,3718,3600,3487,3378,3273,3171,3074,2980,2889,2802,2718,2637,2558,2483,2410,2340,2272,2206,2143,2082,2023,1966,1911,1858,1806,1756,1708,1662,1617,1573,1531,1490,1451,1412,1375,1339,1305,1271,1238,1207,1176,1146,1118,1090,1063,1036,1011,986 };
unsigned int L,M,N,Q,ADC_DATA;//作為adc 計算溫度使用
unsigned int TP0,P0n;//,TP1,TP2,TP3,P0n,P1n,P2n,P3n;
unsigned char Rtemp0,Rtemp1,Rtemp2,Rtemp3;//P1n ¤p???I?á1|ì
unsigned char Compare_tempres (unsigned int);
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayUs20x(unsigned char t)//delay 200us
{
while(--t)
{
DelayUs2x(49);
}
}
void DelayMs(unsigned char t)
{
while(t--)
{ //¤j-P?μ?o1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*******************************************************************
adc程式
*******************************************************************/
unsigned int Read (unsigned char CHA){
unsigned char AD_FIN=0; //
CHA &= 0x07;
ADC_CONTR = 0x60;
_nop_();
ADC_CONTR |= CHA;
_nop_();
ADC_CONTR |= 0x80;
DelayMs(1);
ADC_CONTR |= 0x08;
_nop_();
_nop_();
_nop_();
_nop_();
while (AD_FIN ==0){
AD_FIN = (ADC_CONTR & 0x10);
}
ADC_CONTR &= 0xE7;
ADC_DATA=ADC_RES*4+ADC_RESL;
return (ADC_DATA);
}
/******************************************************************
read an channel then get thermo-resister
******************************************************************/
/*
unsigned int transfer(unsigned char an){
float PP,Kp;
unsigned int Rt;
M=Read(an);//讀取 溫度的電壓AD Count
N=Read(4);//讀取2.5V參考電壓 AD Count
PP=(M*2.5/N)*1000;// 待測電壓COUNT=(溫度電壓COUNT/(2.5V電壓COUNT/2.5))*1000
Kp=10000/(5000/PP-1); //電阻10K 溫度25度
//目前溫度電阻換算= (10K+溫度電阻)/溫度電阻=溫度COUNT
Rt=Kp;
return Rt;//return thermo-resister value
}
*/
unsigned int transfer(unsigned char an){
float PP,Kp,qq;
unsigned int Rt;
M=Read(an);// tc read out volt
N=Read(6);//P1.5¤f2.5V°ò-??z‰í??a??T?]?H???^change form----4>>6 接vcc
//PP=(M*2.5/N)*1000;//read an temp convert to mVchange from----2.5>>5
qq=N/5;//-----------------------順序有差異喔
PP=M/qq*1000;//----------------順序有差異喔
Kp=10000/((5000/PP)-1); //float caculate
Rt=Kp;
return Rt;//return thermo-resister value
}
unsigned char Compare_tempres(unsigned int TR)
{
unsigned char cmp_cnt;
cmp_cnt =0;
while (TR<tempresist[cmp_cnt])
{
cmp_cnt++;
if (cmp_cnt>100)
break;
}
return cmp_cnt;
}
void Fireout(void)
{
// in par temp :Rtemp0
// out par :Fire
//act : under 20.C Fire=1 ,over 20.C 1.C=2% ,total cycle 1ms
//result: Fire from 500us off 700us on ~ 20 off 1180on 480 off 720on...
//10k resister pull up
Fire=0;
DelayUs20x(FOFF);
Fire=1;// drive npn
DelayUs20x(FON);
}
void main(void)
{
P1M0 = 0xff; //ad port 設定
P1M1 = 0x00; //P1.0
P1ASF=0xff; //all analog in put mode
while (1)
{
{
TP0= transfer(0);//read chanel 0 resister value
Rtemp0=Compare_tempres(TP0);//查表對應溫度值
P0n=((tempresist[Rtemp0-1]-TP0)*10)/(tempresist[Rtemp0-1]-tempresist[Rtemp0]);//溫度值小數點?
}
{
Tdif=Rtemp0-21;//溫度差距於20度
if (Rtemp0>20)// 高於20度才動作
{
if(Rtemp0>45)//高於45度就全開
Fire=1;
else
{
FON=70+(Tdif*2);//duty cycle ON
FOFF=50-(Tdif*2);//duty cycle OFF
Fireout();
}
}
else
Fire=0;//stop fan
}
}
}
|
|