文章目录
一.定时器中断实现多任务并发
在嵌入式开发中,定时器中断是实现精准定时和多任务并发的高效方式。相比传统的循环延时,定时器中断能让 CPU 在等待期间处理其他任务,大幅提高资源利用率。
1. 功能需求
- 5 秒定时:每隔 5 秒通过串口发送 “hello windows!”
- 2 秒定时:控制 LED 周期性闪烁
- 实现上述两个任务的并发执行
2. 硬件设计
- 主控:STM32F103C8T6 最小系统板
- LED:外接 LED+ 板载 LED
- 串口:USART1
- 定时器:TIM2(2 秒定时)、TIM3(5 秒定时)
3. STM32CubeMX 配置步骤
(1)基础配置
- 时钟配置:外部晶振 (HSE),系统时钟 72MHz
- LED 引脚:PA0 设为 GPIO 输出,PC13 默认输出
- 串口配置:USART1 异步模式,波特率 115200,无校验位
(2)定时器配置
定时器时钟频率为 72MHz,通过预分频器 (PSC) 和自动重装载值 (ARR) 计算定时时间:定时时间 = (PSC+1)×(ARR+1) / 时钟频率
- TIM2(2 秒定时):
- 预分频器 (PSC):7199 → 72MHz/(7199+1)=10kHz
- 自动重装载值 (ARR):19999 → 10kHz×20000=2 秒
- 使能更新中断 (Update Interrupt)
- TIM3(5 秒定时):
- 预分频器 (PSC):7199 → 同 TIM2,10kHz 计数频率
- 自动重装载值 (ARR):49999 → 10kHz×50000=5 秒
- 使能更新中断 (Update Interrupt)
配置过程如下:

定时器3与上述类似
4.代码实现
(1)定时器中断回调函数
在main.c中重写 HAL 库定时器中断回调函数:
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim2) { // 2秒定时:LED闪烁
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
}
else if (htim == &htim3) { // 5秒定时:串口发送
uint8_t data[] = "hello windows!\r\n";
HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100);
}
}
/* USER CODE END 4 */
(2)主函数启动定时器
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
MX_TIM3_Init();
// 启动定时器中断
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Start_IT(&htim3);
while (1) {
// 主循环可执行其他任务,不阻塞
}
}
实验结果如下:
定时器中断
定时器中断
定时器中断
5.非定时器实现方案(轮询法)
若不使用定时器,可通过系统滴答定时器的时间戳实现伪并发:
int main(void) {
uint32_t led_prev = 0, uart_prev = 0;
uint32_t current;
while (1) {
current = HAL_GetTick(); // 获取毫秒级时间戳
// 2秒LED闪烁
if (current - led_prev >= 2000) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
led_prev = current;
}
// 5秒串口发送
if (current - uart_prev >= 5000) {
uint8_t data[] = "hello windows!\r\n";
HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100);
uart_prev = current;
}
}
}
缺点:精度受主循环执行速度影响,若存在耗时操作会导致定时不准。
二.PWM 实现呼吸灯效果
PWM(脉冲宽度调制)通过改变高低电平占空比实现模拟输出效果,适合控制 LED 亮度变化(呼吸灯)。
1. 功能需求
- 使用 TIM3 和 TIM4 输出 PWM 波形
- 占空比随时间动态变化,实现两个 LED 的呼吸效果
- 控制对象:板载 LED和外接 LED
2. STM32CubeMX 配置
(1)定时器 PWM 配置
- TIM3_CH1(PA6):控制外接 LED
- 时钟源:内部时钟
- 预分频器 (PSC):71 → 72MHz/(71+1)=1MHz
- 自动重装载值 (ARR):999 → 频率 = 1MHz/1000=1kHz(人眼无闪烁)
- 模式:PWM Generation CH1,PWM 模式 1
- TIM4_CH2(PB7):控制板载 LED(需通过 GPIO 重映射)
- 配置同 TIM3,PSC=71,ARR=999
- 使能 TIM4 重映射:部分重映射→TIM4_CH2 映射到 PB7
配置过程如下图:

3. 呼吸灯代码实现
(1)PWM 占空比动态调整逻辑
// 全局变量
uint16_t pwm_val = 0; // PWM占空比(0-999)
uint8_t dir = 1; // 变化方向(1-递增,0-递减)
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
MX_TIM4_Init();
// 启动PWM输出
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
while (1) {
// 占空比调整(0→999→0循环)
if (dir) {
pwm_val++;
if (pwm_val >= 999) dir = 0;
} else {
pwm_val--;
if (pwm_val <= 0) dir = 1;
}
// 更新PWM占空比
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwm_val);
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, pwm_val);
HAL_Delay(5); // 控制变化速度
}
}
4.实现原理
- 呼吸灯效果通过 PWM 占空比从 0 到 100% 平滑过渡再反向过渡实现
- TIM3 和 TIM4 的 PWM 频率设置为 1kHz(高于人眼视觉暂留频率)
- 通过
__HAL_TIM_SET_COMPARE函数实时更新比较值,改变高低电平占空比
实验结果如下:
PWM呼吸灯
三.总结
该内容围绕 STM32F103C8T6 的定时器中断与 PWM 应用展开,介绍了两部分核心内容:一是利用 TIM2 和 TIM3 定时器中断实现多任务并发,通过配置合适的预分频器和自动重装载值,分别实现 2 秒 LED 闪烁与 5 秒串口发送消息的功能,并对比了轮询法的不足;二是借助 TIM3 和 TIM4 的 PWM 功能实现呼吸灯效果,通过动态调整占空比让外接 LED 和板载 LED 呈现亮度平滑变化的效果,同时说明了相关配置与实现原理。
269

被折叠的 条评论
为什么被折叠?



