Funpack S4 #3使用MAX32655FTHR点亮LED灯
该项目使用了MAX32655FTHR,实现了点亮LED灯的设计,它的主要功能为:通过按键切换LED灯的颜色,和点亮方式。。
标签
LED
MAX32655FTHR
maximSDK
软件PWM
aramy
更新2026-02-05
23

一、硬件介绍:

image.png

MAX32655FTHR 是一款使用MAX32655 Arm© Cortex®-M4F和Bluetooth® 5.2低功耗(LE)快速实施超低功耗无线解决方案。该电路板还包括MAX20303 PMIC以实现电池和电源管理。该电路板包括各种外设,如数字麦克风、低功耗立体声音频编解码器、128MB QSPI闪存、micro SD卡连接器、RGB指示器LED和按钮。这次任务有使用板载的LED和按键。

二、任务选择:

这次任务,选择了简单任务。任务4:点灯。使用板载按键控制板卡上的RGB LED,并实现一种或多种不同灯效切换。

三、设计思路:

使用两种方式驱动LED灯。一种为普通的亮、灭;一种为呼吸灯的方式。板子上的LED灯是一个RGB三色LED灯,所以还可以选择红、绿、蓝三色显示。给系统两个状态值,用来控制颜色和闪烁模式。使用板载的按键来切换不同的状态值,为了保障系统响应及时性,使用中断获取按键信息。

image.png

四、任务实现:

开发工具使用MaximSDK,基本就是eclipse内核,加载了完整的编译工具的一个SDK。安装起来挺不容易的,好在之前有做MAX78000项目,电脑安装好了MaximSDK。

image.png

使用kimi做协助,现在的人工智能很强大了,能很好滴帮忙生成代码。

首先是GPIO的驱动。将LED对应的管脚设置为输出;按键对应的管脚设置为输入。并添加按键的中断调用。

/***** ISR Functions *****/
static void sw2_isr(void *cbdata) {
sw2_event = 1; // 设置事件标志
MXC_GPIO_ClearFlags(SW2_PORT, SW2_PIN);
}

static void sw3_isr(void *cbdata) {
sw3_event = 1; // 设置事件标志
MXC_GPIO_ClearFlags(SW3_PORT, SW3_PIN);
}

/***** Functions *****/
static void gpio_interrupt_init(void) {
mxc_gpio_cfg_t gpio_cfg;

// 使能GPIO时钟(必须!)
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_GPIO0);

// LED配置(初始熄灭)
gpio_cfg.port = LED_RED_PORT;
gpio_cfg.mask = LED_RED_PIN;
gpio_cfg.pad = MXC_GPIO_PAD_NONE;
gpio_cfg.func = MXC_GPIO_FUNC_OUT;
gpio_cfg.vssel = MXC_GPIO_VSSEL_VDDIO;
MXC_GPIO_Config(&gpio_cfg);
MXC_GPIO_OutSet(LED_RED_PORT, LED_RED_PIN);

gpio_cfg.port = LED_GREEN_PORT;
gpio_cfg.mask = LED_GREEN_PIN;
MXC_GPIO_Config(&gpio_cfg);
MXC_GPIO_OutSet(LED_GREEN_PORT, LED_GREEN_PIN);

gpio_cfg.port = LED_BLUE_PORT;
gpio_cfg.mask = LED_BLUE_PIN;
MXC_GPIO_Config(&gpio_cfg);
MXC_GPIO_OutSet(LED_BLUE_PORT, LED_BLUE_PIN);

// SW2中断配置
gpio_cfg.port = SW2_PORT;
gpio_cfg.mask = SW2_PIN;
gpio_cfg.pad = MXC_GPIO_PAD_PULL_UP;
gpio_cfg.func = MXC_GPIO_FUNC_IN;
gpio_cfg.vssel = MXC_GPIO_VSSEL_VDDIO;
MXC_GPIO_Config(&gpio_cfg);
MXC_GPIO_RegisterCallback(&gpio_cfg, sw2_isr, NULL);
MXC_GPIO_IntConfig(&gpio_cfg, MXC_GPIO_INT_FALLING); // 下降沿触发
MXC_GPIO_EnableInt(SW2_PORT, SW2_PIN);

// SW3中断配置
gpio_cfg.port = SW3_PORT;
gpio_cfg.mask = SW3_PIN;
MXC_GPIO_Config(&gpio_cfg);
MXC_GPIO_RegisterCallback(&gpio_cfg, sw3_isr, NULL);
MXC_GPIO_IntConfig(&gpio_cfg, MXC_GPIO_INT_FALLING);
MXC_GPIO_EnableInt(SW3_PORT, SW3_PIN);

// 使能GPIO中断向量
NVIC_EnableIRQ(MXC_GPIO_GET_IRQ(MXC_GPIO_GET_IDX(SW2_PORT)));
}

