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定时器配置

  1. 时钟源:内部时钟(72MHz)
  2. PWM通道
    • 启用TIM3_CH2、TIM3_CH3、TIM3_CH4
    • 模式:PWM Mode 1
    • 极性:高电平有效
  3. 参数设置
    • 预分频器(PSC):720-1 → 分频后时钟频率100kHz
    • 自动重装载值(ARR):100-1 → PWM周期1ms
    • 初始占空比(Pulse):50%
设置TIM3为PWM模式

# 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. 主循环逻辑(代码清单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

# 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

# 13.4.4 下载验证

# 现象与步骤

  1. 烧录程序:通过ST-LINK将代码下载至开发板。
  2. 运行效果
    • LED依次显示红、绿、蓝三色呼吸灯效果。
    • OLED同步显示当前颜色(如Led:Red)。
  3. 硬件验证
    • 呼吸灯亮度平滑变化,无闪烁。
    • 颜色切换周期与中断触发同步。
硬件实现结果

关键说明

  • PWM周期计算

  • 中断触发:每次计数器溢出(1ms)触发颜色切换。

  • 占空比控制:通过__HAL_TIM_SET_COMPARE动态修改CCR值实现亮度调节。