ZHOUNACHU

MCS-51学习小结之直流电机

0
阅读(1776)

电机其实也可以称为马达,虽然结构和驱动方式多达几十种,但是它的控制原理是大同小异的,只要掌握了简单的控制,复杂一点的就好说了。

直流电动机的工作原理如下图所示:
     
直流电机虽然控制简单,但是它的应用还是比较广泛的,例如磁盘驱动器、人造卫星等,都必须达到速度和定位的目标,因为电机的控制无非就是两个目的:速度控制和位置控制。我手里用的是普通的直流电机,如下图:
 
它的两个输出端无论哪个接正、负极都无所谓,区别只是顺时针转动还是逆时针转动罢了。我这次调试采用的仍然是非常经典的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); 
}