1.采用全控型的开关功率元件进行脉宽调制(PulseWidth Modulation,简称PWM)已成为直流电机新的调速方式。
2.本设计采用由单片机控制实现的脉冲计数法。
3.本设计在硬件电路上共分为5个部分,单片机部分、按键输入、PWM斩波电路、测速电路以及模拟负载
4.单片机接口电路
本设计采用的是STC的89C52单片机
工作电压范围为5.5V-3.4V
晶振选用石英晶振,频率为20MHz
采用的是12V直流通过7805三端稳压器稳压到5V,给单片机和显示部分供电。
在第9脚-RST,复位脚外,加了一个复位按键和复位电路,复位原理为:
第一次上电时,+5V通过给电容充电,于是此时电容相当于短路,+5V直接加到RST脚上,单片机自动复位。过了极短的时间,电容充电完毕,此时电容则相当于开路,于是RST脚被电阻R113拉为低,单片机开始正常工作。
当RESET键按下时,+5V通过按键加到RST脚上,单片机复位,RESET键弹起之后,RST脚重新被R113拉为低,单片机开始正常工作。
5.按键输入电路
6.PWM驱动电路
如图所示,R21为P1.1口的上拉电阻10k,R20为限流电阻。
当P1.1口为低时,8050的基极电平被拉低,此时8050截止,所以9012的基极为高,9012截止,电机两端没有电压。
当P1.1口为高时,8050基极电压也为高,于是8050导通, 8050的集电极电压为低,此时9012的基极也为低,9012导通,+12V加到电机两端,电机开始转动。
所以,当P1.1口为高时,电机两端电压也为高;P1.1口为低时,电机两端电压也为低。于是当P1.1口产生PWM信号输出时,电机两端会产生同样的PWM波形,从而达到调节电机转速的目的。
7.测速电路
R25=510 R22=10K R24=10K
8.软件编程 按键系统
其对应程序如下:
voidclear_shake()
{
if(nn ==0)
{n = 0;}
if(nn1 == 0)
{
nn = 1;
if(shake == 0&&n >= 100)//shake就是被按下的键
{
shake_1 = 1;
nn1 = 1;
nn = 0;
}
}
9.PWM
PWM调速子程序是放在定时器0中断中进行的,中断设置如下:
//------T0-----------T0用作斩波
ET0 = 1;//中断允许位
time0_set = 300;
time0_tmp = 65536-(time0_set)*fosc/12;//
TH0 = (time0_tmp/256);
TL0 = (time0_tmp%256);
TF0 = 0;//CLR TF0
TR0 =1;//SETB TR0
PT0 = 1; //高优先级
下面是PWM的中断子程序:
void time0_int(void) interrupt 1
{
TH0=(time0_tmp/256);
TL0=(time0_tmp%256);
if(cut== 1)
{
time0_tmp= 65536-time0_set*20/12;
cut= 0;
}
else
{
time0_tmp= 65536-(time0 - time0_set)*20/12;
cut= 1;
}
}
10.测速系统
//-------外部中断1--------用做测速
IT1= 1; //为跳沿触发方式,引脚INT1上的电平从高到低的负跳变有效。
IE1= 0; //中断请求标志
EX1= 0; //外部中断1允许位
PX1= 0; //为高优先级
//------T1-----------T1用做计数
TH1= 0;
TL1= 0;
TF1= 0;//中断请求位
TR1= 0;//计数器1关闭
ET1= 0; //禁止T1溢出中断
//--------------------------------
IE = 0xaa;//
TMOD = 0x91;//
//---------------------------
外部中断1中断服务子程序如下:
void out1_int(void) interrupt 2
{
IE1 = 0;
EX1 = 0;
TR1 = 0;
TH1_1 = TH1;
TL1_1 = TL1;
TH1 = 0;
TL1 = 0;
m = 1;
}
获取脉冲宽度值子函数如下:
void getwidth_1()
{
TH1 = 0;
TL1 = 0;
n = 0;
n1 = n;
while(INT1==1&&((n-n1)<30))//n为每1MS +2
{}
if(INT1==0)
TR1 = 1; //计数器1打开
else
goto out;
//IE1 = 0;//中断请求标志
EX1 = 1;//外部中断1启动
n = 0;
n1 = n;
while(m==0&&((n-n1)<30))
{}
if(m==0)//M=1,则已经进入out_int1中断,若等于0,则说明30MS延时已过
{
TH1_1= 0;
TL1_1= 0;
}
out:
IE1 = 0;//中断请求标志
m = 0;
EX1 = 0;//外部中断允许位
TR1 = 0;
width_1 = (TH1_1*256+TL1_1);//timepr=脉冲宽度 /μS
}
此外,为了稳定测得的转速值,在程序中加了一个取平均值的函数:
void getwidth()
{
int gw,gw1;
width = 0;
gw1 = 0;
for(gw=0;gw<6;gw++)
{
GG: getwidth_1();
if(width_1!= 0)
widthbuf[gw]= width_1;
else
gotoGG;
}
width= (widthbuf[0] + widthbuf[1] + widthbuf[2] + widthbuf[3] + widthbuf[4] +widthbuf[5])/6;
这段函数的意思就是,将测得的连续6个不为零的脉冲宽度取平均值,以消除偶然的不稳定因素,使转速显示更加稳定。
11.PID调节系统 即精确误差
void PI()
{
EK1 = EK;
EK = speed_set - speed;
EK2 = EK - EK1;
if(PIn == 0)
{
EK2 = 1000;
PIn++;
}
YK = KP*EK + KI*EK2;
|