[应用相关] STM32通用定时器核心原理与HAL库实践

[复制链接]
435|0
heimaojingzhang 发表于 2025-9-13 15:10 | 显示全部楼层 |阅读模式
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 定时器时钟频率

6396068c375689ea6e.png

fCLK :定时器输入时钟频率(如 APB1 总线频率)
PSCPSCPSC:预分频器值
4.2 定时器溢出时间

6499468c3753cb28ee.png


ARRARRARR:自动重载值
PSCPSCPSC:预分频器值
fCLK :定时器输入时钟频率
5. 典型应用场景
5.1 定时中断

6676868c3752bea829.png

5.2 PWM 生成

3119568c3752318485.png

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

您需要登录后才可以回帖 登录 | 注册

本版积分规则

110

主题

4357

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部