1. 通用定时器概述
STM32 的通用定时器(General Purpose Timer, GPTIM)是嵌入式系统中实现定时、计数、PWM 生成功能的核心外设。其核心特性包括:
16/32 位可编程计数器(TIMx_CNT)
预分频器(TIMx_PSC):将时钟源分频为计数器时钟
自动重载寄存器(TIMx_ARR):设定计数器周期
捕获/比较通道(TIMx_CCRx):支持输入捕获和输出比较
多种工作模式:向上计数、向下计数、中央对齐模式
中断/DMA 支持:支持更新事件、捕获/比较事件等中断
2. 核心寄存器详解
2.1 控制寄存器 1 (TIMx_CR1)
typedef struct {
uint16_t TIM_CounterMode; // 计数模式(向上/向下/中央对齐)
uint16_t TIM_CounterDirection; // 计数方向(仅中央对齐模式有效)
uint16_t TIM_Prescaler; // 预分频器值
uint16_t TIM_AutoReloadPreload; // 自动重载预装载使能
} TIM_CR1_TypeDef;
TIM_CounterMode:
TIM_COUNTERMODE_UP:向上计数
TIM_COUNTERMODE_DOWN:向下计数
TIM_COUNTERMODE_CENTERALIGNED1:中央对齐模式 1
TIM_Prescaler:预分频系数(0~65535),用于分频定时器时钟。
TIM_AutoReloadPreload:
TIM_AUTORELOAD_PRELOAD_DISABLE:禁用自动重载
TIM_AUTORELOAD_PRELOAD_ENABLE:启用自动重载(更新事件后加载新值)
2.2 预分频器寄存器 (TIMx_PSC)
uint16_t TIMx_PSC;
作用:将输入时钟分频为 TIMx_CLK = (TIMx_CLK_IN) / (PSC + 1)
典型配置:
htim.Instance->PSC = 7199; // 72MHz -> 10kHz(72MHz / (7199+1) = 10kHz)
2.3 自动重载寄存器 (TIMx_ARR)
uint32_t TIMx_ARR;
作用:设定计数器周期(向上计数时从 0 到 ARR;向下计数时从 ARR 到 0)。
典型配置:
htim.Instance->ARR = 9999; // 10kHz -> 1s(10000 个计数周期)
2.4 状态寄存器 (TIMx_SR)
uint16_t TIMx_SR;
标志位:
TIM_FLAG_UPDATE:更新事件标志(计数器溢出)
TIM_FLAG_CC1:捕获/比较通道 1 事件
TIM_FLAG_CC2:捕获/比较通道 2 事件
清零方法:
__HAL_TIM_CLEAR_FLAG(&htim, TIM_FLAG_UPDATE); // 清除更新事件标志
3. HAL 库主要函数详解
3.1 定时器初始化函数
HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);
参数说明:
htim:指向 TIM_HandleTypeDef 结构体的指针,包含以下关键成员:
Instance:定时器外设基地址(如 TIM2)
Init:初始化配置结构体(TIM_Base_InitTypeDef)
typedef struct {
uint32_t Prescaler; // 预分频值(0~65535)
uint32_t CounterMode; // 计数模式(向上/向下/中央对齐)
uint32_t Period; // 自动重载值(0~65535 或 0~4294967295)
uint32_t ClockDivision; // 时钟分频(0: 不分频, 1: 2 分频, 2: 4 分频)
uint32_t AutoReloadPreload; // 自动重载预装载使能
} TIM_Base_InitTypeDef;
返回值:HAL_OK 表示初始化成功。
示例代码:
TIM_HandleTypeDef htim2;
void MX_TIM2_Init(void) {
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7199; // 72MHz -> 10kHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 9999; // 10kHz -> 1s
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
Error_Handler();
}
}
3.2 启动定时器
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
参数说明:
htim:指向已初始化的 TIM_HandleTypeDef 结构体。
功能:启动定时器并使能更新中断。
示例代码:
if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK) {
Error_Handler();
}
3.3 中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
参数说明:
htim:触发中断的定时器句柄。
功能:当计数器溢出时自动调用此回调函数。
示例代码:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM2) {
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // 切换 LED 状态
}
}
3.4 PWM 输出配置函数
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
参数说明:
htim:指向已初始化的 TIM_HandleTypeDef 结构体。
Channel:PWM 通道(如 TIM_CHANNEL_1)。
示例代码:
// 配置 PWM 参数
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1; // PWM 模式 1
sConfigOC.Pulse = 500; // 占空比(ARR=9999,占空比为 5%)
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 高电平有效
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
Error_Handler();
}
// 启动 PWM
if (HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1) != HAL_OK) {
Error_Handler();
}
4. 定时器时序计算公式
4.1 定时器时钟频率
fCLK :定时器输入时钟频率(如 APB1 总线频率)
PSCPSCPSC:预分频器值
4.2 定时器溢出时间
ARRARRARR:自动重载值
PSCPSCPSC:预分频器值
fCLK :定时器输入时钟频率
5. 典型应用场景
5.1 定时中断
5.2 PWM 生成
6. 常见问题与解决方案
6.1 定时器无法启动
原因:未使能定时器时钟或未配置 NVIC 中断。
解决方案:
__HAL_RCC_TIM2_CLK_ENABLE(); // 使能 TIM2 时钟
HAL_NVIC_EnableIRQ(TIM2_IRQn); // 使能中断
6.2 PWM 占空比不准确
原因:未正确配置 TIMx_CCRx 寄存器。
解决方案:
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 1000); // 设置占空比为 10%
7. 总结
STM32 通用定时器通过灵活的寄存器配置和 HAL 库函数,可以实现精确的定时、PWM 生成、输入捕获等功能。掌握预分频器、自动重载寄存器和中断回调函数的配置是关键。实际应用中需结合具体需求调整参数,并验证时序计算结果是否符合预期。
————————————————
版权声明:本文为CSDN博主「Shylock_Mister」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Shylock_Mister/article/details/151082900
|
|