
前言 基于学习的目的,详细讲解关于标准外设库中的定时器的 17 个示例项目函数文件。本次介绍 TIM15_ComplementarySignals的示例。 一、示例详解 基于硬件平台:STM32F100B-EVAL,MCU 的型号是 STM32F100VBT6。软件则是其标准外设库。 1、TIM15_ComplementarySignals 的寄存器配置 软件配置,运行程序可以发现,系统时钟设置为 24MHz,定时器使用到的是 TIM15 ; ![]() 根据时钟树的图谱及其程序, 该示例选择的是内部时钟源作为定时器的时钟源;TIM15 的时钟源来自 APB2 的分频。 ![]() ![]() AHB 时钟 (HCLK)在 RCC_CFGR 寄存器中的分频系数 HPRE 的值为 0,即 SYSCLK not divided,即/1,所以 HCLK 就是24MHz; APB2 的 prescaler 的系数是 PPRE2:0x0,HCLK not divided,即/1,APB2CLK 为 24MHz;由于 APB2 的 prescaler 系数部分频,即/1,所以倍频器不起作用,即为上图中的 TIMxCLK = 24Mhz。 二、示例演练 ![]() 综合上述,本案例中,Timer 的时钟源选择的是 Internal clock,CK_PSC 的时钟频率其实就是时钟树图中的输出 TIMxCLK,然后 TIMxCLK 或 CK_PSC 经过预分频器,才是最终用于计数的时钟基本单位(clock input,输入时钟)。 另外, ![]() 设置 PrescalerValue 的值为 0,不分频,即 TIMxCLK = 24Mhz,即 TIM15 counter clock at 24 MHz。 时基部分的设置为向上计数,周期 ARR65535,CCR1_Val = 32767;不重复计数;TIM_ClockDivision = 0,不分频。 ![]() 因为计到 ARR 值后还要再计一次,才重新计到 0,所以整个宽度是(TIM15_Period +1),即 ARR+1;所以带入上述值后,占空比为 50%。 ![]() 在上面的函数执行完成后,TIM_INT 的计数时钟等已经设置好了。 再简单的描述一下 Prescaler 和 ClockDivision 这两者区别:个人理解,prescalor 是预分频,用于输入捕获等采样时候的分频,是计数分频;而 ClockDivision 决定了时钟和滤波器采样时间之间的关系,只能取 1,2,4 这三个值。 接着配置各个通道的设置: ![]() (结合上面两个图片和极性的配置,可以得出 OCx 的电平的输出,这里不再多说。) 配置的模式为 TIM_OCMode_PWM2 (值为 OC1M = 111);输出使能;低电平有效;最后 TIM_Cmd(TIM2, ENABLE);,使能PWM 输出;没有打开中断; TIM15 counter clock at 24 MHz,计数到 32767 变化,50%占空比,所以更新率为 24000000/32767 = 732.4Hz,PWM 周期为732.4/2 = 366Hz,用示波器观测符合描述。如下图:(下图中并未使能 TIM_Break_Enable,未插入死区时间,仅仅是观察互补信号的波形,从下图可以看出,两个波形的周期相同,占空比之和为 100%,符合互补性号的描述)。 其中: 黄色信号代表的是 PA2,TIM15_CH1; 蓝色信号代表的是 PB15,TIM15_CH1N; ![]() 接着讨论,下面两句话,对 PA2,PB15 的波形的差别的影响, ![]() 此处,TIM_OCIdleState 的端口是 PA2,空闲时是 Set 即为高电平, TIM_OCNIdleState 的端口是 PB15,空闲时是 Reset 即为低电平, 对于通道对应的端口位可以参考相关芯片的 datasheet 表格。 ![]() 执行下面的程序, ![]() 打到如上断点后,示波器的波形,黄色的是 PA2,高电平,蓝色的是 PB15,低电平;也符合描述,用于指明空闲时的状态。 ![]() 接着,讨论下面这一段函数对于波形的影响,其实就是对 TIM15_BDTR 寄存器的定义设置。 ![]() 其中, TIM_OSSRState_Enable 和 TIM_OSSIState_Enable 分别是运行模式下“关闭状态”选择 (Off-state selection for Run mode)和空闲模式下“关闭状态”选择 (Off-state selection for Idle mode)。具体结合下图表,可以得出相应的端口状态。 ![]() TIM_AutomaticOutput_Enable,在该程序中,AOE = 1,而 MOE = 0,即 MOE 主输出使能 (Main output enable)在下一个更新事件被自动置’1’(如果刹车输入无效)。 ![]() 接着,查看刹车功能的设置,如下两句: ![]() 使能刹车功能,且刹车输入高电平有效,即当: TIM15_BKIN(PA9)引脚拉高时,刹车功能起作用,无信号输出 ; TIM15_BKIN(PA9)引脚拉低时,刹车功能不起作用,有信号输出 ; 所以在演练该示例时,需要将 PA9 跳线接到地以观察输出的互补信号。 最后,讨论死区时间的设置,TIM_DeadTime 的影响;其设置的公式如下: ![]() 在本示例中,TIM15 counter clock at 24 MHz,DTG 为 0x27,即 0010,0111,为 39,所以死区时间的计算公式是 : ![]() 所以,Tdts = 1/24Mhz,带入上式,DT = 39/24000000 = 0.00000163s = 1.63us ![]() 自己的计算与 Readme.txt 中的描述相符。 当 TIM_DeadTime = 0xFF;可以很明显的看出 DeadTime 在起作用, 那么 DeadTime 是只对 CH1 或 CH1N 起作用,还是对 CH1 以及 CH1N 都可作用呢? 对照上面的描述,这儿先简单概述下, 未使用 DeadTime 时(黄色 CH1,蓝色 CH1N): ![]() 使用 DeadTime,且设为 0xFF 时(黄色 CH1,蓝色 CH1N): ![]() 直观的看是对两者 CH1 和 CH1N 都起作用,对占空比有影响,不影响周期。 下图讲解的很清楚: 如果 OCx 和 OCxN 为高有效: 1/ OCx 输出信号与参考信号 OCxREF 相同,只是它的上升沿相对于参考信号的上升沿有一个延迟。 2/ OCxN 输出信号与参考信号 OCxREF 相反,只是它的上升沿相对于参考信号的下降沿有一个延迟。参考这两句话,可以得出下面的图形。 ![]() |