直流电动机的工作原理如下图所示:
直流电机虽然控制简单,但是它的应用还是比较广泛的,例如磁盘驱动器、人造卫星等,都必须达到速度和定位的目标,因为电机的控制无非就是两个目的:速度控制和位置控制。我手里用的是普通的直流电机,如下图:
它的两个输出端无论哪个接正、负极都无所谓,区别只是顺时针转动还是逆时针转动罢了。我这次调试采用的仍然是非常经典的H桥驱动电路,因为它非常具有典型性,对于一般的应用场合是足够的了,先做简单的,再玩复杂的,嘿嘿。它顺时针、逆时针转动时的原理图如下:
下面给出它的驱动电路,
上面电路的具体原理我就不多说了,比较简单,只是需要说明电路中使用二极管的原因,它们是为了防止电流突然反向时,产生的电压突变会损坏BJT。还有就是如果该电机的控制要应用在大电流(大功率)的场合时,就需要把6个BJT换成大功率BJT才行。
在这次调试直流电机中,我用上位机(串口调试助手)通过RS232通讯方式控制直流电机的顺、逆时针转动和停止,调试结果很好,通讯很成功。这个过程中还遇到了有趣的事,嘿嘿。我刚开始写驱动程序时写了一条指令为:sbit B = P0^1; 我进行编译时,Keil软件一个劲地报错,我把程序上下反复看了几次,心里纳闷到底问题出在哪里呢?它的报错原因为:
我思考了几分钟,边逛了几分钟的网页,再回到程序上,一眼看到“redefinition”这个单词!心想这不是“重复定义”的意思吗?于是乎,我突然想到MCS-51中有一个通用寄存器B,这个SFR是专门为乘法和除法设置的寄存器,也是一个二进制8位寄存器。(幸好本人的英文水平也不是盖的,嘿嘿。)当即打开"reg52.h"软件自带的头文件一看究竟,果然!
里面有一个sfr B = 0xF0;说明B这个字符已经被头文件定义过了,不允许用户自己再定义。同时这里也说明了一个问题,sbit和sfr的定义至少是有相通之处的!以前从未听说过这个,不由得感叹:在实践中长见识啊!
下面把我调试正确后的程序搬上来:
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit BEEP=P3^6;
sbit shunshizhen=P0^0; //顺时针转动控制引脚
sbit nishizhen=P0^1; //逆时针转动控制引脚
//************************************************
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--); //大概1ms。
}
//************************************************
void beep() //蜂鸣器提示。
{
delay(1);
BEEP=0;
delay(100);
BEEP="1";
}
//************************************************
void send_back() //数据返回子程序
{
SBUF="P1";
while(!TI); //等待数据发送完毕
TI="0"; //将发送标志位清零
}
//************************************************
void UART() interrupt 4
{
if(RI==1) //接收到数据时该位自动置为1。
{
RI="0"; //将接收标志位清零,否则上位机会一直不停地发送数据
P1=SBUF;
send_back(); //把接收到的数据返回PC机
switch(P1)
{
case(0x01):BEEP=0;shunshizhen=1;nishizhen=0;break; //顺时针转动
case(0x02):BEEP=0;shunshizhen=0;nishizhen=1;break; //逆时针转动
case(0x03):BEEP=0;shunshizhen=0;nishizhen=0;break; //电机停止
}
}
}
//************************************************
void main()
{
TMOD="0x20"; //定时器1,工作方式2
TH1 =0xfd;
TL1 =0xfd; //给定时器1装初值,设定波特率为9600bps
PCON="0x00"; //波特率不进行加倍
SM0 =0;
SM1 =1; //串行工作方式1
REN =1; //允许接收数据
ES =1; //打开串口中断4
TR1 =1; //启动定时器1
EA =1; //打开总中断
while(1);
}