首页 区块链

玩转单片机:用 PWM 实现 RGB 三色呼吸灯和跑马灯效果

分类:区块链
字数: (2753)
阅读: (7959)
内容摘要:玩转单片机:用 PWM 实现 RGB 三色呼吸灯和跑马灯效果,

在嵌入式开发中,RGB 三色呼吸灯和跑马灯是常见的视觉效果,常用于指示设备状态或增添趣味性。本文将深入探讨如何利用单片机的 PWM(脉冲宽度调制)功能,实现这两种效果。本文将以常见的STM32系列单片机为例,但原理同样适用于其他单片机平台,例如 Arduino,ESP32 等。这些平台都支持PWM,只是配置方式略有不同。关键在于理解PWM的本质和如何控制RGB LED的亮度。

RGB LED 原理

RGB LED 实际上是由红 (Red)、绿 (Green)、蓝 (Blue) 三个独立的 LED 封装在一起。通过控制这三个 LED 的亮度,我们可以混合出各种颜色。常见的 RGB LED 有共阳极和共阴极两种类型,区别在于公共端是连接电源正极还是负极。本文以共阴极为例进行讲解。

玩转单片机:用 PWM 实现 RGB 三色呼吸灯和跑马灯效果

共阴极 RGB LED 连接

共阴极 RGB LED 的公共端连接到 GND,而 R、G、B 三个引脚分别连接到单片机的 PWM 输出引脚。为了限制电流,需要在每个引脚上串联一个电阻,阻值根据 LED 的额定电压和电流来计算,通常在 220Ω 到 1kΩ 之间。

玩转单片机:用 PWM 实现 RGB 三色呼吸灯和跑马灯效果
// 共阴极 RGB LED 连接示例
// R -> 单片机 PWM 输出引脚 1
// G -> 单片机 PWM 输出引脚 2
// B -> 单片机 PWM 输出引脚 3
// 公共端 -> GND

PWM 控制 RGB LED 亮度

PWM 是一种通过改变脉冲的占空比来调节输出电压的技术。对于 RGB LED,我们可以利用 PWM 来控制每个 LED 的亮度。占空比越大,LED 亮度越高;占空比越小,LED 亮度越低。通过调整 R、G、B 三个 LED 的占空比,我们可以混合出各种颜色。

玩转单片机:用 PWM 实现 RGB 三色呼吸灯和跑马灯效果

PWM 呼吸灯实现

呼吸灯效果是指 LED 的亮度逐渐增加到最大值,然后再逐渐减小到最小值,循环往复。我们可以通过改变 PWM 的占空比来实现呼吸灯效果。例如,可以使用正弦函数或三角形函数来控制占空比的变化。

玩转单片机:用 PWM 实现 RGB 三色呼吸灯和跑马灯效果
// STM32 HAL 库 PWM 呼吸灯示例

#include "stm32f1xx_hal.h"

TIM_HandleTypeDef htim3; // 定时器句柄
uint16_t brightness = 0; // 亮度值
int8_t direction = 1; // 亮度变化方向 (1: 增加, -1: 减小)

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
{
  // 使能时钟,配置引脚等,略
}

void TIM3_Init(void)
{
  // 定时器初始化配置,略
}

void main(void)
{
  HAL_Init();
  TIM3_Init();
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动 PWM 通道 1 (R)
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 启动 PWM 通道 2 (G)
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // 启动 PWM 通道 3 (B)

  while (1)
  {
    brightness += direction;
    if (brightness > __HAL_TIM_GET_AUTORELOAD(&htim3)) {
      brightness = __HAL_TIM_GET_AUTORELOAD(&htim3); // 防止溢出
      direction = -1; // 改变方向
    } else if (brightness == 0) {
      direction = 1; // 改变方向
    }

    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, brightness); // 设置 R 通道占空比
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, brightness); // 设置 G 通道占空比
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, brightness); // 设置 B 通道占空比

    HAL_Delay(10); // 延时
  }
}

