赞
踩
TIM定时器
定时器(TIM)最基本的功能就是定时了,比如定时发送 USART 数据、定时采集 AD 数据等等。如果把定时器与 GPIO 结合起来使用的话可以实现非常丰富的功能,可以测量输入信号的脉冲宽度,可以生产输出波形。定时器生产 PWM 控制电机或者驱动电桥桥臂等是非常有必要深入了解的。
STM32F407 系列控制器有 2 个高级控制定时器、10 个通用定时器和 2 个基本定时器,所有定时器都是彼此独立的,不共享任何资源。它们的特性如下图所示:
基本定时器
基本定时器比高级控制定时器和通用定时器功能少,结构简单,理解起来更容易,基本定时器主要有两个功能,第一就是定时功能,生成时基,第二就是专门用于驱动数模转换器(DAC)。
①时钟源
定时器要实现计数必须有个时钟源,基本定时器时钟只能来自内部时钟,我们可以通过 RCC 专用时钟配置寄存器(RCC_DCKCFGR)的 TIMPRE 位设置所有定时器的时钟频率,一般设置该位为默认值 0,即 TIMxCLK 为总线时钟的两倍,即基本定时器的内部时钟(CK_INT)频率为 84MHz。
基本定时器只能使用内部时钟,当 TIM6 和 TIM7 控制寄存器 1(TIMx_CR1)的 CEN 位 置 1 时,启动基本定时器,并且预分频器的时钟来源就是 CK_INT。
②控制器
定时器控制器控制实现定时器功能,控制定时器复位、使能、计数是其基础功能,基本定时器还可以用于 DAC 转换触发。
③时基单元
基本定时器TIM6和TIM7的时基是由一个 16 位递增计数器及其相关的自动重载寄存器组成,主要包括以下三个部分:
● 计数器寄存器 (TIMx_CNT)
● 预分频器寄存器 (TIMx_PSC)
● 自动重载寄存器 (TIMx_ARR)
预分频器 PSC,它有一个输入时钟 CK_PSC 和一个输出时钟CK_CNT。输入时钟 CK_PSC 来源于控制器部分,基本定时器只有内部时钟源所以CK_PSC 实际等于 CK_INT,即 84MHz。在不同应用场所,经常需要不同的定时频率,通过设置预分频器 PSC 的值可以非常方便得到不同的 CK_CNT,实际计算为:f[CK_CNT] 等于 f[CK_PSC] / (PSC[15:0]+1)。
在定时器使能时,计数器 TIMx_CNT 根据 CK_CNT 频率向上计数,即每来一个 CK_CNT 脉冲,TIMx_CNT 值就加 1。当 TIMx_CNT 值与 TIMx_ARR 的设定值相等时就自动生成事件并将 TIMx_CNT 清零,然后重新开始计数,如此重复以上过程。
为此可见,我们只要设置 CK_PSC 和 TIMx_ARR 这两个寄存器的值就可以控制事件生成的时间,而我们一般的应用程序就是在事件生成的回调函数中运行的。在 TIMx_CNT 递增至与 TIMx_ARR 值相等,叫做为定时器上溢。
定时周期计算
经过上面分析,我们知道定时事件生成时间主要由 TIMx_PSC 和 TIMx_ARR 两个寄存器值决定,这个也就是定时器的周期。比如我们需要一个 1s 周期的定时器,具体这两个寄存器值该如何设置内。假设,我们先设置 TIMx_ARR 寄存器值为 9999,即当 TIMx_CNT从 0 开始计算,刚好等于 9999 时生成事件,总共计数 10000 次,那么如果此时时钟源周期为 100us 即可得到刚好 1s 的定时周期。接下来问题就是设置 TIMx_PSC 寄存器值使得 CK_CNT 输出为 100us 周期(10000Hz)的时钟。预分频器的输入时钟 CK_PSC 为 84MHz,所以设置预分频器值为(8400-1)即可满足。
定时器初始化结构体
/** * @brief TIM Time base Configuration Structure definition */ typedef struct { uint32_t Prescaler; /*!< 预分频系数,TIMx_PSC 寄存器的值,范围0~65535,分频1~65536 */ uint32_t CounterMode; /*!< 计数模式 (向上计数、向下计数、向上向下计数)*/ uint32_t Period; /*!< 定时周期,实际是自动重装载寄存器的值 */ uint32_t ClockDivision; /*!< 时钟分频系数,定时器时钟 CK_INT 频率与数字滤波器采样时钟频率分频比 */ uint32_t RepetitionCounter; /*!< 重复计数器,属于高级控制寄存器专用寄存器位,控制输出 PWM 的个数。 */ uint32_t AutoReloadPreload; /*!< 自动重装载使能 */ } TIM_Base_InitTypeDef;
定时器基本功能函数
HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); //定时器基本功能初始化
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim); //开启定时器
HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim); //关闭定时器
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); //开启定时器和更新中断
HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim); //关闭定时器和更新中断
基本定时器实验
本次实验基于野火STM32F407-霸天虎V2开发板实现,使用基本定时器TIM6定时0.5秒,定时溢出后进入中断对LED_Green取反,形成绿灯闪烁的效果。硬件电路之前几篇文章已有说明,这里不再阐述。
打开Cube,在Timers中激活TIM6,设置分频系数8399,向上计数模式,自动重装载值4999,使能自动重装载,同时使能NVIC中断。TIM6时钟频率为84MHz,8400分频后为10KHz,即计数周期100us,计数值5000即0.5秒。
生成代码之后,在stm32f4xx_it.c
中对应位置添加以下代码:
/* USER CODE BEGIN TIM6_MspInit 1 */
HAL_TIM_Base_Start_IT(&htim6); //打开定时器
/* USER CODE END TIM6_MspInit 1 */
/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&htim6))
{
LED_Green_Toggle;
}
}
/* USER CODE END 1 */
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。