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(); } }
|