直流电机电极正接正转,反接反转
驱动方式:大功率器件直接驱动
仍然是用三极管做开关,电源驱动电机,二极管是为了防止电感释放能量时产生过高的电流
实际中可以把电机一级接到VCC,一级通过J47接到OUT口上
PWM 调整脉冲的宽度来等效的获取需要的模拟参量(需在具有惯性的系统中)
(类似波的合成?这算啥,数字信号模拟模拟信号吗)
![](https://img-blog.csdnimg.cn/direct/c5e6916d4f5a4b22adbd46d828b10e29.png)
PWM重要参数:频率 = 1 / Ts, 占空比 = To / Ts, 精度=占空比变化步距
这样就可以想出一个电机调速的方案,不断输出一个脉冲信号,控制脉冲信号的周期来控制电机速度
照这个原理可以来试试LED呼吸灯
先试试把LED亮灭不断循环
#include <REGX52.H>
sbit LED = P2^0;
void main()
{
while(1)
{
LED = 0;
LED = 1;
}
}
会发现LED亮度变低
再延长灭的时间
会发现更暗了
#include <REGX52.H>
sbit LED = P2^0;
void main()
{
while(1)
{
LED = 0;
LED = 1;
LED = 1;
LED = 1;
LED = 1;
LED = 1;
LED = 1;
LED = 1;
LED = 1;
}
}
根据这个原理我们可以通过延时来粗略控制LED亮度
#include <REGX52.H>
sbit LED = P2^0;
void Delay(unsigned int t)
{
while(t--);
}
void main()
{
while(1)
{
LED = 0;
Delay(5);
LED = 1;
Delay(95);
}
}
再按照:控制LED逐渐变亮,第一重循环控制LED亮度,第二重循环减缓变化速度→控制LED逐渐变暗→回到第一步 的逻辑实现整体LED呼吸灯功能
#include <REGX52.H>
sbit LED=P2^0;
void Delay(unsigned int 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; //LED亮
Delay(Time); //延时Time
LED=1; //LED灭
Delay(100-Time); //延时100-Time
}
}
for(Time=100;Time>0;Time--) //改变亮灭时间,由亮到暗
{
for(i=0;i<20;i++) //计次延时
{
LED=0; //LED亮
Delay(Time); //延时Time
LED=1; //LED灭
Delay(100-Time); //延时100-Time
}
}
}
}
在LED上实践过了就可以上电机了
要产生PWM,我们可以用到定时器
利用定时器产生一个可控制的脉冲
先设置定时器为100微秒进一次中断,再拿下面这个程序测试一下这个想法可不可行
#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Timer0.h"
#include "Nixie.h"
unsigned char Counter,Compare;
sbit LED = P2^0;
void main()
{
Timer0Init();
Compare = 50;
while(1)
{
}
}
void Timer0_Routine() interrupt 1
{
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
Counter%=100;
if(Counter < Compare)
{
LED = 0;
}
else
{
LED = 1;
}
}
运行后可以观察到LED变暗
再根据这个原理就可以实现电机调速了
#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Timer0.h"
#include "Nixie.h"
unsigned char Counter,Compare;
unsigned char KeyNum,Speed;
sbit Motor = P1^0;
void main()
{
Timer0Init();
Compare = 5;
while(1)
{
KeyNum = Key();
if(KeyNum == 1)
{
Speed++;
Speed%=4;
if(Speed==0){Compare=0;} //设置比较值,改变PWM占空比
if(Speed==1){Compare=50;}
if(Speed==2){Compare=75;}
if(Speed==3){Compare=100;}
}
Nixie(1,Speed);
}
}
void Timer0_Routine() interrupt 1
{
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
Counter%=100;
if(Counter < Compare)
{
Motor = 1;
}
else
{
Motor = 0;
}
}