通用定时器概述
定时器分类表如下图所示
通用 TIMx 定时器具有以下特性:
● 16 位(TIM3 和 TIM4)或 32 位(TIM2 和 TIM5) 递增、递减和递增/递减自动重载计 数器。
● 16 位可编程预分频器,用于对计数器时钟频率进行分频 (即运行时修改),分频系数介 于 1 到 65536 之间。
● 多达 4 个独立通道,可用于:
— 输入捕获
— 输出比较
— PWM 生成(边沿和中心对齐模式)
— 单脉冲模式输出
● 使用外部信号控制定时器且可实现多个定时器互连的同步电路。
● 发生如下事件时生成中断/DMA 请求:
— 更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)
— 触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
— 输入捕获 — 输出比较 ● 支持定位用增量(正交)编码器和霍尔传感器电路
● 外部时钟触发输入或逐周期电流管理
定时器时钟来源
通用定时器时钟可以选择下面四类时钟源之一:
1)内部时钟(CK_INT)
2)外部时钟模式 1:外部输入引脚(TIx),x=1,2(即只能来自于通道 1 或者通道 2)
注:外部时钟模 式 1 下,时钟源信号只能从 CH1 或者 CH2 输入到定时器,
3)外部时钟模式 2:外部触发输入(ETR)
4)内部触发输入(ITRx):使用一个定时器作为另一定时器的预分频器
时基单元
计数器寄存器(TIMx_CNT)、
预分频器寄存器(TIMx_PSC)、
自动重载寄存器 (TIMx_ARR)。
预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 (UEV) 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。
时基单元的控制位
TIMx_CR1的CEN(Counter Enable) 位是能计数器。
TIMx_EGR的UG(Update Generation) 用软件方式产生一次事件更新,使得定时器复位。
计数器模式
- 递增计数模式
在递增计数模式下,计数器从 0 计数到自动重载值(TIMx_ARR 寄存器的内容),然后重新 从 0 开始计数并生成计数器上溢事件。
- 递减计数模式
在递减计数模式下,计数器从自动重载值(TIMx_ARR 寄存器的内容)开始递减计数到 0, 然后重新从自动重载值开始计数并生成计数器下溢事件。
- 中心对齐模式(递增/递减计数)
在中心对齐模式下,计数器从 0 开始计数到自动重载值(TIMx_ARR 寄存器的内容)— 1, 生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从 0 开始重新计数。
捕获/比较通道
每个捕获/比较通道均围绕一个捕获/比较寄存器(包括一个影子寄存器)、一个捕获输入阶段(数字滤波、多路复用和预分频器)和一个输出阶段(比较器和输出控制)构建而成。通道输入阶段、比较阶段和输出阶段组成。
输入阶段对相应的 TIx 输入进行采样,生成一个滤波后的信号 TIxF。然后,带有极性选择功能的边沿检测器生成一个信号 (TIxFPx),该信号可用作从模式控制器的触发输入,也可用作捕获命令。该信号先进行预分频 (ICxPS),而后再进入捕获寄存器。
输出阶段生成一个中间波形作为基准:OCxRef(高电平有效)。链的末端决定最终输出信号的极性。
捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。始终可通过读写操作访问预装载寄存器。
在捕获模式下,捕获实际发生在影子寄存器中,然后将影子寄存器的内容复制到预装载寄存器中。
在比较模式下,预装载寄存器的内容将复制到影子寄存器中,然后将影子寄存器的内容与计 数器进行比较。
输入捕获模式
输入捕获通过检测输入通道方波信号跳变沿,并且将跳变是的计数器值锁存到CCR。
输入捕获测定脉冲周期的工作原理:
在一个上跳沿时,寄存器TIMx_SR中的捕获/比较标志位CCyIF置1,表示发生了捕获事件,并且产生对应中断。计数器的置自动锁存到CCR中,在程序中读出CCR的值ccr1,并且清除CCyIF的标志位。
在下一个上跳沿,TIMx_SR中的捕获/比较标志位CCyIF置1,表示发生了捕获事件,并且产生对应中断。在程序中读出CCR的值ccr2。假设,如果在上一次发生捕获以后,CCR的值没有及时被读出,CCyIF保持1,则捕获溢出标志位CCRyOF会被置1。
假设,上跳沿捕获发生在一个周期以内,方波周期则为ccr2-ccr1。
如果方波周期超过计数器周期,则需要将计数器的技术周期和UEV事件发生次数考虑进去。ARR*N-cc2+cc1。
PWM输入捕获模式
PWM输入捕获模式为输入捕获模式的一个特例。
将两个输入捕获信号通道IC1和IC2映射到同一个TI1输入上。
这两个捕获通道边沿有效,但是极性相反。
选择两个 TIxFP 信号之一作为触发输入,并将从模式控制器配置为复位模式。
同时使能两个输入捕获。
在第一个上跳沿,TIMx_CCR1锁存计数器的值,是的计数器复位,在下一个下降沿,TIMx_CC2出发捕获输入,锁存计数器的值,这就是PWM高电平宽度;在下一个上升沿,TIMx_CCR1锁存计数器的值,与之前的值相比较,即为PWM的频率。
定时器同步
两个或者多个定时器可以内部连接,实现定时器同步或者串联。某个工作与主模式的定时器,可对另一个配置为从模式的定时器的计数器执行复位、启动、停止操作或为其提供时钟。
输出比较模式
此功能用于控制输出波形,或指示已经过某一时间段。 当捕获/比较寄存器与计数器(CNT)之间相匹配时,输出比较功能:
● 将为相应的输出引脚分配一个可编程值,该值由输出比较模式(TIMx_CCMRx 寄存器 中的 OCxM 位)和输出极性(TIMx_CCER 寄存器中的 CCxP 位)定义。匹配时,输出引脚既可保持其电平 (OCXM=000),也可设置为有效电平 (OCXM=001)、无效电平 (OCXM=010) 或进行翻转 (OCxM=011)。
● 将中断状态寄存器中的标志置 1(TIMx_SR 寄存器中的 CCxIF 位)。
● 如果相应中断使能位(TIMx_DIER 寄存器中的 CCXIE 位)置 1,将生成中断。
● 如果相应 DMA 使能位(TIMx_DIER 寄存器的 CCxDE 位,TIMx_CR2 寄存器的 CCDS 位,用来选择 DMA 请求)置 1,将发送 DMA 请求。
使用 TIMx_CCMRx 寄存器中的 OCxPE 位,可将 TIMx_CCRx 寄存器配置为带或不带预装 载寄存器。
输出模式有:冻结(Frozen)保持电平
有效电平(active level)
无效电平 (inactive level)
翻转 (toggle)
PWM模式
脉冲宽度调制模式可以生成一个信号,该信号频率由 TIMx_ARR 寄存器值决定,其占空比则 由 TIMx_CCRx 寄存器值决定。通过向 TIMx_CCMRx 寄存器中的 OCxM 位写入 110(PWM 模式 1)或 111(PWM 模式 2),可以独立选择各通道(每个 OCx 输出对应一个 PWM)的 PWM 模式。必须通过将 TIMx_CCMRx 寄存器中的 OCxPE 位置 1 使能相应预装载寄存器,最后通过将 TIMx_CR1 寄存器中的 ARPE 位置 1 使能自动重载预装载寄存器。由于只有在发生更新事件时预装载寄存器才会传送到影子寄存器,因此启动计数器之前,必须通过将 TIMx_EGR 寄存器中的 UG 位置 1 来初始化所有寄存器。OCx 极性可使用 TIMx_CCER 寄存器的 CCxP 位来编程。既可以设为高电平有效,也可以 设为低电平有效。OCx 输出通过将 TIMx_CCER 寄存器中的 CCxE 位置 1 来使能。有关详 细信息,请参见 TIMx_CCERx 寄存器说明。.
在 PWM 模式(1 或 2)下,TIMx_CNT 始终与 TIMx_CCRx 进行比较,以确定是TIMx_CCRx>TIMx_CNT 还是TIMx_CCRx≤TIMx_CNT。
在计数值达到ARR时会产生UEV事件。TIMx_CCRx≤TIMx_CNT可以产生CC(捕获比较)事件
根据 TIMx_CR1 寄存器中的 CMS 位状态,定时器能够产生边沿对齐模式或中心对齐模式的 PWM 信号。
例:PWM输出模式
实现目标:使用定时器TIM2输出可变脉冲宽度的PWM脉冲,将PWM信号从PA0引脚输出,将PA0引脚与LED引脚连接,使得LED灯呈现出不同的亮度。
- LED引脚配置成输入模式。
- 配置芯片时钟 略
Peripheral clocks 是挂载在总线上定时器意外的设备的时钟源;timer clocks 是为定时器提供的时钟源
- 对定时器时钟TIM2 进行配置。
时钟源,输出通道,预分频,计数周期(ARR)进行配置。Pulsa 在PWM模式1是高电平的宽度。
定时器TIM2 挂载在APB1 的时钟总线上,时钟频率位84MHz
根据配置的分频系数和装载值可求得,定时器时钟频率为:
修改PWM占空比:
在stm32f4xx_hal_tim.h文件中 有修改CCR的宏定义
__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__)
使用该宏定义 可以修改PWM的占空比
在使用PWM之前 需要启动定时器和开启的对应通道的PWM。
HAL_TIM_Base_Start(&htim2);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
PWM常用的HAL函数
HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim) |
PWM初始化,需要在完成定时器初始化配置完成后。 |
HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfig, uint32_t Channel) |
PWM通道配置 |
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) |
PWM启动 |
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) |
PWM停止 |
HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim) |
获取PWM状态 |
__HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) |
使能CCR预装载功能 |
__HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) |
禁止CCR预装载功能 |
__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) |
设置CCR |
__weak void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) |
CNT=CCR时,产生的比较事件的回调函数 |
例:输出比较模式
输出比较模式与PWM模式类似,也可以生成PWM波形。
但是在PWM模式中,在递增模式下,CNT与CCR作比较,如果CNT小于CCR,输出高电平;若CNT大于CCR,输出低电平。并且在CNT达到ARR是,会溢出。
在比较模式下,CNT与CCR不断做比较,若CNT=CCR,会发生对应的设置的电平改变,并且发生时间。在这种情况下,可以在一个定时器情况下,生成不同频率的PWM信号。
- LED引脚配置成输入模式。
- 配置芯片时钟 略
- 输出比较模式设置:以定时器TIM2为例。
- 在主函数中启动定时器和OC生成。
HAL_TIM_Base_Start(&htim2);
HAL_TIM_OC_Start(&htim2, TIM_CHANNEL_1);
完成配置后,LED会根据设置时间发生信号翻转。
OC常用的HAL函数
HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim) |
|
HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim) |
|
HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) |
|
HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) |
|
HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim) |
|
__HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) |
使能CCR预装载功能 |
__HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) |
禁止CCR预装载功能 |
__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) |
设置CCR |
__weak void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) |
产生输出比较事件时的回调函数 |