基础定时器
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 时钟
- SYSCLK配置 略
- TIM6 配置
定时器频率:
Tigger Event Selection触发输出信号源选择,就是选择定时器溢出后产生什么信号:
Reset:定时器复位
Enable:定时器使能
Update Event:更新事件(一般用于ADC、DAC等)
- 程序代码编写
在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)
{
}