Funpack4-3 - 基于MAX32655FTHR实现多种不同灯效切换
该项目使用了MAX32655FTHR和MaximMicrosSDK,实现了多种不同灯效切换的设计,它的主要功能为:使用板载按键控制板载 RGB LED,并支持多种灯效切换。
标签
Funpack活动
测试
开发板
estelle
更新2026-02-10
华中科技大学
23

项目总结报告(MAX32655FTHR:按键控制 RGB 灯效切换)

1. 项目描述(项目介绍与设计思路)

本项目基于 Analog Devices / Maxim 的 MSDK(MaximSDK)示例工程 Hello_World,在原有“串口打印 + LED 闪烁”的基础上,扩展实现了“使用板载按键控制板载 RGB LED,并支持多种灯效切换”的功能。项目的目标不仅是点亮 LED,而是以最小依赖、清晰结构的方式,把一个典型嵌入式交互式小应用所需的关键点串起来:GPIO 驱动封装、按键输入获取与去抖、有限状态机(模式管理)、基于时间片(tick)的灯效渲染,以及通过 UART 输出运行状态用于调试。

1.1 需求分解

  • 输入:板载按键(至少一个)
  • 输出:板载 RGB LED(至少实现两种灯效;本项目实现三种:颜色循环、彩虹、呼吸)
  • 交互:通过按键在不同灯效之间切换,并可调整速度
  • 可观测性:串口输出当前模式/速度,便于验收和调试

1.2 总体设计思路

  1. 采用“模式(Mode)+ 渲染(Render)”的结构:
  • mode 表示当前灯效类型(颜色循环/彩虹/呼吸)。
  • 每个 tick(本项目取 10ms)执行一次按键采样、去抖判断、模式切换,然后执行对应灯效的渲染逻辑。
  1. 按键采用“轮询 + 去抖 + 边沿触发”方案:
  • 直接调用 MSDK 的 PB_Get() 获取当前按键是否按下。
  • 通过连续多次采样一致确认“稳定态”,从而滤掉机械抖动。
  • 以“稳定态从 0->1 的跃迁”作为一次有效按键事件(按下边沿)。
  1. RGB LED 采用 MSDK BSP 的 LED_On/LED_Off 封装:
  • 对于 FTHR_Apps_P1,BSP 提供 LED_RED/LED_GREEN/LED_BLUE 三通道宏。
  • 由于板载 RGB LED 本质上是三路 GPIO 控制(开/关),本项目以“1-bit RGB”进行颜色组合(7 色 + 白色)。
  1. 呼吸灯采用“软件 PWM”实现亮度渐变:
  • RGB LED 没有直接的模拟亮度控制接口时,可用短周期 PWM(例如 2ms 周期)在 10ms tick 中循环若干次,形成占空比变化,从而达到视觉上的明暗变化。

2. 简短的硬件介绍

2.1 开发板与核心器件

本项目使用的硬件平台为 **MAX32655FTHR(BSP:`FTHR_Apps_P1`)**。MAX32655 属于低功耗 MCU 系列,MSDK 提供了完整的 BSP、外设驱动(PeriphDrivers)以及常用杂项驱动(MiscDrivers,如 LED/PushButton)。

2.2 本项目用到的板载资源

- RGB LED:由红/绿/蓝三路 LED 组成,对应三路 GPIO 输出控制(在 BSP 中抽象为 `LED_RED`、`LED_GREEN`、`LED_BLUE`)。

- 用户按键:板载两枚按键,对应 BSP 抽象为 `BUTTON1`、`BUTTON2`。

- Console UART:用于输出调试信息(默认 115200,8-N-1)。

2.3 连接与现象

  • 将 USB 线连接到 FTHR 的 USB 口供电。
  • PC 端打开串口终端(115200 8-N-1),可看到启动信息与模式/速度变化提示。
  • BUTTON1 切换灯效;按 BUTTON2 切换灯效速度(周期)。

