PWM發生子程序 由前面介紹可知,通過調節PWM脈沖的占空比就能夠調節電機的轉動速度,從而控制開關門的速度。由于AT89C2051單片機內部沒有PWM功能模塊,因此只能通過程序控制單片機的某個引腳輸出高低電平,從而模擬產生PWM脈沖。脈沖的高低電平時間由定時器T0控制。T0中斷服務程序如下: void Timer0 ( ) interrupt 1 { cyclet = ~cyclet; TR0 = 0; if(cyclet) { TH0 = 0XFC; TL0 = 0XE0; if(smode == 0) PWMPIN = 0; else PWMPIN = 1; } else { TH0 = 0XFF; TL0 = 0X28; if (smode == 0) PWMPIN = 1; else PWMPIN = 0; } TR0 = 1; } 設置好T0的各種方式并啟動T0運行,其后T0不斷溢出,產生中斷,在T0的中斷服務程序中,通過將P3.4引腳值取反并輸出,從而產生高低交替的電平信號。通過重新設置T0的計數初始值,從而產生不同時間的高低電平,由此可以調節 PWM脈沖的占空比。本設計中電機快轉時占空比為80%,慢轉時占空比為20%,因此T0的計數初始值0xFCE0、0xFFE8。 StartMotol子程序用于啟動電機,子程序根據電機轉速設置T0計數初始值并啟動T0運行。根據電機轉動方向,設置P1.3、P1.4引腳輸出相應電平。程序如下: void StartMotol (uchar direct, uchar speed) //direct 1:正轉 0:反轉 speed 1:快速 0:慢速 { smode = (speed == 0)?0:0xff TR0 = 0; TH0 = 0XFC; TL0 = 0XE0; TR0 = 1; if(direct) { motolconz = 0; motolconf = 1; } else { motolconz = 1; motolconf = 0; } } 開關門子程序 開門子程序用于控制自動門開門的整個過程。當有人靠近自動門或有物體被夾住時,該程序首先控制電機快速開門;當到達減速位置時,程序控制電機慢速開門;當到達停止位置時,程序控制電機停轉,并定時5秒。在定時過程中,程序不斷判斷是否有人靠近自動門,若有則重新定時。程序代碼如下: void OpenDoor () { uchar tcnt; if((gatesensor ==1)&&(comparator == 1)) return; StartMotol (1,1); while (sensorB2 ==0); //判斷是否減速 StartMotol (1,0); while(sensorB1 ==0); //判斷是否停止運動 StopMotol (); tcnt = 0; while(tcnt<101) { TR1 = 0; TH1 = 0X3C; TL1 = 0XB0; TF1 = 0; TR1 = 1; while(TF1 == 0); TF1 = 0; if(gatesensor ==1) tcnt = 0; else tcnt = + +; } flagclose = 1; } 關門子程序:
void CloseDoor() { if(flagclose == 0) return; flagclose = 0; StartMotol(0,1); while(sensorB3 == 1) //判斷是否減速 { if(gatesensor == 1) return; if(comparator == 0) return; } StartMotol(0,0); while(sensorB4 == 0) //判斷是否停止轉動 { if(gatesensor == 1) return; if(comparator == 0) return; } StopMotol(); } 測試主程序 該程序主要調用相關子程序,實現了自動門的開關門及防夾等功能,代碼如下: #include <REGX51.H> typedef unsigned char uchar; typedef unsigned int uint; sbit PWMPIN = P3^4; sbit motolconz = P1^3; sibt motolconf = P1^4; uchar smode,cyclet; sbit gatesensor = P3^2; sbit sensorB1 = P3^1; sbit sensorB2 = P1^5; sbit sensorB3 = P1^6; sbit sensorB4 = P3^0; sbit comparator = P3^6; bit flagcclose; void InTimer01() { TMOD = 0X11; ET0= 1; EA= 1; }
void main() { InTimer01(); while(1) { OpenDoor(); CloseDoor(); } }
|