
前言3 G2 T! ^4 [3 Z f 基于学习的目的,详细讲解关于标准外设库中的定时器的 17 个示例项目函数文件。本次介绍 TIM15_ComplementarySignals的示例。* |3 B+ Q, o4 X& ` 一、示例详解 基于硬件平台:STM32F100B-EVAL,MCU 的型号是 STM32F100VBT6。软件则是其标准外设库。 1、TIM15_ComplementarySignals 的寄存器配置& w) D9 w% K) H+ R. U" f2 z 软件配置,运行程序可以发现,系统时钟设置为 24MHz,定时器使用到的是 TIM15 ;7 L, K( e0 m: D; n" O ![]() 根据时钟树的图谱及其程序, 该示例选择的是内部时钟源作为定时器的时钟源;TIM15 的时钟源来自 APB2 的分频。7 }2 G3 n5 A3 }" E& L( l0 D. V ( f; C; j5 o( }. e ![]() ![]() ; G- ^" d- H+ N5 I5 e. \2 q5 ? AHB 时钟 (HCLK)在 RCC_CFGR 寄存器中的分频系数 HPRE 的值为 0,即 SYSCLK not divided,即/1,所以 HCLK 就是24MHz;- n$ z: \+ I" k! v2 j- M/ z APB2 的 prescaler 的系数是 PPRE2:0x0,HCLK not divided,即/1,APB2CLK 为 24MHz;由于 APB2 的 prescaler 系数部分频,即/1,所以倍频器不起作用,即为上图中的 TIMxCLK = 24Mhz。7 e4 q1 H' F- Z# Y- f- f 二、示例演练 + E `) ^) [$ E- ? ![]() 综合上述,本案例中,Timer 的时钟源选择的是 Internal clock,CK_PSC 的时钟频率其实就是时钟树图中的输出 TIMxCLK,然后 TIMxCLK 或 CK_PSC 经过预分频器,才是最终用于计数的时钟基本单位(clock input,输入时钟)。" A8 p/ t h( c K: |- K K; d 另外,( N. Y; U f( F) O) X6 ~* j ![]() 设置 PrescalerValue 的值为 0,不分频,即 TIMxCLK = 24Mhz,即 TIM15 counter clock at 24 MHz。' u' h3 N" v/ u, y8 f7 h5 [ 时基部分的设置为向上计数,周期 ARR65535,CCR1_Val = 32767;不重复计数;TIM_ClockDivision = 0,不分频。$ e" I+ P" W. i/ M ( x* e2 [; L7 |9 t8 ]8 N ![]() 因为计到 ARR 值后还要再计一次,才重新计到 0,所以整个宽度是(TIM15_Period +1),即 ARR+1;所以带入上述值后,占空比为 50%。/ Y1 E) n5 ~5 s ![]() 在上面的函数执行完成后,TIM_INT 的计数时钟等已经设置好了。 再简单的描述一下 Prescaler 和 ClockDivision 这两者区别:个人理解,prescalor 是预分频,用于输入捕获等采样时候的分频,是计数分频;而 ClockDivision 决定了时钟和滤波器采样时间之间的关系,只能取 1,2,4 这三个值。 接着配置各个通道的设置: ![]() (结合上面两个图片和极性的配置,可以得出 OCx 的电平的输出,这里不再多说。)( I* n! N2 F; N4 Q 配置的模式为 TIM_OCMode_PWM2 (值为 OC1M = 111);输出使能;低电平有效;最后 TIM_Cmd(TIM2, ENABLE);,使能PWM 输出;没有打开中断;% {, g- y) V* B, I2 ^8 c; v9 ? TIM15 counter clock at 24 MHz,计数到 32767 变化,50%占空比,所以更新率为 24000000/32767 = 732.4Hz,PWM 周期为732.4/2 = 366Hz,用示波器观测符合描述。如下图:(下图中并未使能 TIM_Break_Enable,未插入死区时间,仅仅是观察互补信号的波形,从下图可以看出,两个波形的周期相同,占空比之和为 100%,符合互补性号的描述)。 其中:! a& M. B" e @( U" _% ` 黄色信号代表的是 PA2,TIM15_CH1; 蓝色信号代表的是 PB15,TIM15_CH1N; 0 g9 C, Z& ~/ @) e+ t2 Y% q% c ![]() 接着讨论,下面两句话,对 PA2,PB15 的波形的差别的影响, ![]() 此处,TIM_OCIdleState 的端口是 PA2,空闲时是 Set 即为高电平, TIM_OCNIdleState 的端口是 PB15,空闲时是 Reset 即为低电平, 对于通道对应的端口位可以参考相关芯片的 datasheet 表格。 ![]() 5 _' ]8 n. z1 {/ C7 h3 a2 L 执行下面的程序, ![]() 打到如上断点后,示波器的波形,黄色的是 PA2,高电平,蓝色的是 PB15,低电平;也符合描述,用于指明空闲时的状态。/ [! E- G0 \- A- Y* ~7 j: R * o% B" D4 P2 y1 _ ![]() 接着,讨论下面这一段函数对于波形的影响,其实就是对 TIM15_BDTR 寄存器的定义设置。 ![]() 其中, TIM_OSSRState_Enable 和 TIM_OSSIState_Enable 分别是运行模式下“关闭状态”选择 (Off-state selection for Run mode)和空闲模式下“关闭状态”选择 (Off-state selection for Idle mode)。具体结合下图表,可以得出相应的端口状态。/ A8 f, I* x/ _$ S" Y & |9 Y, d. @) @( F! N ![]() TIM_AutomaticOutput_Enable,在该程序中,AOE = 1,而 MOE = 0,即 MOE 主输出使能 (Main output enable)在下一个更新事件被自动置’1’(如果刹车输入无效)。. ?3 L/ }8 l ]7 e5 Q/ y! \8 G ![]() ' x/ W7 H8 H, U) U! F 接着,查看刹车功能的设置,如下两句:* \1 r% p0 b' v2 l, G/ G ![]() ; F2 s% u9 t3 w 使能刹车功能,且刹车输入高电平有效,即当: TIM15_BKIN(PA9)引脚拉高时,刹车功能起作用,无信号输出 ; TIM15_BKIN(PA9)引脚拉低时,刹车功能不起作用,有信号输出 ; 所以在演练该示例时,需要将 PA9 跳线接到地以观察输出的互补信号。 最后,讨论死区时间的设置,TIM_DeadTime 的影响;其设置的公式如下:( h" _2 h0 T& F8 [2 }; L & V2 Q! P1 ^; e4 @0 S, t ![]() 在本示例中,TIM15 counter clock at 24 MHz,DTG 为 0x27,即 0010,0111,为 39,所以死区时间的计算公式是 :0 Y }. N# o+ S9 e' `/ N 5 N4 P1 x1 \9 l# r) p& z/ Z; w: f ![]() 所以,Tdts = 1/24Mhz,带入上式,DT = 39/24000000 = 0.00000163s = 1.63us ) C2 A* Z9 N) _: A; B' i ![]() 3 y$ N6 E' A0 c/ ], @- ~3 V 自己的计算与 Readme.txt 中的描述相符。 当 TIM_DeadTime = 0xFF;可以很明显的看出 DeadTime 在起作用,3 E4 s$ i' I. y3 t + R. U. {5 ]' Q5 c0 [4 \; `8 U 7 h! \8 c( G: T% D( f- I 那么 DeadTime 是只对 CH1 或 CH1N 起作用,还是对 CH1 以及 CH1N 都可作用呢?" P+ K U7 s$ O+ z+ _8 @ 对照上面的描述,这儿先简单概述下,4 b* l; ^1 `, [8 R2 x 未使用 DeadTime 时(黄色 CH1,蓝色 CH1N): ![]() ) L6 ~5 i; m: S" e7 h/ S- S. t; e 使用 DeadTime,且设为 0xFF 时(黄色 CH1,蓝色 CH1N): : b+ `$ N% W0 v8 O2 k6 R2 t& ] ![]() 2 ?5 v; v% O4 v 直观的看是对两者 CH1 和 CH1N 都起作用,对占空比有影响,不影响周期。$ i0 Y4 Y( x* B( L' ~ 下图讲解的很清楚:% B7 ? [* ?: B' u/ W9 k2 l 如果 OCx 和 OCxN 为高有效: 1/ OCx 输出信号与参考信号 OCxREF 相同,只是它的上升沿相对于参考信号的上升沿有一个延迟。 2/ OCxN 输出信号与参考信号 OCxREF 相反,只是它的上升沿相对于参考信号的下降沿有一个延迟。参考这两句话,可以得出下面的图形。+ `2 z- H$ h: |$ O" O! G( E7 e ' t) | @! s7 ^3 A" }8 q ![]() |