3. 软件流程图与主要代码片段说明

3.1 软件总体流程图(主循环)

image.png

3.2 关键模块与代码片段

说明:以下代码片段摘自 main.c,用于解释实现思路。

3.2.1 模式定义(状态机的“状态”)

typedef enum {
MODE_COLOR_CYCLE = 0,
MODE_RAINBOW,
MODE_BREATH,
MODE_COUNT,
} led_mode_t;
  • MODE_COLOR_CYCLE:按步进在 7 色/白色中循环。
  • MODE_RAINBOW:逻辑上与颜色循环类似(同样使用 7 色序列),保留为独立模式便于后续扩展不同“彩虹策略”。
  • MODE_BREATH:软件 PWM + 亮度值递增/递减实现呼吸。

3.2.2 RGB 输出封装(把“颜色”映射到 LED 通道)

static void set_rgb(uint8_t r, uint8_t g, uint8_t b)
{
r ? LED_On(LED_RED) : LED_Off(LED_RED);
g ? LED_On(LED_GREEN) : LED_Off(LED_GREEN);
b ? LED_On(LED_BLUE) : LED_Off(LED_BLUE);
}

这一层封装的意义是:上层灯效逻辑只关心“我想要什么颜色/亮度”,而不直接散落 LED_On/Off 调用。后续若更换硬件(例如 LED 为高电平点亮/低电平点亮差异,或改为 PWM 外设控制),只需调整这一层或替换实现。

3.2.3 按键去抖(稳定态 + 边沿触发)

static int debounce_pressed_edge(debounce_t *d, uint8_t raw_pressed)
{
if (raw_pressed == d->last_raw) {
if (d->same_count < 255) d->same_count++;
} else {
d->last_raw = raw_pressed;
d->same_count = 0;
}

// 3 consecutive identical samples (with 10ms tick) ~= 30ms debounce
if (d->same_count == 3) {
uint8_t prev = d->stable;
d->stable = d->last_raw;
if (!prev && d->stable) return 1; // released -> pressed
}
return 0;
}
  • 机械按键在按下/抬起时会产生抖动,导致一次按压被识别为多次。
  • 这里使用“连续 N 次采样一致”确认稳定态(N=3,tick=10ms,对应约 30ms)。
  • 仅当稳定态由“未按下 -> 按下”时触发一次事件,保证每次按压只切换一次模式/速度。

3.2.4 颜色/彩虹灯效(1-bit RGB 的 7 色序列)

static void render_color_by_index(uint8_t idx)
{
switch (idx % 7) {
case 0: set_rgb(1,0,0); break; // R
case 1: set_rgb(1,1,0); break; // Y
case 2: set_rgb(0,1,0); break; // G
case 3: set_rgb(0,1,1); break; // C
case 4: set_rgb(0,0,1); break; // B
case 5: set_rgb(1,0,1); break; // M
default:set_rgb(1,1,1); break; // W
}
}

由于板载 RGB LED 通道是“开/关”控制,本项目用最直观的 7 色组合(RGB 三基色 + 混色)构成彩虹序列。通过 step_period_ms 控制步进速度,即可得到“颜色切换/彩虹滚动”的效果。

3.2.5 呼吸灯效(软件 PWM + 亮度渐变)

static void render_breath_white(uint8_t brightness_percent)
{
const uint32_t pwm_period_us = 2000;
const uint32_t tick_budget_us = 10000;
uint32_t cycles = tick_budget_us / pwm_period_us;
uint32_t on_us = (pwm_period_us * (uint32_t)brightness_percent) / 100U;
uint32_t off_us = pwm_period_us - on_us;

for (uint32_t i = 0; i < cycles; i++) {
if (on_us) { set_rgb(1,1,1); MXC_Delay(on_us); }
if (off_us){ set_rgb(0,0,0); MXC_Delay(off_us); }
}
}

