51单片机-PWM(脉冲宽度调制)
一、PWM(脉冲宽度调制)
- PWM,即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,可用于电机控速,舵机控制角度等等领域
- 周期为Ts, 频率f = 1/Ts,占空比 = Ton/Ts(高电平时间占1个周期的比例)
- PWM本质上就是在固定周期里面,对高电平的占比进行调节,从而得到不一样的模拟量
二、直流电机
2.1 电机介绍
- 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,电极反接时,电机反转
- 除直流电机外,常见的电机还有步进电机、舵机、无刷电机(转速快)等等
由于电机的功率比较大,直接接在单片机的IO口上会损坏电路,所以需要驱动电路来驱动电机
- 大功率器件直接驱动电路:电机只能正转(电机正负极反接时,可以实现反转)
- H桥驱动:可以实现电机的正转和反转
2.2 电机转速调节代码
我们通过定时器和中断来模拟周期和电机的占空比,通过独立按键来控制电机转速的四个挡位,占空比为1时,电机转速最快,占空比为75%、50%、25%时,电机转速逐渐减少
下面是main.c
#include <REGX52.H>
#include "Delayms.h"
#include "Key.h"
#include "Nixie.h"
#include "Timer0.h"
sbit Motor = P1^0;
unsigned char Counter,Compare; //计数器/比较器
unsigned char KeyNum,Speed;
void main()
{
Timer0_Init();
// Compare = 5;
while(1)
{
KeyNum = Key();
if(KeyNum == 1)
{
Speed++;
Speed%=4;
if(Speed == 0){Compare = 0;} //占空比为0
if(Speed == 1){Compare = 50;} //占空比为50%
if(Speed == 2){Compare = 70;} //占空比为70%
if(Speed == 3){Compare = 100;} //占空比为100%
}
Nixie(1,Speed);
}
}
//定时器中断函数100us执行一次
void Timer0_Routine() interrupt 1
{
TL0 = 0xA4;
TH0 = 0xFF;//初值
Counter++;
Counter%=100; //Counter = 100 ,Counter = 0; 周期为100*100us = 10ms
if(Counter<Compare) //指定高电平
{
Motor = 1;
}
else
{
Motor = 0;
}
}
三、舵机
3.1 舵机介绍
- 舵机是一种位置(角度)伺服的驱动器,适合角度变化并可以保持的控制系统,或者需要固定速度旋转的控制系统
- 目前常见的舵机种类有SG90、MG90S等等,根据角度细分,有90°、180°和360°之分。180°舵机可以根据PWM波控制旋转的角度,而360°舵机无法控制角度,只能控制其转动方向和速度不停的旋转
- 180°舵机的波形周期都是20ms,高电平时间对应角度分别为:0.5ms – 0°;1.0ms – 45°;1.5ms – 90°;2.0ms – 135°;2.5ms – 180°;
如下图所示,上图为SG90(塑料)、下图为MG90S(金属)舵机的图片
从上图中可以看出,此两种舵机除了材质不同,其他均相同,并且都是引出了红、黄和棕三种颜色的线
舵机内部自带驱动电路,可以直接接入单片机IO口
- 红色线:VCC(3-7.2V,一般是5V)
- 棕色线:GND
- 黄色线:PWM管脚
3.2 按键控制舵机转动固定角度
通过定时器和按键来控制舵机PWM口的占空比,实现舵机的转动
#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
sbit MG90S = P1^0;
unsigned char mode; //角度参数
unsigned char count; //比较值
unsigned char KeyNum;
void main()
{
Timer0_Init();
while(1)
{
KeyNum = Key();
if(KeyNum) //判断键码值,旋转角度
{
if(KeyNum == 1)mode = 0; //0°--0.5ms
if(KeyNum == 2)mode = 1; //45°--1.0ms
if(KeyNum == 3)mode = 2; //90°--1.5ms
if(KeyNum == 4)mode = 3; //135°--2.0ms
}
}
}
//定时器中断函数 0.5ms执行一次
void Timer0_Routine() interrupt 1
{
TL0 = 0x33;
TH0 = 0xFE; //0.5ms
if(count <= mode) //占空比
{
MG90S = 1; //高电平
}
else
{
MG90S = 0;
}
count++;
if(count == 40) //20ms周期完成后,清零
{
count = 0;
}
}
上电后,舵机如果不在0°,那么会回到0°的位置,因为默认值mode =0,导致占空比为0。按键1:舵机转动0°;按键2:舵机转动45°;按键3:舵机转动90°;按键4:舵机转动135°