小麦大叔
认证:普通会员
所在专题目录 查看专题
新手零基础如何快速入门单片机
基于STM32的hello world点灯教程
STM32 使用st-link调试遇到写保护 Flash Timeout 问题的解决思路
天哪!原来PWM这么简单
小小舵机,大大玄机
UART协议快速扫盲(图文并茂+超详细)
作者动态 更多
新手学STM32的话,先学标准库还是HAL库?
10-18 15:09
一个超级实用的源码阅读小技巧
07-31 10:28
Sourcetail 一款代码编辑神器,让看源码如丝般顺滑
07-30 09:24
真正的机器人为什么都需要SLAM?
07-29 13:12
又踩坑了!这次败给CAN总线了
07-16 13:59

天哪!原来PWM这么简单

本文将带你了解PWM。我们将学习PWM的基本原理与分类,PWM如何实现,以及程序实现。如果觉得不错,欢迎关注、分享、收藏、点赞。希望能帮助到大家,如有错误敬请指出,谢谢!

目录

  • 基本原理
  • PWM是如何实现?
  • 分类
  • 程序实现
  • 总结

一、基本原理

PWM的全称是脉冲宽度调制Pulse-width modulation),是通过将有效的电信号分散成离散形式从而来降低电信号所传递的平均功率的一种方式。

所以根据面积等效法则,可以通过对改变脉冲的时间宽度,来等效的获得所需要合成的相应幅值频率的波形。

具体如下图所示:

由上图可知,脉冲宽度调制使用一个脉冲宽度会被调制的方波,并且波型的平均值会有所变化。

因为不支持自动解析latex公式,又不想重新敲公式,下面文字我直接复制为图片了;

占空比

图中存在三种占空比状态,25%50%75%占空比状态,不难发现,假设占空比为D,则满足:

                                   

其中是PWM的周期,通常和载波的周期相同;

二、PWM是如何实现?

PWM实现的原理是通过锯齿波/三角波(载波)所需要合成的波形(调制波)进行比较,然后确定PWM所需要输出的极性,通常是ON或者是OFF,因为一般都是作用到开关元器件上;如下图所示;

振荡器和比较器

振荡器输出的锯齿波和参考值 进行比较,然后就可以输出PWM波形了;

matlabsimulink中搭建了一下仿真,具体如下图所示;

simulink

最终输出波形如下:

50%占空比

这里简单说明一下:

  • 锯齿波(图中橙色波形)最大为10,然后我希望输出平均为5的波形(图1中红色的水平直线);
  • 那么通过比较,当锯齿波小于5时;PWM输出低电平,即为OFF
  • 当锯齿波大于5时,PWM输出高电平,即为ON

所以再换一个思路,如果我希望输出一个电压逐渐升高的波形呢,该如何设计呢?

其实很简单,只要把需要调制的波形设置为斜坡输出的波形就可以了,具体如下图所示;

占空比逐渐增大

可以看到,最终占空比逐渐从0%增大到100%

然后我们继续想,能不能调制出其他的波形,比如调制一个正弦波sin wave,那也就是我们常说的SPWM,其实是可以的,具体如下图所示;

SPWM

三、分类

参考STM32中PWM的配置,根据载波波形的形状,假设三角波最大值是10,那么它的变化过程可能存在以下两种情况:

  • 完整周期包括两个过程,先递增,再递减:增加增加减少减少,这种也叫中央对齐PWM;
  • 完整周期只有递增过程:增加增加

中央对齐PWM

脉冲波的中心将会被固定在时间窗格的中心,同时脉冲波的两边可以移动,使得波的宽度被延伸或压缩,具体如下图所示;

         中央对齐PWM

另一种类型的PWM脉冲波形如下图所示;

四、程序实现

现在的MCU大部分都自带硬件PWM发生器,即配置好相应的寄存器,就能直接产生PWM,下面的例子基于NUCLEO-F767ZI,通过cubemx配置了三路PWM输出,然后实现了呼吸灯的效果;

int main(void)
{

	HAL_Init();

	MX_GPIO_Init();
	MX_TIM4_Init();
	MX_TIM3_Init();
	MX_TIM12_Init();

	int32_t time_stamp = 0;
	int32_t time_stamp_old = 0;
	int32_t ccr_val = 0;
	uint8_t add_flag = 1;
	HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
	HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);	
	while (1)
	{
		time_stamp = HAL_GetTick();
		if(time_stamp - time_stamp_old > 5){
		time_stamp_old = time_stamp;
		if(add_flag){
			ccr_val+=25;
			if(ccr_val >= 0xFFFF){
			ccr_val = 0xFFFF;
			add_flag = 0;
		}
		}else{
			ccr_val-=25;
			if(ccr_val <= 0){
				add_flag = 1;
				ccr_val = 0;
			}
		}
		TIM4->CCR2 = ccr_val;
		TIM12->CCR1 = ccr_val;
		TIM3->CCR3 = ccr_val;
		}
	}
}

整体效果如下:

呼吸灯

通过示波器看其中的一路PWM输出的占空比也是随时间变化;

PWM变化情况

五、总结

本文简单介绍了PWM的原理,以及如何产生PWM,可以通过锯齿波作为载波和调制波经过比较强,产生相应的PWM输出波形,最后结合STM32实现了一个呼吸灯的简单程序。


声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
本篇所含全部资料,点击此处留下邮箱我会发给你
资料明细:NUCLEO-F767ZI的PWM呼吸灯测试程序
觉得内容不错的朋友,别忘了一键三连哦!
赞 2
收藏 9
关注 138
成为作者 赚取收益
全部留言
0/200
  • stevendo 2021-11-04 13:35
    老师,能不能发我一下资料,谢谢! 25****@****.com
    回复 4条回复
  • xjin1989 2021-06-09 11:10
    老师,能不能发我一下资料,谢谢! 84****@****.com
    回复 5条回复
  • 鱼鹰单片机 2021-01-14 17:06
    老师,能不能发我一下资料,谢谢! ya****@****.com
    回复 1条回复
  • VKN007 2020-12-17 18:56
    老师,能不能发我一下资料,谢谢! 93****@****.com
    回复 3条回复