PWM 跑马灯实现

跑马灯效果是指 LED 按照一定的顺序依次点亮,循环往复。对于 RGB LED,我们可以通过改变 R、G、B 三个 LED 的点亮顺序和颜色来实现跑马灯效果。可以使用状态机或数组来控制颜色变化。

// STM32 HAL 库 PWM 跑马灯示例

#include "stm32f1xx_hal.h"

TIM_HandleTypeDef htim3; // 定时器句柄
uint8_t colorIndex = 0; // 颜色索引

// 颜色数组,可以自定义颜色
uint16_t colors[7][3] = {
  {255, 0, 0},   // Red
  {0, 255, 0},   // Green
  {0, 0, 255},   // Blue
  {255, 255, 0}, // Yellow
  {255, 0, 255}, // Magenta
  {0, 255, 255}, // Cyan
  {255, 255, 255}  // White
};

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
{
  // 使能时钟,配置引脚等,略
}

void TIM3_Init(void)
{
  // 定时器初始化配置,略
}

void main(void)
{
  HAL_Init();
  TIM3_Init();
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动 PWM 通道 1 (R)
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 启动 PWM 通道 2 (G)
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // 启动 PWM 通道 3 (B)

  while (1)
  {
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, colors[colorIndex][0]); // 设置 R 通道占空比
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, colors[colorIndex][1]); // 设置 G 通道占空比
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, colors[colorIndex][2]); // 设置 B 通道占空比

    colorIndex++;
    if (colorIndex >= 7) {
      colorIndex = 0; // 循环颜色
    }

    HAL_Delay(500); // 延时
  }
}

实战避坑经验

  1. 电阻选择:务必根据 LED 的额定参数选择合适的电阻,防止 LED 烧毁。使用万用表测量实际电流,确保在安全范围内。
  2. PWM 频率:PWM 频率过低会导致 LED 闪烁,频率过高会增加单片机的负担。通常选择 1kHz 到 10kHz 之间。
  3. 共阳极/共阴极:注意区分 RGB LED 的类型,共阳极和共阴极的控制方式相反。共阳极的控制信号是低电平有效。
  4. 单片机资源:合理分配单片机资源,确保 PWM 输出引脚与其他外设不冲突。例如,在使用 DMA (直接内存访问) 时需要注意通道分配。
  5. 调试工具:使用调试器(如 J-Link、ST-Link)可以方便地观察 PWM 输出和变量变化,加速调试过程。
  6. 软件延时:避免在中断服务程序中使用过长的软件延时,可能导致系统响应不及时。

在开发过程中,我们可以借助一些开源库来简化开发流程,例如 Arduino 的 FastLED 库,它提供了丰富的颜色定义和动画效果。同时,可以使用串口调试助手打印调试信息,方便排查问题。

随着物联网技术的快速发展,RGB 三色呼吸灯和跑马灯等视觉效果在智能家居、可穿戴设备等领域有着广泛的应用前景。掌握这些技术,可以为你的项目增添更多亮点。

玩转单片机:用 PWM 实现 RGB 三色呼吸灯和跑马灯效果

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea1.store/blog/495014.SHTML

本文最后 发布于2026-04-02 19:17:12,已经过了25天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 柚子很甜 5 天前
    请问一下,如果我想实现更复杂的颜色渐变效果,有什么好的算法或库推荐吗?
  • 雪碧透心凉 3 天前
    感谢分享!跑马灯效果的代码示例简洁明了,可以直接拿来用。
  • 背锅侠 2 天前
    这篇文章讲得很透彻,代码示例也很实用,正好解决了我的一个项目需求。
  • 追梦人 1 天前
    请问一下,如果我想实现更复杂的颜色渐变效果,有什么好的算法或库推荐吗?
  • 广东肠粉 1 天前
    感谢分享!跑马灯效果的代码示例简洁明了,可以直接拿来用。