STM32 定时器(定时中断 & PWM 控制 LED 亮度)
STM32 定时器(TIM)可用于 精准定时、PWM 产生、编码器读取、输入捕获 等。本文介绍 定时中断(Timer Interrupt) 和 PWM(Pulse Width Modulation) 控制 LED 亮度。
1. STM32 定时器简介
STM32 定时器分为 四类:
定时器类型 | 功能 | 示例 |
---|---|---|
基础定时器(Basic Timer) | 仅定时 | TIM6、TIM7 |
通用定时器(General Timer) | 定时、PWM、输入捕获 | TIM2、TIM3、TIM4、TIM5 |
高级定时器(Advanced Timer) | 高级 PWM(死区、互补输出) | TIM1、TIM8 |
看门狗定时器(Watchdog Timer) | 超时复位 | IWDG、WWDG |
💡 常用定时器:
- TIM2/TIM3/TIM4:通用定时器,支持 定时中断 & PWM
- TIM1:高级定时器,支持 互补 PWM(用于电机控制)
2. 定时中断(Timer Interrupt)
定时中断可用于 定时任务,如 LED 闪烁、周期采样、系统时钟。
📌 2.1 STM32CubeMX 配置
- 选择 TIM3(通用定时器)
- Mode 设为 "Internal Clock"
- Prescaler(预分频) 设置为 7999
- Counter Period(计数周期) 设为 9999
- NVIC 使能中断
📌 计算定时周期:
定时周期=(ARR+1)×(PSC+1)时钟频率\text{定时周期} = \frac{(\text{ARR} + 1) \times (\text{PSC} + 1)}{时钟频率}
例如:
(9999+1)×(7999+1)72MHz=1s\frac{(9999+1) \times (7999+1)}{72MHz} = 1s
👉 定时 1 秒触发一次中断
📌 2.2 代码实现
(1)初始化定时器
void MX_TIM3_Init(void) {
htim3.Instance = TIM3;
htim3.Init.Prescaler = 7999; // 预分频
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 9999; // 计数周期
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim3);
HAL_TIM_Base_Start_IT(&htim3); // 启动定时器中断
}
(2)定时中断回调
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM3) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // 翻转 LED 状态
}
}
📌 每 1 秒 LED 亮灭一次。
📌 2.3 启动定时器
HAL_TIM_Base_Start_IT(&htim3); // 启动 TIM3 定时中断
📌 2.4 关闭定时器
HAL_TIM_Base_Stop_IT(&htim3);
3. PWM 控制 LED 亮度
PWM(脉宽调制)用于 LED 亮度控制、舵机控制、电机调速。
📌 3.1 STM32CubeMX 配置
- 选择 TIM2(通用定时器)
- Channel1 设为 PWM 模式
- 设置 Prescaler=71,Period=999
- 引脚配置
- PA0(TIM2_CH1):PWM 输出(连接 LED)
📌 PWM 频率计算:
PWM 频率=时钟频率(PSC+1)×(ARR+1)\text{PWM 频率} = \frac{\text{时钟频率}}{(\text{PSC} + 1) \times (\text{ARR} + 1)}
如:
72MHz(71+1)×(999+1)=1KHz\frac{72MHz}{(71+1) \times (999+1)} = 1KHz
📌 3.2 代码实现
(1)初始化 PWM
void MX_TIM2_Init(void) {
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; // 预分频
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 999; // 自动重装值
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim2);
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500; // 初始占空比 50%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
}
(2)启动 PWM
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
(3)修改 LED 亮度
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 700); // 占空比 70%
📌 值越大,LED 越亮
(4)渐变 LED 亮度
for (uint16_t i = 0; i < 1000; i += 10) {
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, i);
HAL_Delay(10);
}
📌 LED 亮度逐渐变化
4. 总结
✅ 定时中断(Timer Interrupt)用于周期任务,如 LED 闪烁、定时采样
✅ PWM 通过调节占空比,实现 LED 亮度调节、电机调速
✅ 结合定时器 + PWM,可实现智能控制,如呼吸灯、自动调节亮度
🚀 建议新手先实现 LED 闪烁,再进阶学习 PWM 控制!