一、PWM
1.1.PWM介绍
PWM 是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调制,简称脉宽调制。在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域。其中PWM有三个重要参数:
- 频率 = 1 / T(S)
- 占空比 = T(ON) / T(S)
- 精度 = 占空比变化步距
2.2.产生PWM方法
PWM 的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号,例如:设定一个计数器为100,比较值为60,当计数器<比较值,输出0;计数值>=比较值,输出1。
一开始的时候计数器小于60,PWM波形输出为0,随着计数器自增,大于等于比较值,PWM波形输出为1。调节比较值可以间接调节PWM的占空比。
二、使用PWM实现呼吸灯
由于51单片机没有硬件PWM,所以只能由程序来实现:
#include <REGX52.H>
sbit LED=P2^0;
void Delay(unsigned char t)
{
while(t--);
}
void main()
{
unsigned char Time,i;
while(1)
{
for(Time=0;Time<100;Time++)
{
for(i=0;i<20;i++) //由暗到亮
{
LED=0;
Delay(Time);
LED=1;
Delay(100-Time);
}
}
for(Time=0;Time<100;Time++) //由亮到暗
{
for(i=0;i<20;i++)
{
LED=1;
Delay(Time);
LED=0;
Delay(100-Time);
}
}
}
}
二、直流电机
2.1.直流电机的介绍
直流电机是指能将直流电能转换成机械能(直流电动机)或将机械能转换成直流电能(直流发电机)的旋转电机。它是能实现直流电能和机械能互相转换的电机。当它作电动机运行时是直流电动机,将电能转换为机械能;作发电机运行时是直流发电机,将机械能转换为电能。
直流电机的结构应由定子和转子两大部分组成。直流电机运行时静止不动的部分称为定子,定子的主要作用是产生磁场,由机座、主磁极、 换向极、 端盖、轴承和电刷装置等组成。运行时转动的部分称为转子,其主要作用是产生电磁转矩和感应电动势,是直流电机进行能量转换的枢纽,所以通常又称为电枢,由转轴、电枢铁心、电枢绕组、换向器和风扇等组成。直流电机没有正负之分,在两端加上直流电就能工作。需要知道直流电机的额定电压和额定功率,不能使之长时间超负荷运作。 在交换接线后,可以形成正反转。
2.2.硬件设计
2.2.1.引脚图
从上图中可以看出,该电路是集成的,芯片的输入通过单片机 P1_0 ~ P1_5 IO口提供,芯片的输出由 J47 端子引出。
2.2.2.驱动电路
51 单片机主要是用来控制而非驱动,如果直接使用芯片的GPIO 管脚去驱动大功率器件,要么将芯片烧坏,要么就是驱动不起来。所以要驱动大功率器件,比如电机。就必须搭建外部驱动电路。下面是两种常见的驱动方式:
- 大功率器件直接驱动,下图的三极管用作开关控制,D1二极管的作用是保护电路,防止电机停止的时候产生的感应电流击穿三极管。
- H桥驱动,Q1和Q4导通;或是Q2和Q3导通,这样驱动能够控制电流方向,从而控制电机的转动方向。
2.3.软件设计
使用定时器来使计时器定时自增,当计时器<比较值,输出为1;计时器>比较值,输出为0(这些都可以自己按需求设定)。
void Timer0() interrupt 1
{
unsigned char Counter,Compare=0;
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
Counter%=100; //这里的取余可以实现当Counter为100时自动为0,Counter可以取到这些值:0、1、2、~、99,100对100取余为0
if(Counter<Compare)
{
Motor=1; //转动
}
else
{
Motor=0; //停止
}
}
下面是完整的实现按键控制直流电机的转速,并把转动速度显示在LCD屏幕上的代码:
#include <REGX52.H>
#include "Time0.h"
#include "Delay.h"
#include "Nixie.h"
#include "Key.h"
sbit Motor=P1^0;
unsigned char Counter,Compare=0;
unsigned char Speed,KeyNum;
void main()
{
Timer0_Init();
while(1)
{
KeyNum=Key();
if(KeyNum==1)
{
Speed++;
Speed%=4; //这里也一样,Speed能取到的值有:0、1、2、3
if(Speed==0){Compare=0;}
if(Speed==1){Compare=10;}
if(Speed==2){Compare=50;}
if(Speed==3){Compare=100;}
}
Nixie(1,Speed);
}
}
void Timer0() interrupt 1
{
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
if(Counter>100)
{
Counter%=100;
}
if(Counter<Compare)
{
Motor=1;
}
else
{
Motor=0;
}
}