【STM32】4_0 基础定时器

发布时间 2023-08-24 14:28:51作者: 山愈海

基础定时器

TIME6 和 TIME7 基本定时器

• 16位计数器(Counter):基础定时器内部有一个16位的自动增减计数器。计数器可以通过软件或外部触发递增

• 时钟源(Clock Source):基础定时器可以使用不同的时钟源作为计数器的输入时钟。通常,它可以选择使用内部时钟(如系统时钟)或外部时钟(如外部晶体振荡器)作为时钟源,即内部时钟信号CK_INT。基础定时器通常不能直接使用外部时钟信号作为输入。

TIM6 的默认时钟源是 APB1 总线的时钟。

• 预分频器(Prescaler):基础定时器内部有一个可配置的预分频器,用于将输入时钟分频以降低计数器的增减速度。预分频器的设置可以根据需要进行调整,以满足特定的定时要求。

• 自动重装载寄存器(Auto-Reload Register):基础定时器有一个自动重装载寄存器,用于设置计数器的最大计数值。当计数器达到重装载值时,会触发计数器的重装载并产生相应的中断或触发信号。

• 中断/触发控制:基础定时器允许配置中断或触发功能。可以通过使能或禁用中断来触发中断请求,并且可以配置计数器的重装载触发信号。

• 可以输出触发信号(TRGO) 用于出发DAC的同步电路

只有一种事件引起中断或者DMA请求,即计数器上溢出是产生的更新事件中断(UEV Update Event)

时基单元包括:

  • 计数器寄存器 (TIMx_CNT)
  • 预分频器寄存器 (TIMx_PSC)
  • 自动重载寄存器 (TIMx_ARR)

影子寄存器与预加载寄存器

影子寄存器(Shadow Registers)和预加载寄存器(Reload Registers)都与定时器(Timer)和定时器中断有关。它们是在微控制器中用于定时器的高级功能。

影子寄存器(Shadow Registers):

影子寄存器是一种机制,用于在更新定时器寄存器值时避免不必要的干扰。定时器通常用于生成定时中断或脉冲信号,当你更新定时器的计数值或者预加载值时,可能会导致不稳定的定时器行为。为了避免这种情况,一些定时器在更新寄存器值时,首先将新的值加载到影子寄存器中,然后在定时器溢出或计数到某个特定值时,再将影子寄存器的值更新到实际定时器寄存器。这种方式可以确保在定时器计数期间不会干扰定时器的稳定性。

预加载寄存器(Reload Registers):

预加载寄存器是一种用于设置定时器自动重新加载值的机制。当定时器计数到达某个特定值时,它可以自动重新加载一个预设值,然后继续计数。这在周期性生成固定时间间隔的定时中断时非常有用。通过设置预加载寄存器,可以让定时器在每次计数溢出时自动重新开始计数,并生成周期性的中断或触发信号。

CUBEMX对应配置位 auto-reload preload

基础定时器配置流程

  • 选择定时器:根据您的需求和应用场景,选择适合的基础定时器。STM32系列芯片通常提供多个基础定时器,例如TIM6、TIM7等。
  • 确定时钟源:选择基础定时器的时钟源。通常,您可以选择使用内部时钟(如系统时钟)或外部时钟(如外部晶振)作为基础定时器的时钟源。
  • 配置预分频器:根据您的定时要求,配置预分频器以将输入时钟分频。预分频器的设置将影响定时器的计数速度和精度。

预分频器输出频率 = 输入时钟频率 / (预分频值 + 1)

  • 设置自动重装载值:确定定时器的重装载值。重装载值决定了定时器计数器达到的最大值。当计数器达到重装载值时,可以触发中断或其他操作。
  • 配置计数模式和计数方向:选择基础定时器的计数模式和计数方向。
  • 配置中断或触发:如果需要,配置定时器的中断或触发功能。您可以使能或禁用中断,以便在计数器达到重装载值时触发相应的中断请求。
  • 初始化和启动定时器:根据上述配置参数,使用相应的寄存器设置将定时器初始化为所需的状态。确保使能定时器并启动计数。
  • 相应中断或触发处理:如果配置了中断或触发功能,在定时器计数达到重装载值时,处理相应的中断或触发事件。

基础定时器主要函数

初始化

HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) 定时器初始化函数

HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim) 定时器单次执行函数,需要先执行 HAL_TIM_Base_Init()

__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) MSP若函数,在HAL_TIM_Base_Init()被执行,重新实现一般用于定时器时钟设置和中断设置

启动和停止

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)

HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)

HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim)

获取状态

HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim)

中断处理函数

void TIM6_DAC_IRQHandler(void)

{

/* USER CODE BEGIN TIM6_DAC_IRQn 0 */

/* USER CODE END TIM6_DAC_IRQn 0 */

HAL_TIM_IRQHandler(&htim6);

/* USER CODE BEGIN TIM6_DAC_IRQn 1 */

/* USER CODE END TIM6_DAC_IRQn 1 */

}

 

触发更新时间中断后 会调用更新事件中断函数

/* TIM Update event */

if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)

{

if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)

{

__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

htim->PeriodElapsedCallback(htim);

#else

HAL_TIM_PeriodElapsedCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

}

}

 

__weak void 计数器模式(TIM_HandleTypeDef *htim)

{

}

例:配置TIM6 时钟

  1. SYSCLK配置 略
  2. TIM6 配置

定时器频率:

Tigger Event Selection触发输出信号源选择,就是选择定时器溢出后产生什么信号:

Reset:定时器复位

Enable:定时器使能

Update Event:更新事件(一般用于ADC、DAC等)

  1. 程序代码编写

在main函数中 启动定时器

HAL_TIM_Base_Start(&htim6);

// HAL_TIM_Base_Start_IT(&htim6); 中断方式启动

// HAL_TIM_Base_Start_DMA(&htim6); DMA方式启动

在中断配置函数tim.c中添加TIM6的回调函数,编写定时器中断函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

}