13.4 通用定时器项目:PWM呼吸灯
# 13.4 通用定时器项目:PWM呼吸灯
本实验通过STM32的TIM3定时器实现三色LED呼吸灯效果,结合PWM占空比动态调节与中断控制,实现颜色渐变与切换。
核心功能:
- PWM呼吸灯:亮度从0%渐变至100%,再渐变为0%。
- 颜色轮换:红、绿、蓝三色LED周期性切换。
- OLED显示:实时显示当前激活的LED颜色。
# 13.4.1 硬件电路设计
# 三色LED连接
- 引脚分配:
- PA7 → TIM3_CH2(蓝色LED)
- PB0 → TIM3_CH3(红色LED)
- PB1 → TIM3_CH4(绿色LED)
- 限流电阻:防止LED过流损坏。

# 13.4.2 STM32CubeMX配置
# 1. 工程基础配置
- 芯片型号:STM32F103C8T6
- 主频:72MHz
- 调试接口:SWD
# 2. TIM3定时器配置
- 时钟源:内部时钟(72MHz)
- PWM通道:
- 启用TIM3_CH2、TIM3_CH3、TIM3_CH4
- 模式:PWM Mode 1
- 极性:高电平有效
- 参数设置:
- 预分频器(PSC):720-1 → 分频后时钟频率100kHz
- 自动重装载值(ARR):100-1 → PWM周期1ms
- 初始占空比(Pulse):50%

# 3. 中断配置
- 启用TIM3更新中断(计数器溢出触发)。
# 13.4.3 软件设计
# 1. TIM3初始化(代码清单13‑3)
static void MX_TIM3_Init(void) {
htim3.Instance = TIM3;
htim3.Init.Prescaler = 720-1; // 预分频720,时钟100kHz
htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数
htim3.Init.Period = 100-1; // 周期1ms
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
// 配置PWM通道参数
TIM_OC_InitTypeDef sConfigOC = {
.OCMode = TIM_OCMODE_PWM1,
.Pulse = 50, // 初始占空比50%
.OCPolarity = TIM_OCPOLARITY_HIGH // 高电平有效
};
// 初始化通道2/3/4
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3);
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2. 主循环逻辑(代码清单13‑4)
int main(void) {
// 初始化外设
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
MX_I2C1_Init();
OLED_Init();
HAL_TIM_Base_Start_IT(&htim3); // 启动定时器中断
while (1) {
// 呼吸灯效果:占空比0%→100%→0%
for (int i=0; i<100; i++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, i);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, i);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, i);
HAL_Delay(10); // 渐变速度控制
}
for (int i=99; i>=0; i--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, i);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, i);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, i);
HAL_Delay(10);
}
Led++; // 切换颜色
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 3. 中断回调函数(代码清单13‑5)
volatile int Led = 0;
char message[20];
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim3) {
switch (Led % 3) {
case 0: // 红色LED激活
sprintf(message, "Led:Red");
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // 红
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2); // 蓝
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_4); // 绿
break;
case 1: // 绿色LED激活
sprintf(message, "Led:Green");
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); // 绿
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // 红
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2); // 蓝
break;
case 2: // 蓝色LED激活
sprintf(message, "Led:Blue");
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 蓝
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_4); // 绿
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3); // 红
break;
}
// OLED刷新显示
OLED_NewFrame();
OLED_PrintString(1, 1, message, &font16x16, OLED_COLOR_NORMAL);
OLED_ShowFrame();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 13.4.4 下载验证
# 现象与步骤
- 烧录程序:通过ST-LINK将代码下载至开发板。
- 运行效果:
- LED依次显示红、绿、蓝三色呼吸灯效果。
- OLED同步显示当前颜色(如
Led:Red
)。
- 硬件验证:
- 呼吸灯亮度平滑变化,无闪烁。
- 颜色切换周期与中断触发同步。

关键说明:
PWM周期计算:
中断触发:每次计数器溢出(1ms)触发颜色切换。
占空比控制:通过
__HAL_TIM_SET_COMPARE
动态修改CCR值实现亮度调节。