① 三線cpu風扇怎麼用單片機測速
除了紅、黑線,三線CPU風扇的另一根線是風扇轉速輸出信號線。這根線輸出的是一個周期不變(通常為40~50uS),脈沖寬度隨風扇轉速改變的信號,脈沖的幅度為2v左右。也就是說,信號的占空比隨轉速變化。
用單片機測量風扇轉速時,可以直接測量正脈沖的寬度(負脈沖寬度則與轉速成反向變化)。採用正跳沿開啟計數器、捕獲甚至查詢等都可以達到測量正脈沖寬度的目的,當然,你的晶振頻率要足夠高。
② 求51單片機風扇轉速監控程序 C語言
給你個我寫的基於89c52的單片機測頻率的程序,你參考下
#include<reg52.h>
#include<intrins.h>
#include<stdlib.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineLCD_dataP0
sbitLCD_RS=P2^0;
sbitLCD_RW=P2^1;
sbitLCD_EN=P2^2;
sbitLCD_PSB=P2^3;
bitflag=0;
uintnum1=0,num2=0,count=0;
voiddisplay();
voiddelayms(uintx)
{
uinti,j;
for(j=0;j<x;j++)
for(i=0;i<110;i++)
;
}
voidwrite_cmd(ucharcmd) //12864寫命令函數
{
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
P0=cmd;
delayms(5);
LCD_EN=1;
delayms(5);
LCD_EN=0;
}
voidwrite_dat(uchardat) //12864寫數據函數
{
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=dat;
delayms(5);
LCD_EN=1;
delayms(5);
LCD_EN=0;
}
voidlcd_pos(ucharX,ucharY) //12864寫位置函數
{
ucharpos;
if(X==0)
X=0x80;
elseif(X==1)
X=0x90;
elseif(X==2)
X=0x88;
elseif(X==3)
X=0x98;
pos=X+Y;
write_cmd(pos);
}
voidlcd_init() //12864初始化函數
{
LCD_PSB=1;
write_cmd(0x30);
delayms(5);
write_cmd(0x0c);
delayms(5);
write_cmd(0x01);
delayms(5);
}
voidTime2_Init(void) //T2定時器自動重裝初值定時1s
{
EA=1;
ET2=1;
TR2=1;
RCAP2L=(65535-46083)%256;
RCAP2H=(65535-46083)/256;
}
voiddisplay() //12864顯示函數
{
lcd_pos(0,0);
write_dat(num1/1000+'0');
write_dat(num1/100%10+'0');
write_dat(num1/10%10+'0');
write_dat(num1%10+'0');
lcd_pos(1,0);
write_dat(num2/1000+'0');
write_dat(num2/100%10+'0');
write_dat(num2/10%10+'0');
write_dat(num2%10+'0');
}
main()
{
lcd_init();
Time2_Init();
TMOD=0x55;
TR0=1;
TR1=1;
while(1)
{
TH0=0;
TL0=0;
TH1=0;
TL1=0;
flag=0;
while(!flag);
num1=TH0<<8|TL0; //num1為T0在1s內統計的下降沿次數,輸入引腳為P3.4
num2=TH1<<8|TL1; //num2為T1在1s內統計的下降沿次數,輸入引腳為P3.5
display();
}
}
voidTime2(void)interrupt5 //T2定時器中斷1s
{
TF2=0;
count++;
if(count==20)
{
flag=1;
count=0;
}
}
③ 如何用單片機控制電路中電流或者電壓的大小,從而控制電風扇的轉速
如果用單片機控制電動機轉速的話,你需要一個三極體和一個場效應管或者找一個IRF3205這樣的器件,然後找一個合適的驅動控制電路,這種電路很好找,利用PWM波來驅動,然後AD采樣電路采樣,你要恆壓控制還是橫流控制,最省事的辦法是用BUCK電路集成晶元,利用反饋端的反饋,如果你反饋的是電壓信號,就可以實現恆壓控制,如果反饋的是電流信號,就可以實現橫流控制,風扇轉速控制我做過,有問題留言吧!溫度感測器如果你用ds18B20的話,那個程序就相當的好找,網上一大堆;
④ 求文檔: 單片機怎樣控制風扇電機轉速
你要求單片機控制什麼樣的風扇轉速還是按照什麼樣的要求控制轉速,你說的很模糊,請說的詳細一點。
要是按照溫度來模糊控制就加個溫控開關,溫度達到多少就啟動風扇 高於多少就加大檔位,低於多少就停止轉動,
要是想精確控制就在風扇電機後面加一個旋轉編碼器,並且用直流電機晶閘管控制電路電源來控制電機的轉速,或者是用變頻器控制電機的轉速。
不知你想要多麼高精度的控制。
請說詳細了,我可以告訴你。
祝你好運!
⑤ 怎樣實現51單片機根據溫度動態控制風扇轉速,請高手幫幫忙!
給您思路:第一,你需要使用溫控元件測溫,比如DS18B20溫度感測器。
第二:你所需要使用的控制晶元可以選擇單片機,比如STC89C55(帶掉電參數保存功能)。
第三:使用數碼管或者LCD1602顯示您所檢測的溫度或者顯示您所需要設置的溫度范圍。
第四:按鍵,根據你所需要的溫度范圍,根據按鍵來設置參數范圍。
第五:使用定時器1或者2輸出PWM波,控制可控硅(BTA06等),根據您的電流大小吧。
第七:在單片機里處理您的各類控制。大概就是如此吧。
⑥ 用單片機控制風扇的轉速希望提供具體電路,我是新手希望大家多多幫助!!!
直流電機調速的技術是很常見的。。
不過當然不是用電阻,那樣會有巨大的損耗。
一般直流電機調速都採用PWM(即脈寬調制)技術。
即,首先在電源和電機之間串聯一個開關電子器件(比如mosfet管、達林頓管),這種器件可以以極高的速度控制電路通斷。然後,我利用模擬電路或者數字電路(現在多用單片機)來控制這個開關管就能控制電機的電功率。比如,我想讓電機工作電壓只有電源電壓的一半,我可以以1毫秒為周期,讓開關管通0.5毫秒,斷0.5毫秒,這樣快速的電壓波動在經過電機轉子電樞這一有慣性的元件後就被「抹平」了,而且平均下來電壓正好是電源的1/2,這就達到了控制電機輸出功率的目的。[1]
開關元件可以在淘寶上買到現成的模塊。其中最常用的是L298N做的電機控制板(樓上圖中上方的那個就是),有兩路雙向調速(用H橋實現)的輸出,單路最大電流2A,工作電壓是12V以下(記不清是12還是24,你查一下。。)。如果需要更大功率,可以找BTS7960做的模塊,容量是40A。。。
至於單片機,如果你有51可以用,學學定時器中斷和IO操作,然後網上51 PWM的資料很多。。當然arino更不錯(樓上圖中下方的那個就是,不過是山寨的,正版是藍色的,淘寶搜),除了AVR性能更好之外,IDE自帶的驅動函數也挺方便。我記得51是沒有硬體PWM埠的,而AVR有,在Arino IDE中直接調現成函數就能用。。。
參考資料:[1]來自我以前的原創回答
⑦ 單片機控制風扇調速 具體點最好有源碼就好
#include <iom16v.h>
#include <macros.h>
#define OVER_TEMPERATURE 0x01
#define LOW_LIGHT 0X02
#define HIGH_LIGHT 0X03
#define THIS_NODE 0x12
#define CENTRAL_SITE 0x18
#define LIGHT_NODE 0x11
#define OBJ 90
/*#define KP 15
#define KI 1
#define KD 20
#define P (KP + KI + KD)
#define I (KP + 2 * KD)
#define D KD*/
typedef unsigned char uchar;
typedef unsigned int uint;
uint KP = 5;
uchar dKP = 1;
uint KI = 1;
uchar dKI = 2;
uint KD = 3;
uchar dKD = 1;
uchar table[10] = {0xf3, 0x50, 0xcb, 0xd9, 0x78, 0xb9, 0xbb, 0xd0, 0xfb, 0xf9};
uchar node[7] = {0x00, 0x0d, 0x6f, 0x00, 0x0c, 0x08, 0x09};
uchar rcv_buf[4] = {0, 0, 0, 0};
uchar command = 0;
uchar uart_flag = 0;
uchar sec = 0;
uchar minute = 0;
uchar hour = 0;
uchar wakeup = 1;
uchar key_down[4] = {0, 0, 0, 0};
uchar key_up[4] = {0, 0, 0, 0};
uchar pre_key = 0;
uchar cur_key = 0;
uchar key_chg = 0;
uchar time_chg = 0;
uchar key_timer = 0;
uchar uart_isr = 0;
typedef struct _PID{
uint set_point;
uint B;
int ek[3];
int ek_flag[3];
uint uk;
}PID;
PID sPID;
int abs(int num)
{
return ((num>0)?(num):(-num));
}
int delta_PID(PID *pp, int next_point)//增量法
{
int error;
error = pp->set_point - next_point;
pp->ek[2] = pp->ek[1];
pp->ek[1] = pp->ek[0];
pp->ek[0] = error;
return (KP*pp->ek[0] - KI*pp->ek[1] + KD*pp->ek[2]);
}
void PIDproc(PID *pp, int next_point) //帶死區控制以及抗積分飽和的PID
{
uint tmp[3] = {0, 0, 0};
uint PosSum = 0;
uint NegSum = 0;
uchar gain = 1;
if(pp->set_point > next_point){
tmp[0] = pp->set_point - next_point;//ek0
if(tmp[0] > pp->B){
pp->ek[2] = pp->ek[1];
pp->ek[1] = pp->ek[0];
pp->ek[0] = tmp[0];
pp->ek_flag[2] = pp->ek_flag[1];
pp->ek_flag[1] = pp->ek_flag[0];
pp->ek_flag[0] = 0; //當前EK為正數
tmp[0] = KP * pp->ek[0] / dKP + KI * pp->ek[0] / dKI + KD * pp->ek[0] / dKD; // KP*EK0
tmp[1] = KP * pp->ek[1] / dKP + 2 * KD * pp->ek[1] / dKD; // KI*EK1
tmp[2] = KD * pp->ek[2] / dKD; // KD*EK2
}
}
else{ //反饋大於給定
tmp[0] = next_point - pp->set_point;//ek0
if(tmp[0] > pp->B){
//數值移位
pp->ek[2] = pp->ek[1];
pp->ek[1] = pp->ek[0];
pp->ek[0] = tmp[0];
//符號移位
pp->ek_flag[2] = pp->ek_flag[1];
pp->ek_flag[1] = pp->ek_flag[0];
pp->ek_flag[0] = 1; //當前EK為負數
tmp[0] = KP * pp->ek[0] / dKP + KI * pp->ek[0] / dKI + KD * pp->ek[0] / dKD; // KP*EK0
tmp[1] = KP * pp->ek[1] / dKP + 2 * KD * pp->ek[1] / dKD; // KI*EK1
tmp[2] = KD * pp->ek[2] / dKD; // KD*EK2
}
}
/*以下部分代碼是講所有的正數項疊加,負數項疊加*/
if(pp->ek_flag[0]==0){
PosSum += tmp[0]; //正數和
}
else{
NegSum += tmp[0]; //負數和
} // KP*EK0
if(pp->ek_flag[1]!=0){
PosSum += tmp[1]; //正數和
}
else{
NegSum += tmp[1]; //負數和
} // - kI * EK1
if(pp->ek_flag[2]==0){
PosSum += tmp[2]; //正數和
}
else{
NegSum += tmp[2]; //負數和
} // KD * EK2
PosSum += pp->uk; //
if(PosSum > NegSum){ // 是否控制量為正數
tmp[0] = PosSum - NegSum;
tmp[0] *= gain;
if( tmp[0] < (uint)65000){ //小於限幅值則為計算值輸出
pp->uk = tmp[0];
}
else{
pp->uk = (uint)65000; //否則為限幅值輸出
}
}
else{ //控制量輸出為負數,則輸出0
pp->uk = 0;
}
}
void PID_init(PID* pp)
{
pp->set_point = OBJ;
pp->B = 0;
pp->ek[0] = 0;
pp->ek[1] = 0;
pp->ek[2] = 0;
pp->ek_flag[0] = 0;
pp->ek_flag[1] = 0;
pp->ek_flag[2] = 0;
pp->uk = 0;
}
void delay(int n)
{
int i = 0, j = 0;
for(i = 0; i < n; i++)
for(j = 0; j < 1000; j++);
}
void disp(int a)
{
uchar flag = 0;
PORTC = 0X01;
PORTB = table[a / 1000];
delay(3);
PORTB = 0X00;
PORTC = 0X02;
PORTB = table[a / 100 % 10];
delay(3);
PORTB = 0X00;
PORTC = 0X04;
PORTB = table[a / 10 % 10];
delay(3);
PORTB = 0X00;
PORTC = 0X08;
PORTB = table[a % 10];
delay(3);
PORTB = 0X00;
}
void delay_on(int n, uchar cur_val)
{
int i = 0, j = 0;
for(i = 0; i < n; i++)
for(j = 0; j < 30; j++)
disp(cur_val);
}
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = 0x06;//BIT(URSEL) | 0x06;
UBRRL = 0x0b; //set baud rate lo 0x03:115.2k,0x17:19200,0x0b:38400
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
// 數據發送【發送5 到8 位數據位的幀】
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)));
UDR = data;
}
// 數據接收【以5 到8 個數據位的方式接收數 據幀】
unsigned char USART_Receive( void )
{
while (!(UCSRA & (1<<RXC)));
return UDR;
}
void USART_TranStr(uchar data[], uchar n)
{
uchar i = 0;
for(i = 0; i < n; i++)
{
USART_Transmit(data[i]);
}
}
#pragma interrupt_handler uart_rx_isr:iv_USART_RX
void uart_rx_isr(void)
{
uchar i;
for(i = 0; i < 4; i++)
{
rcv_buf[i] = USART_Receive();
}
uart_flag = 1;
}
void scankey(void)
{
uchar tmp = 0;
DDRD &= ~0X04;
DDRC = (DDRC & 0X0F) | 0XC0;
PORTD |= 0X04;
PORTC = (PORTC & 0X0F) | 0X70;
delay(2);
tmp = PINC;
if((~tmp & 0x30) != 0)
delay(2);
tmp = PINC;
if((~tmp) & (1 << 4)){
key_timer = 0;
cur_key = 2;//test
return;
}
if((~tmp) & (1 << 5)){
key_timer = 0;
cur_key = 1;//up
return;
}
PORTC = (PORTC & 0X0F) | 0Xb0;
delay(2);
tmp = PINC;
if((~tmp & 0x30) != 0)
delay(2);
tmp = PINC;
if((~tmp) & (1 << 4)){
key_timer = 0;
cur_key = 4;//switch
return;
}
if((~tmp) & (1 << 5)){
key_timer = 0;
cur_key = 3;//time
return;
}
cur_key = 0;
}
void decidekey(void)
{
if(cur_key==0 && pre_key != 0)
{
key_up[pre_key - 1] = 1;
key_chg = 1;
}
else if(cur_key!=0 && pre_key==0)
{
key_down[cur_key - 1] = 1;
key_chg = 1;
}
else
{
key_chg = 0;
}
pre_key = cur_key;
}
void port_init(void)
{
DDRB = 0xFF;
PORTB = 0X00;
DDRC |= 0X0F;
PORTC = 0X00;
DDRA |= 0X30;
PORTA &= ~0X30;
}
void sendto(uchar no, uchar data[], uchar n)
{
USART_TranStr(node, 7);
USART_Transmit(no);
USART_TranStr(data, n);
}
void zigbeeReset(void)
{
USART_TranStr("AT+RESET", 8);
}
void zigbeeSleep(uchar TH, uchar TL)
{
uchar sleep[] = {"AT+SLEEP="};
USART_TranStr(sleep, 9);
USART_Transmit(TH);
USART_Transmit(TL);
}
void setrelay(uchar op)
{
uchar setRelay[] = {"AT+SETRELAY="};
USART_TranStr(setRelay, 12);
USART_Transmit(op);
}
void timer1_init(void)
{
TCCR1A = 0xa2; //兩路PWM,匹配清零
TCCR1B = 0x19; //快速PWM模式,位數可調,預分頻1
ICR1 = 0xFFFF;
//計數上限值,此數為16位PWM,此值的多少決定PWM的位數,改變值可以改變時鍾的輸入頻率
//在1M時鍾下,OCR1A,OCR1B=1M/65536=15HZ。改為7FFF時,為30HZ,ICR1變小,OCR1A,B成比例變大
}
void main()
{
uchar data[] = {0x01};
uchar time[] = {0x03, 21, 14, 55};
uchar send_buf[] = {0x05, 0x01, 0x00, 0x00};
uchar oldcomm[] = {0x00};
uchar flag = 0;
uchar light_obj = 500;
int a = 0;
uint PID_out = 0;
uint pre_PID_out = 0;
int delta_PID_out = 0;
int PID_in = 0;
int disp_num = 0;
CLI();
PID_init(&sPID);
uart0_init();
timer1_init();
MCUCR = 0x00;
GICR = 0x00;
OCR1A = a;
//OCR1B=a; //匹配初值
DDRA |= 0X20;
PORTA = 0X00;
DDRD |= 0XF8;
PORTD &= ~0XF8;
port_init();
SEI();
delay(1000);
sendto(LIGHT_NODE, send_buf, 4);
while(1)
{
if(uart_flag == 1)
{
uart_flag = 0;
PID_in = 255 - rcv_buf[1];// * 4 - rcv_buf[2];
/*pre_PID_out = PID_out;
delta_PID_out = delta_PID(&sPID, PID_in);
PID_out += delta_PID_out;
OCR1A = PID_out;*/
PIDproc(&sPID, PID_in);
OCR1A = sPID.uk;
sendto(LIGHT_NODE, send_buf, 4);
}
scankey();
decidekey();
if(key_chg && key_up[0])
{
key_up[0] = 0;
sPID.set_point += 10;
sendto(LIGHT_NODE, send_buf, 4);
}
if(key_chg && key_up[1])
{
key_up[1] = 0;
sPID.set_point -= 10;
sendto(LIGHT_NODE, send_buf, 4);
}
if(key_chg && key_up[2])
{
key_up[2] = 0;
disp_num = 0;
}
if(key_chg && key_up[3])
{
key_up[3] = 0;
disp_num = 1;
}
(disp_num == 0)?disp(PID_in):disp(PID_out / 10);
}
}//這是PID調節光照的,你自己慢慢看看,道理差不多
⑧ 怎麼實現用單片機控制家用電風扇(單相交流電機)的轉速,有具體的電路圖可供參考嗎
家用風扇一般只有1,2,3,4,5檔速度如果要無級變速例如要求速度為0到2000圈每分,那麼就復雜了,錢多的話買個單相變頻器即可,自己設計的話…………難度大首先要把交流電變為直流電就很簡單用用個二極體即可,然後要調節直流後的電壓,整流後的電壓為200到300伏如果轉速降低那麼整流後的電壓也要降低,否則會燒壞風扇,解決了調節電壓後就可以逆變了把直流電變為交流電,這要脈沖發生器,可以說用單片機控制最合適了,也是因為電路這個原因所以常用的家用風扇都是多級調速而不是無級變速的
⑨ 怎麼實現用單片機控制家用電風扇的轉速
家用電風扇是單相電機,使用at89C2051之類的單片機,外加過零檢測電路,再外加雙向可控硅,由單片機驅動三極體,三極體驅動可控硅,就可達到調速目的。
基本原理,類似於調光燈電路,過零檢測電路檢測交流電過零時間,然後控制可控硅導通時間,可控硅導通點越接近過零點,風扇轉速越快。
⑩ 請問下,怎麼用單片機控制電風扇的轉速,能給些大體思路,和給些資料嗎我是大一的很多都不懂,謝謝了
你用步進電機吧,速度和你的控制速度成正相關,對於大一的學生而言,PID加轉速感測器難度大了點;你可以直接搜索步進電機;這樣簡單很多,如果你嫌轉矩太小的話,可以加入齒輪組,也就是變速箱。這樣就容易實現多了