该实现将 10ms 的时间片拆成若干个短 PWM 周期(2ms),通过占空比(亮度百分比)变化实现“渐亮/渐暗”。这样在不引入额外外设(如定时器 PWM)的前提下,也能得到清晰可见的呼吸效果。

3.3 功能映射(按键与灯效)

  • BUTTON1:切换灯效模式(颜色循环 -> 彩虹 -> 呼吸 -> 循环)。
  • BUTTON2:切换速度档位(例如 500ms / 200ms / 1000ms)。
  • 串口输出:
    • 启动打印:Hello World! 与按键说明。
    • 切换打印:mode = xspeed period_ms = y

4. 功能展示图片及说明(占位符)

4.1 硬件连接与运行环境

image.png

说明:展示 USB 供电连接、串口打开方式(115200 8-N-1),标注 RGB LED 与 BUTTON1/BUTTON2 的位置。

4.2 灯效模式展示

见视频

说明:按 BUTTON1 切换到颜色循环,RGB 颜色按固定序列切换,按 BUTTON2 可明显看到切换速度变快/变慢。

说明:展示 7 色序列滚动效果,强调“彩虹”是由 RGB 组合色构成。

说明:展示亮度从暗到亮再到暗的周期变化,说明该效果由软件 PWM 近似实现。

4.3 串口输出截图

image.png

说明:展示模式切换打印、速度切换打印,便于验收。

5. 项目中遇到的难题与解决方法

5.1 板卡 BSP 切换(EvKit_V1 -> FTHR_Apps_P1)

难点:不同板卡的 LED/按键宏定义、引脚映射不同。直接复用 EvKit 示例可能导致“找不到 LED_BLUE / BUTTON 宏”或硬件现象不符合预期。

解决:

  • 明确目标板卡为 MAX32655FTHR,选择 BSP:FTHR_Apps_P1
  • 依赖 BSP 提供的统一抽象(LED_RED/GREEN/BLUEBUTTON1/2),代码尽量不写死具体 GPIO 引脚。

5.2 安装SDK

难点:win11系统下安装的document有点问题

飞书文档 - 图片

解决:管理员身份运行(否则无法取消下载安装document的选项),取消勾选下载安装document的选项

6. 对本活动的心得体会(意见与建议)

通过本次活动,我最大的收获是把“驱动 API 的调用”提升到“可交互的嵌入式小系统”的思路:输入需要去抖与事件化,输出需要抽象与可扩展,逻辑需要用模式/状态机组织,时间需要用 tick 或定时器进行统一调度。相比单纯点灯,本项目更接近实际产品中“按键控制灯效/指示状态”的小功能模块。

我也有几点建议:

  1. 建议在示例工程中提供“按键去抖”的标准范式(轮询与中断两种),避免新手反复踩坑。按键抖动是非常典型的问题,但很多入门示例不会覆盖。
  2. 建议在 BSP 文档或 README 中更明确地列出“本板卡 LED/按键资源映射”(例如 LED1/2/3 分别对应 RGB 哪一路,BUTTON1/2 的极性),这样在切换板卡(EvKit/FTHR)时更直观。
  3. 对于呼吸灯等需要亮度变化的效果,后续可以进一步探索硬件 PWM/定时器方案:软件 PWM 简单直接,但会占用 CPU 时间片;硬件 PWM 方案更节能、更平滑,也更贴近产品化实现。
  4. 在活动验收层面,建议同时提供“可视化现象 + 串口日志”的双证据:LED 效果用于直观展示,串口日志用于定量确认模式/速度切换是否正确,减少主观误判。


附:本项目在 MAX32655FTHR 的使用说明(简要)

  • 串口:115200 8-N-1
  • BUTTON1:切换灯效
  • BUTTON2:切换速度

构建(示例):

make -r -j 8 TARGET=MAX32655 BOARD=FTHR_Apps_P1 MAXIM_PATH=C:/MaximSDK
附件下载
Hello_World.7z
团队介绍
个人和GPT
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号