然后是LED灯的驱动。两种驱动模式。模式一,普通的亮灭驱动。只需要按颜色状态值,去给LED灯对应的管脚设置高、低电平即可。

static void update_led_color(void) {
// 关闭所有LED
MXC_GPIO_OutSet(LED_RED_PORT, LED_RED_PIN);
MXC_GPIO_OutSet(LED_GREEN_PORT, LED_GREEN_PIN);
MXC_GPIO_OutSet(LED_BLUE_PORT, LED_BLUE_PIN);

// 点亮当前颜色
switch (current_color) {
case COLOR_RED:
MXC_GPIO_OutClr(LED_RED_PORT, LED_RED_PIN);
break;
case COLOR_GREEN:
MXC_GPIO_OutClr(LED_GREEN_PORT, LED_GREEN_PIN);
break;
case COLOR_BLUE:
MXC_GPIO_OutClr(LED_BLUE_PORT, LED_BLUE_PIN);
break;
case COLOR_OFF:
printf("LED: OFF\n");
break;
}
}

模式2:呼吸灯状态。使用PWM来驱动呼吸灯。使用人工智能生成的硬件PWM驱动LED灯,总是有点问题。最后放弃了,使用软件模拟PWM,来驱动呼吸灯的效果。软件模拟缺点就是占用MCU时间较多,这样会导致用户按键响应速度降低,交互体验较差。所以这里使用软件模拟PWM后,按键部分就全部使用硬件中断,以提升系统相应速度。

//呼吸灯
static void set_led_bread() {
mxc_gpio_regs_t *port;
uint32_t currmask=0;
// 先关闭所有LED(设置为高电平)
MXC_GPIO_OutSet(LED_RED_PORT, LED_RED_PIN);
MXC_GPIO_OutSet(LED_GREEN_PORT, LED_GREEN_PIN);
MXC_GPIO_OutSet(LED_BLUE_PORT, LED_BLUE_PIN);

switch (current_color) {
case COLOR_RED:
port = LED_RED_PORT;
currmask = LED_RED_PIN;
break;
case COLOR_GREEN:
port = LED_GREEN_PORT;
currmask = LED_GREEN_PIN;
break;
case COLOR_BLUE:
port = LED_BLUE_PORT;
currmask = LED_BLUE_PIN;
break;
case COLOR_OFF:
// 保持全灭
return;
break;
}

for (int duty = 0; duty <= 100; duty += 1) {
for (int i = 0; i < 100; i++) {
if (i < duty) {
MXC_GPIO_OutClr(port, currmask); // 点亮
} else {
MXC_GPIO_OutSet(port, currmask); // 熄灭
}
MXC_Delay(MXC_DELAY_USEC(50)); // 10us周期 = 100kHz
}
}
for (int duty = 100; duty >= 0; duty -= 1) {
for (int i = 0; i < 100; i++) {
if (i < duty) {
MXC_GPIO_OutClr(port, currmask);
} else {
MXC_GPIO_OutSet(port, currmask);
}
MXC_Delay(MXC_DELAY_USEC(50));
}
}
}

最后在主函数中通过按键状态的判断,来修改颜色、显示模式两个状态量。

/***** Main *****/
int main(void) {
gpio_interrupt_init();
update_led_color();

while (1) {
// 检查是否有按键事件且未锁定
if ((sw2_event) && !button_lock) {
button_lock = 1; // 锁定,防止重复触发
current_color = (current_color + 1) % 4;
// 等待按键释放
while (MXC_GPIO_InGet(SW2_PORT, SW2_PIN) == 0) {
MXC_Delay(MXC_DELAY_MSEC(10));
}
// 清除事件标志
sw2_event = 0;
button_lock = 0; // 解锁,准备下次按键
}
if ((sw3_event) && !button_lock) {
button_lock = 1; // 锁定,防止重复触发
led_stat = (led_stat + 1) % 2;
// 等待按键释放
while (MXC_GPIO_InGet(SW3_PORT, SW3_PIN) == 0) {
MXC_Delay(MXC_DELAY_MSEC(10));
}
// 清除事件标志
sw3_event = 0;
button_lock = 0; // 解锁,准备下次按键
}
if (led_stat == 0)
update_led_color();
if (led_stat == 1)
set_led_bread();
}
return 0;
}

五、效果展示:

绿色呼吸灯。

image.png

image.png

蓝色呼吸灯

image.png

红灯

image.png

六、心得体会:

MAX这个系列的板子很有意思,之前有接触过MAX78000,所以很快就上手了这块板子。但是在学习过程中错误滴将MAX78000的固件写错到了这块MAX32655板子,导致一块板子的损坏,一直无法修复。还是非常感谢电子森林,能让自己接触到更多优秀的产品。

附件下载
GPIO.zip
团队介绍
单片机业余爱好者,瞎捣鼓小能手。
团队成员
aramy
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号