
01、PWM介绍8 K+ d* U/ O6 J$ n$ ~ PWM定义:脉冲宽度调制(PulseWidthModulation,PWM)简称脉宽调制。通俗讲,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。; V5 U4 r6 A; N% Y1 L; X' ^ 0 ?, E5 v/ A2 ~) Z$ j% J 占空比定义:占空比就是高电平所占整个周期的时间,如下图所示:/ [. s6 E% O9 b5 {' K6 M, | 8 g" ?& z% q4 P- L ![]() , I5 P- P5 N% d; y$ H 第一个PWM波,周期为10ms,高电平的时间为4ms,所以占空比为40%,同理第二个PWM波为60%,第三个为80%。7 W! n" O6 S( ?+ Y$ | PWM的频率: PWM的频率的整个周期的倒数,所以说上图PWM的周期为1/0.01,也就是100HZ。改变PWM的频率是通过改变整个的周期实现的。所以通过改变高低电平总共的时间、改变高电平占总周期的比例就可以实现任意频率、任意占空比的PWM波。3 n1 T8 |' z$ r" q , O3 \+ P2 U9 P# A PWM的用途和优点:电机调速、功率调制、PID调节、通信等等,配置简单、抗干扰能力强,从处理器到被控系统信号都是数字形式的,无需进行数模转换。并且让信号保持为数字形式可将噪声影响降到最小,噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响,这是PWM用于通信的主要原因。0 {" a; n- f( M) m; W # u$ Q+ `% s' k, Y- I& T 02、STM32的管脚复用' y( U! s& n, j# @4 a, M STM32没有专门的PWM引脚,所以使用IO口的复用模式。首先确认PWM功能的输出管脚,使用定时器9。从下面的框图中得知,timer9只有两个输出通道,所以timer9只能输出两路PWM。 ![]() 在STM32F207数据手册中的Alternatefunction mapping图片中,timer9的两个通道分别可以复用为PA2,PA3,PE5和PE6。 8 i5 j; z1 y7 ^0 ^4 O9 s: J2 b ![]() 03、STM32输出PWM原理0 G1 D7 e, y! ]! g8 X# } 下图中的①部分,在《STM32基础定时器详解》讲解过了,关于影子寄存器,也在《STM32影子寄存器》中讲述,下文不再赘述了。本文将重点在②部分,捕获/对比通道讲解,其中STM32的PWM就是利用对比通道实现的。' @# K' P: z+ |1 \# y* J ![]() 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。, B$ ~3 q5 Y6 h* H. C) L " F! y X, h9 b; p 节选自STM32F207 Reference manual手册& r# n8 p: t+ D: P$ t4 |0 [ + e* j8 R1 x7 H) Z( g 脉冲宽度调制模式可以生成一个信号,该信号频率由TIMx_ARR 寄存器值决定,其占空比则由TIMx_CCRx 寄存器值决定。 ; \! f. A$ X) s* p. r+ n 从下图可以看出,当CCR寄存器和CNT计数器数值一样时,会产生动作(改变通道对应的GPIO电平)。由于CNT溢出时,重载值由TIMx_ARR寄存器值决定的。所以说TIMx_ARR寄存器值决定周期,而TIMx_CCRx寄存器值决定CNT溢出时,经过多久会产生动作(改变通道对应的GPIO电平),也就是决定了占空比。 ![]() 以向上计数为例,重载值为ARR,比较值为CRRx ![]() 上图可以看出:) j$ P L5 w3 { 1.0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平。( {8 e& @+ c0 B 2.t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平。 当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数...循环此过程至此一个PWM周期完成。 上图更加形象的说明了 6 Y! l) `" a; S 1.信号频率由 TIMx_ARR 寄存器值决定。# ?4 L' V) @3 P0 F) \ 2.占空比则由 TIMx_CCRx 寄存器值决定。8 l9 q" ~+ u3 q7 ?! v- N 0 r$ I4 _3 U [6 e* ~ STM32输出PWM的过程: 1、首先配置GPIO,配置定时器,具体参考一下代码。定时器配置参考《STM32基础定时器详解》。4 y9 b) t% K+ ^+ z" \1 q 2、捕获/比较通道使能比较通道。8 w, k/ p' r, y 5 ~6 N/ \: _- {1 |# a: i+ a ![]() 0 Y8 v; s, v# C. t 上图看到,①寄存器名字为:Capture/Compare1register。可以选择从②处输入捕获,也可以选择从从③中输出,也就是我们需要的PWM输出功能。选择捕获通道,还是选择比较通道,在框图中没有找到具体的说明,但在TIMx_CCMR1寄存器CC1S[1:0]控制位使能。 6 K7 _$ d2 U0 G7 L ![]() 2 |: q L# O$ M- g' G 3、使能完输出,就要配置PWM输出了; c( b9 V$ E# T; z) N [1 Q: {# n5 P! [: m( u" e ![]() ①TIMx_CCMR1寄存器的OC1M[2:0]位,设置输出模式控制器8 w; R8 f0 r. ?' @& e$ H* Z0 c |% k" a1 [& W$ O& j8 N 110:PWM模式1,111:PWM模式2。 1 N. h! r G2 w+ D6 S! h ②计数器值TIMx_CNT与通道1捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平。 / m5 Q" A( D. c6 z OC1REF=0 无效电平,OC1REF=1无效电平。! P6 `. {. ?1 \ 3 }: |/ {5 {% u: ~: Y/ y2 x4 g4 S ③通过输出模式控制器产生的信号。TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性。 9 }6 j2 F( @( F, B" i- y2 m7 `# _ 0:高电平有效,1:低电平有效。 ④TIMx_CCER:CC1E位控制输出使能电路,信号由此输出到对应引脚。 0:关闭,1:打开。8 r) z' ]: M! O8 X& [ 首先对PWM模式1和PWM模式2进行介绍: ( r2 w% a. S1 L5 `- ?8 h% f 模式18 _- s9 L0 `2 I1 a% ]8 q2 Y 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向上计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。 模式2. R, U0 k* Y6 j3 W5 b6 p, a 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。; C- c) k+ ~& H- v( d6 f / k! p, n! }3 g/ N: D' M8 t TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。 PWM输出高低电平由TIMx_CCMR1:OC1M位和TIMx_CCER:CC1P位共同决定。& X8 H# |7 Y. t i+ j ' z. u. Z+ g1 G 总结下来: 模式1:9 N& s; a0 Q) { " _. u: p- V' E% I2 o CNT<CCR为有效电平//(OC1REF =1)1 N) Q- n1 {. T a" j, L, I5 v7 \ - W' C% l- R) B CNT>CCR为无效电平//(OC1REF =0) 模式2:- t+ S) ~$ O' n" b7 @$ X CNT<CCR为无效电平//(OC1REF =0). l; C ?) F: @: b / ]) H+ {: y/ I& u4 J6 b CNT>CCR为有效电平//(OC1REF =1) CC1P: - T3 z2 E4 C! A$ }! f/ i9 I1 g J8 L 0:高电平有效 1:低电平有效 04、STM32输出PWM配置- D7 p) V. \* |+ f: p 分析了原理,那么下面就分析STM32生成PWM的过程。; A8 P& S: J2 x* |$ ? 1、首先要将GPIO设置为复用输出
2、配置定时器向上计数,配置定时器频率- f* P+ ~2 N9 s: v( n. K7 F 2 j; v) k1 Y, o, w x* A j
3、配置PWM输出 0 p C) z% X1 E+ l, } 上面分析过程较为麻烦,ST提供了标准外设库,我们只需要配置TIM_OCInitTypeDef结构体即可。
其中TIM_Pulse可以在初始化时设置,设置完毕后,也可以通过以下接口再次更新。 # a ~) r; n# O1 a
4、使能定时器 ; t, d7 N& e$ F/ P* t7 Y
使用timer9输出PWM的波形: z0 D' A7 [; o- O9 e; Q ![]() " X& q# J- e, M ; G& Q3 [7 W$ [+ E: C |
【2025·STM32峰会】GUI解决方案实训分享5-调通板载的NRF24L01 SPI接口并使用模块进行无线通信(发送和接收)
【2025·STM32峰会】GUI解决方案实训分享2-编译运行TouchGFX咖啡机例程(含桌面仿真)
实战经验 | Keil工程使用NEAI库的异常问题
STM32 ISP IQTune:真正零门槛的免费ISP调整软件
【经验分享】STM32 新建基于STM32F40x 固件库的MDK5 工程
意法半导体MCU双供应链策略,打消中国客户后顾之忧
【经验分享】基于STM32使用HAL库实现USB组合设备CDC+MSC
2024意法半导体工业峰会:赋能智能电源和智能工业,构筑可持续未来
ST推出灵活、面向未来的智能电表通信解决方案,助力能源转型
意法半导体 x Qu-Bit Electronix:推动新一轮的数字声音合成革命