前言
这次来对PWM做一个总结
最近学习时,发现PWM控制在很多地方都会用到,比如使用PWM来控制电机的速度,使用PWM来生成想要的波形。
那么到底什么是PWM呢?
一、PWM
PWM即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效的获得所需要的模拟参量。
说白了就是通过控制高低电平的时间,来对输出的波形进行控制。
其中有几个重要的参数
- 频率:频率等于周期频率除以1
- 占空比:高电平在整个周期内所占的时间,即高电平和周期时间的比值
- 精度:占空比变化的步距
二、产生PWM的方法
下方为江科大ppt教程ppt里的图,就是通过定时器定时自增,设置一个比较值,然后通过判断计数器和比较值的大小,输出对应的高低电平 。
波形详解,就比如第一个周期内,小于比较值60的部分输出的是低电平,大于比较值60的部分输出高电平。两图的波形等效,PWM波形就这样产生了,控制不同的高低电平存在的时间,然后输出。
使用定时器产生一个恒定的周期
这里没有限制使用什么定时器,当使用多个定时器的时候,一定要注意不同定时器中断和外部中断的优先级,因为如果不同定时器的中断优先级不相同,就有可能一个优先级较高的定时器中断打破了当前定时器产生的中断。使当前中断失效。下方为中断优先级以及使用C语言编程使用到的中断号。 例程序 定时器0产生恒定周期:
#include <REGX52.H>
void Timer0Init()
{
TMOD&=0xF0;
TMOD|=0x01;
TL0 = 0xA4;
TH0 = 0xFF;
TF0=0;
TR0=1;
TF0=1;
ET0=1;
EA=1;
PT0=0;
}
中断服务子程序里设置比较值
和比较值相比较大小,可以自己设置究竟是大于比较值,输出高电平还是低电平,同时小于比较值也同理。
void Timer0_Rourine() interrupt 1
{
TL0 = 0xA4;
TH0 = 0xFF;
Counter++;
if(Counter>=100){Counter=0;}
if(Counter<Compare)
{
out1=1;
}
else
{
out=0;
}
三、实验
使用PWM对直流电机调速
通过按键控制直流电机的速度,使速度在数码管上显示,通过PWM调速 主程序 定时器0程序,和上方定时器0,程序相同
#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Timer0.h"
#include "NixieTube.h"
sbit motor=P1^0;
unsigned char Counter,Compare;
unsigned char KeyNum,Speed;
void main()
{
Timer0Init();
Compare=5;
while(1)
{
KeyNum=Key();
if(KeyNum==1)
{
Speed++;
if(Speed>3){Speed=0;}
if(Speed==0){Compare=0;}
if(Speed==1){Compare=50;}
if(Speed==2){Compare=75;}
if(Speed==3){Compare=100;}
}
NixieTube(8,Speed);
}
}
void Timer0_Rourine() interrupt 1
{
TL0 = 0xA4;
TH0 = 0xFF;
Counter++;
if(Counter>=100){Counter=0;}
if(Counter<Compare)
{
motor=1;
}
else
{
motor=0;
}
}
使用PWM对智能小车的电机调速
直接上源程序啦 在做智能小车的时候肯定大概率会用到,如果你使用PID算法算我没说。 留个小坑,过段时间会把做智能小车遇到问题如何解决的文章分享给大家。 集成了红外循迹、红外避障、红外遥控功能 这个模块可以直接使用
void LoadPWM(void)
{
if(pwm_left > PWM_HIGH_MAX) pwm_left = PWM_HIGH_MAX;
if(pwm_left < PWM_HIGH_MIN) pwm_left = PWM_HIGH_MIN;
if(pwm_right > PWM_HIGH_MAX) pwm_right = PWM_HIGH_MAX;
if(pwm_right < PWM_HIGH_MIN) pwm_right = PWM_HIGH_MIN;
if(pwm_val_left<=pwm_left) Left_moto_pwm = 1;
else Left_moto_pwm = 0;
if(pwm_val_left>=PWM_DUTY) pwm_val_left = 0;
if(pwm_val_right<=pwm_right) Right_moto_pwm = 1;
else Right_moto_pwm = 0;
if(pwm_val_right>=PWM_DUTY) pwm_val_right = 0;
}
void Timer1_Routine() interrupt 3
{
pwm_val_left++;
pwm_val_right++;
LoadPWM();
}
总结
说白了,PWM就是设置一个恒定的周期内,通过设置计时数和设置的比较值的大小,是在计时数比比较值小置高低电平,则要依据自己的需求来进行设置。
这个PWM起初还不知道是啥,看了江科大第一遍视频没懂,第二遍懂了一点点,后面查看了好几个资料,摸着摸着不知道怎么就明白了个大概。
初始接触是应为江科大的视频里,一步一步跟下来
再接触是自己制作的智能小车的速度一直慢不下来,所以使用PWM对小车的速度进行控制
加油加油!
希望本文对你有帮助。
最后行文仓促,还请谅解,欢迎指错。
|