有人想实现如下PWM输出波形,周期T=12us,两路输出波形特征一样,只是第2路【下图中的CHn】波形的输出比第1路【下图中的CHm】滞后T/2。另外,还要保证二者占空比在0~50%范围内可以同步调节。) ]/ r$ |" T; ~9 f
对于这种输出波形,如果使用2个定时器来做会相对方便点,通过定时器的主从模式来实现。现在客户希望使用1个定时器来完成,那如何实现呢? [" p- w$ g- F8 h/ F1 c 当然,用1个带多比较通道的定时器也是可以实现的。我们可以使用PWM输出模式来实现第1路,使用OC toggle模式来实现第2路。下面以STM32F334 Nucleo开发板来着手配置、编程、验证。, ~ ?- e+ [, R& S/ r4 O5 L2 N 这里不妨选用TIM3来实现该输出波形。TIM3的时钟源目前配置为64Mhz,不做预分频,使用向上计数模式。一个计数周期对应的ARR是 (12*64)-1,即767。TIM3的通道1输出对应于下图中第1路,TIM3的通道3输出对应于第2路.【图中的黄色斜箭头表示计数器计数变化趋势,从0到ARR,并周期性循环计数。】
因为TIM3通道1采用PWM模式来输出,设置好CCR1、ARR的值即可。通道3采用OC切换输出模式来实现。对于通道3,在一个周期内有两个翻转点,即上图中第2路上升沿的R点和下降沿的F点。结合本实例需求,不难得知,R点所对应的比较值【CCR3】为768/2,即384并保持不变。F点的比较值的大小决定其占空比。由于这里实际需求的占空比不超过50%,正常来讲,则F点可以设置的比较值最大不会超过ARR的值。6 ~2 w" ?$ U1 X! S' } & `" _5 p5 P( k# Q, l; K 我们可以借助TIM3 CH3的比较事件触发DMA,通过DMA来传输存储在内存中R点/F点所对应的比较值以更新CCR3寄存器内容。在R点发生比较事件时,更新F点的比较值,在F点发生比较事件时更新R点的比较值。刚才前面说过了,这里上升沿R点的比较值始终保持不变,即384,我们是通过改变F点的比较值来改变TIM3通道3的占空比。$ i; X! I7 {. W: _& O! B5 ]; J% R 0 n. g6 S. s( R7 `3 G 另外,我们在TIM3通道1的比较中断里修改CCR1的值和通道3在F点所对应的CCR3比较值,最终实现2路占空比0~50%灵活可调的输出。 大致原理就介绍到这里。 7 W) R; O1 S+ ]! _9 H$ D6 p* D 下面是有关STM32CubeMX进行初始配置到实现输出的全过程的简单描述。+ M0 A# ]9 K5 T! p6 o! y 8 j0 r' N% ]" o6 d$ b/ a 1、 关于定时器TIM3的基本时基参数配置如下:
' c. y# r1 d& N5 }* ~ 2、基于定时器事件的DMA传输配置如下:
有关NVIC的配置可以按需操作,其中DMA的传输中断CubeMx工具默认帮我们开启。这里开启了TIM3相关的NVIC配置。将来在TIM3的OC1比较中断里修改CCR1与通道3下降沿翻转点(即上文中的F点)所对应的比较值,即CCR3的值。. l: l p! f, v- ?! }, H9 D3 y5 ` 3、完成各项配置后,即可生成包含初始化配置代码的工程。 4、在新建的工程里,添加用户代码。代码基于STM32Cube库。) F' }0 ^9 a! G2 n7 Q+ B2 v% A 4.1 开启TIM3 CCR1的预装功能。 __HAL_TIM_ENABLE_OCxPRELOAD(&htim3, TIM_CHANNEL_1);2 x! }" c9 F$ {" [# L9 U7 J 4.2 关闭TIM3 CCR3的预装功能。% I0 K1 _, a1 i __HAL_TIM_DISABLE_OCxPRELOAD(&htim3, TIM_CHANNEL_3); 4.3使能TIM3 通道1的比较输出中断。 __HAL_TIM_ENABLE_IT(&htim3, TIM_IT_CC1); 4.4使能TIM3 通道1的比较输出功能。& F2 L) S( O/ h8 r- N3 ] TIM_CCxChannelCmd(TIM3, TIM_CHANNEL_1, TIM_CCx_ENABLE); 4.5使能TIM3 通道3的比较输出及DMA传输功能。 HAL_TIM_OC_Start_DMA(&htim3, TIM_CHANNEL_3,Data_Pwm, 2);/ S4 N, m( C& H( L6 e' r 其中,Data_Pwm是为DMA传输定义的一个内存数组名。 初始定义是:uint32_t Data_Pwm[]={584,384};. L& X' x3 m; ?5 \ ~0 t 4.6启动TIM3的计数器工作。, l3 D& M( f9 i; L5 w& } {: N __HAL_TIM_ENABLE(&htim3); 4.7 在TIM3的OC1比较中断里修改CCR1和通道3下降沿翻转点所对应的比较值。 具体代码放在中断里调用的回调函数。9 d7 }- _8 Y9 W* ~# H; Y
5、编译、运行,验证结果。% {; H! S2 M& ]! }# S 我这里借助MDK-IDE自带的模拟逻辑分析仪,可以看到预期的结果。两路波形保持固定相差,占空比在0~50%范围同步变化。4 p# j% E5 K9 ]9 S 下面是从动态输出过程中截取到的两幅图,供参考。【红色波形是通道1使用PWM模式实现的,绿色的是通道3使用比较切换模式实现的。】1 j- T$ X ~% K1 Q v' b) ~8 X
; ~, `: }4 H6 I5 I, V6 [0 H
小结1 Y- J' X( B; W 利用定时器的比较输出切换模式,结合DMA外设,可以灵活地输出各种自定义波形。另外,STM32常规定时器中的CCR寄存器跟ARR寄存器一样具备预装功能,什么时候需开启什么时候需要关闭,结合具体应用来正确配置。否则,在更新ARR/CCR寄存器内容时,可能输出一些我们不期望的脉冲出来,比方不时产生些类似于干扰的尖而窄的脉冲。 最后,希望通过上面示例能带给大家一些应用上的帮助或启示。3 C+ A5 b* U0 O: p D |
微信公众号
手机版