本文将介绍通过stm32的定时器输出pwm,如果对定时器不太熟悉的同学可以看下之前的文章《stm32基础定时器详解》,关于定时器的基础功能不再详解。
01 pwm介绍
pwm定义:脉冲宽度调制(pulsewidthmodulation,pwm)简称脉宽调制。通俗讲,pwm是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。pwm信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(on),要么完全无(off)。电压或电流源是以一种通(on)或断(off)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用pwm进行编码。
占空比定义:占空比就是高电平所占整个周期的时间,如下图所示:
第一个pwm波,周期为10ms,高电平的时间为4ms,所以占空比为40%,同理第二个pwm波为60%,第三个为80%。
pwm的频率: pwm的频率的整个周期的倒数,所以说上图pwm的周期为1/0.01,也就是100hz。改变pwm的频率是通过改变整个的周期实现的。所以通过改变高低电平总共的时间、改变高电平占总周期的比例就可以实现任意频率、任意占空比的pwm波。
pwm的用途和优点:电机调速、功率调制、pid调节、通信等等,配置简单、抗干扰能力强,从处理器到被控系统信号都是数字形式的,无需进行数模转换。并且让信号保持为数字形式可将噪声影响降到最小,噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响,这是pwm用于通信的主要原因。
02 stm32的管脚复用
stm32没有专门的pwm引脚,所以使用io口的复用模式。首先确认pwm功能的输出管脚,使用定时器9。从下面的框图中得知,timer9只有两个输出通道,所以timer9只能输出两路pwm。
在stm32f207数据手册中的alternatefunction mapping图片中,timer9的两个通道分别可以复用为pa2,pa3,pe5和pe6。
03 stm32输出pwm原理
下图中的①部分,在《stm32基础定时器详解》讲解过了,关于影子寄存器,也在《stm32影子寄存器》中讲述,下文不再赘述了。本文将重点在②部分,捕获/对比通道讲解,其中stm32的pwm就是利用对比通道实现的。
pulse width modulation mode allows you to generate a signal with afrequency determined by the value of the timx_arr register and a dutycycle determined by the value of the timx_ccrx register。 节选自stm32f207 reference manual手册
脉冲宽度调制模式可以生成一个信号,该信号频率由timx_arr 寄存器值决定,其占空比则由timx_ccrx 寄存器值决定。
从下图可以看出,当ccr寄存器和cnt计数器数值一样时,会产生动作(改变通道对应的gpio电平)。由于cnt溢出时,重载值由timx_arr寄存器值决定的。所以说timx_arr寄存器值决定周期,而timx_ccrx寄存器值决定cnt溢出时,经过多久会产生动作(改变通道对应的gpio电平),也就是决定了占空比。
以向上计数为例,重载值为arr,比较值为crrx
上图可以看出:
0-t1段,定时器计数器timx_cnt值小于ccrx值,输出低电平。
t1-t2段,定时器计数器timx_cnt值大于ccrx值,输出高电平。
当timx_cnt值达到arr时,定时器溢出,重新向上计数...循环此过程至此一个pwm周期完成。
上图更加形象的说明了
信号频率由timx_arr 寄存器值决定。
占空比则由timx_ccrx 寄存器值决定。
stm32输出pwm的过程:
1、首先配置gpio,配置定时器,具体参考一下代码。定时器配置参考《stm32基础定时器详解》。
2、捕获/比较通道使能比较通道。
上图看到,①寄存器名字为:capture/compare1register。可以选择从②处输入捕获,也可以选择从从③中输出,也就是我们需要的pwm输出功能。选择捕获通道,还是选择比较通道,在框图中没有找到具体的说明,但在timx_ccmr1寄存器cc1s[1:0]控制位使能。
3、使能完输出,就要配置pwm输出了
①timx_ccmr1寄存器的oc1m[2:0]位,设置输出模式控制器
110:pwm模式1,111:pwm模式2。
②计数器值timx_cnt与通道1捕获比较寄存器ccr1进行比较,通过比较结果输出有效电平和无效电平。
oc1ref=0 无效电平,oc1ref=1无效电平。
③通过输出模式控制器产生的信号。timx_ccer寄存器的cc1p位,设置输入/捕获通道1输出极性。
0:高电平有效,1:低电平有效。
④timx_ccer:cc1e位控制输出使能电路,信号由此输出到对应引脚。
0:关闭,1:打开。
首先对pwm模式1和pwm模式2进行介绍:
01 模式1
在向上计数时,一旦timx_cnttimx_ccr1时通道1为无效电平(oc1ref=0),否则为有效电平(oc1ref=1)。
02 模式2
在向上计数时,一旦timx_cnttimx_ccr1时通道1为有效电平,否则为无效电平。
timx_cnt>timx_ccr1时通道1为有效电平,否则为无效电平。
pwm输出高低电平由timx_ccmr1:oc1m位和timx_ccer:cc1p位共同决定。
总结下来:
模式1:
cntccr为无效电平//(oc1ref =0)
模式2:
cntccr为有效电平//(oc1ref =1)
cc1p:
0:高电平有效
1:低电平有效
04 stm32输出pwm配置
分析了原理,那么下面就分析stm32生成pwm的过程。
1、首先要将gpio设置为复用输出
/* gpioe clock enable */rcc_ahb1periphclockcmd(rcc_ahb1periph_gpioe,enable); /* gpioe configuration: tim9 ch2(pe6)*/gpio_initstructure.gpio_pin = gpio_pin_5 |gpio_pin_6;gpio_initstructure.gpio_mode =gpio_mode_af;gpio_initstructure.gpio_speed =gpio_speed_100mhz;gpio_initstructure.gpio_otype =gpio_otype_pp;gpio_initstructure.gpio_pupd = gpio_pupd_up;gpio_init(gpioe, &gpio_initstructure); /*connect tim9 pins to af3 */ gpio_pinafconfig(gpioe,gpio_pinsource5, gpio_af_tim9);gpio_pinafconfig(gpioe,gpio_pinsource6, gpio_af_tim9);
2、配置定时器向上计数,配置定时器频率
/* tim9 clock enable */rcc_apb2periphclockcmd(rcc_apb2periph_tim9,enable); /* compute the prescaler value */prescalervalue= (uint16_t) ((systemcoreclock) / 2000000) - 1; /* timebase configuration */tim_timebasestructure.tim_period =1000-1;tim_timebasestructure.tim_prescaler =prescalervalue;tim_timebasestructure.tim_clockdivision =0;tim_timebasestructure.tim_countermode =tim_countermode_up; tim_timebaseinit(tim9,&tim_timebasestructure);3、配置pwm输出 上面分析过程较为麻烦,st提供了标准外设库,我们只需要配置tim_ocinittypedef结构体即可。
tim_ocinittypedef tim_ocinitstructure; /* pwm modeconfiguration: channel1 */tim_ocinitstructure.tim_ocmode =tim_ocmode_pwm1;tim_ocinitstructure.tim_outputstate =tim_outputstate_enable;tim_ocinitstructure.tim_pulse =100-1;tim_ocinitstructure.tim_ocpolarity =tim_ocpolarity_high; tim_oc1init(tim9,&tim_ocinitstructure);tim_oc1preloadconfig(tim9,tim_ocpreload_enable);
tim_ocinittypedef结构体解析
typedef struct{ uint16_t tim_ocmode; //pwm模式1或者模式2 uint16_t tim_outputstate; // 输出使能or失能 uint16_t tim_outputnstate; // pwm输出不需要 uint32_t tim_pulse; // 比较值 uint16_t tim_ocpolarity;// 比较输出极性 uint16_t tim_ocnpolarity; // pwm输出不需要 uint16_t tim_ocidlestate;// pwm输出不需要 uint16_t tim_ocnidlestate; // pwm输出不需要}tim_ocinittypedef;
其中tim_pulse可以在初始化时设置,设置完毕后,也可以通过以下接口再次更新。
void tim_setcompare1(tim_typedef* timx, uint32_t compare1)
4、使能定时器
tim_arrpreloadconfig(tim9, enable); /* tim9 enable counter*/tim_cmd(tim9, enable);
使用timer9输出pwm的波形。
原文标题:stm32 pwm输出
文章出处:【微信公众号:玩转单片机】欢迎添加关注!文章转载请注明出处。
Tipster揭示了Sammy考虑在非美国5G Galaxy S21产品线上使用的芯片
包装生鲜牛肉pH值的高光谱无损检测方法
VRLA电池及其应用
三星推出BESPOKE缤色铂格十字门冰箱,开启保鲜新时代
GaN MEMS/NEMS应变调控谐振器研究
如何通过STM32的定时器输出PWM?
科创板方邦股份董事刘西山介绍、履历信息
电源输入保护技术详解
防护织物合成血液穿透测试仪的用途以及原理的介绍
12家硬件厂商发布飞桨生态发行版 软硬一体协同发展
定华雷达知识讲堂:雷达物位计的天线到底是干什么的?
电竞手机抢占市场 华硕携手腾讯求翻身
日本氢能战略的考虑
三星Note 10的面世使得触控笔成为亮点
Zigbee无线通信模块的特点和应用场景
隐藏结构体成员的方法与问题
(TOSHIBA)东芝光耦:SOP16封装
回收宝宣布iPhone 12补贴价为4567元!
MicroLED离我们还有多远?问问三星和苹果
瑞萨电子推出业内首款25 Gbps直调激光二极管RV2X6376A系列,支持4.9G和5G LTE基站