内容介绍
内容介绍
一、项目简介
1.1 项目背景
本项目基于Analog Devices(原Maxim Integrated)的MAX32690EVKIT开发板,利用MaximSDK软件平台,实现了一个按键控制LED闪烁频率的嵌入式应用示例。该项目展示了嵌入式系统中常见的人机交互功能:通过按键的短按和长按操作,实现对LED闪烁状态的开关控制以及闪烁频率的连续调节。
1.2 硬件平台
- 主控芯片: MAX32690(ARM Cortex-M4内核,32-bit MCU)
- 开发板: MAX32690EVKIT(Evaluation Kit)
- 外设资源: 板载LED(红色LED_RED)、板载按键(PB0)、UART串口
1.3 软件平台
- SDK: MaximSDK(Analog Devices MSDK)
- 编译器: ARM GCC(arm-none-eabi-gcc 10.3)
- 构建工具: GNU Make
二、项目介绍
2.1 功能概览
功能 | 按键操作 | 实现效果 |
|---|---|---|
LED闪烁开关 | 短按按键(<500ms) | 切换LED闪烁开启/关闭状态 |
频率正向调节 | 长按按键(>500ms) | LED闪烁频率从1Hz线性增加到5Hz |
频率反向调节 | 保持长按 | 到达5Hz后自动反向,从5Hz降低到1Hz |
循环调节 | 持续长按 | 频率在1Hz~5Hz之间循环往复调节 |
调试信息输出 | 按键事件触发 | UART串口输出按键类型和当前频率信息 |
2.2 设计思路
2.2.1 按键处理设计
采用中断驱动+状态机的方式实现按键处理:
- 中断驱动: 使用GPIO中断检测按键的上升沿和下降沿,避免轮询占用CPU资源
- 状态机: 定义三个状态(空闲、按下、长按),通过状态转移实现短按/长按的区分
- 软件去抖: 设置20ms去抖延时,防止按键机械抖动引起的误触发
2.2.2 LED闪烁设计
采用定时器中断实现LED闪烁:
- 定时器选择: 使用TMR0定时器,配置为连续计数模式
- 中断频率: 根据目标闪烁频率动态计算定时器周期
- 状态控制: 通过使能标志控制LED是否响应定时器中断
2.2.3 频率调节设计
采用时间间隔触发+方向反转的方式实现连续频率调节:
- 调节间隔: 每隔50ms微调一次频率,确保调节过程平滑
- 调节步长: 0.1Hz的小步长,避免频率跳变
- 边界反转: 到达频率边界(1Hz或5Hz)时自动反向调节
三、功能实现
3.1 软件流程图
3.1.1 系统初始化流程
3.1.2 按键处理流程
3.1.3 长按频率调节流程
3.2 软件代码实现
3.2.1 配置参数定义
#define LONG_PRESS_THRESHOLD 500 /* 长按判定阈值,单位:毫秒 */
#define DEBOUNCE_DELAY 20 /* 按键去抖延时,单位:毫秒 */
#define FREQ_MIN 1.0f /* LED闪烁频率最小值,单位:Hz */
#define FREQ_MAX 5.0f /* LED闪烁频率最大值,单位:Hz */
#define FREQ_STEP 0.1f /* 频率调节步长,单位:Hz */
#define FREQ_ADJUST_INTERVAL 50 /* 频率调节间隔,单位:毫秒 */
设计说明:
LONG_PRESS_THRESHOLD: 设置为500ms,是区分短按和长按的时间界限DEBOUNCE_DELAY: 设置为20ms,有效过滤按键机械抖动FREQ_MIN/MAX: 频率调节范围1Hz~5Hz,覆盖人眼可感知的闪烁频率范围FREQ_STEP: 设置为0.1Hz,确保频率变化平滑无跳变FREQ_ADJUST_INTERVAL: 设置为50ms,平衡调节响应速度和平滑度
3.2.2 按键状态机定义
typedef enum {
BTN_IDLE, /* 按键空闲状态 */
BTN_PRESSED, /* 按键已按下(等待判定短按/长按) */
BTN_LONG_PRESS /* 长按状态(持续调节频率) */
} btn_state_t;
状态转移说明:
BTN_IDLE → BTN_PRESSED: 按键按下且经过去抖延时BTN_PRESSED → BTN_LONG_PRESS: 按键按下时间超过长按阈值(500ms)BTN_PRESSED → BTN_IDLE: 按键释放且按下时间小于长按阈值(短按)BTN_LONG_PRESS → BTN_IDLE: 按键释放(长按结束)
3.2.3 毫秒级时间基准实现
volatile uint32_t ms_ticks = 0;
void SysTick_Handler(void)
{
ms_ticks++;
}
uint32_t Get_Ticks(void)
{
return ms_ticks;
}
实现说明:
- 使用ARM Cortex-M4内置的SysTick定时器
- 配置为1ms中断周期,提供精确的毫秒级时间基准
ms_ticks为全局volatile变量,确保中断和主循环访问的一致性
3.2.4 LED闪烁定时器实现
void LED_Blink_Handler(void)
{
MXC_TMR_ClearFlags(MXC_TMR0); /* 清除定时器中断标志 */
if (led_blink_enabled) { /* 仅在闪烁使能时切换LED */
LED_Toggle(LED_RED); /* 切换红色LED状态 */
}
}
void Set_LED_Frequency(float freq)
{
if (freq < FREQ_MIN) freq = FREQ_MIN;
if (freq > FREQ_MAX) freq = FREQ_MAX;
current_freq = freq;
MXC_TMR_Stop(MXC_TMR0);
MXC_TMR_Shutdown(MXC_TMR0);
mxc_tmr_cfg_t tmr;
uint32_t periodTicks = MXC_TMR_GetPeriod(MXC_TMR0, MXC_TMR_APB_CLK, 32, (uint32_t)(freq * 2));
tmr.pres = TMR_PRES_32;
tmr.mode = TMR_MODE_CONTINUOUS;
tmr.bitMode = TMR_BIT_MODE_32;
tmr.clock = MXC_TMR_APB_CLK;
tmr.cmp_cnt = periodTicks;
tmr.pol = 0;
MXC_TMR_Init(MXC_TMR0, &tmr, 0);
MXC_TMR_EnableInt(MXC_TMR0);
MXC_TMR_Start(MXC_TMR0);
}
实现说明:
- 使用TMR0定时器实现周期性中断
- 定时器配置为连续模式,32位计数,预分频系数32
freq * 2的原因:每个定时器周期切换一次LED状态,因此1Hz闪烁需要2Hz的中断频率
3.2.5 按键回调函数实现
void PB_Callback(void *pb)
{
uint32_t now = Get_Ticks();
if (PB_Get(0)) { /* 按键按下 */
if ((now - btn_press_time) > DEBOUNCE_DELAY) {
btn_state = BTN_PRESSED;
btn_press_time = now;
last_freq_update = now;
freq_direction = 1;
printf("Button pressed\n");
}
} else { /* 按键释放 */
if (btn_state == BTN_LONG_PRESS) {
btn_state = BTN_IDLE;
printf("Long press released, freq=%.1fHz\n", (double)current_freq);
} else if (btn_state == BTN_PRESSED) {
uint32_t press_duration = now - btn_press_time;
if (press_duration < LONG_PRESS_THRESHOLD) {
led_blink_enabled = !led_blink_enabled;
if (led_blink_enabled) {
printf("LED blink ON, freq=%.1fHz\n", (double)current_freq);
} else {
LED_Off(LED_RED);
printf("LED blink OFF\n");
}
}
btn_state = BTN_IDLE;
}
}
}
实现说明:
- 使用
PB_RegisterCallbackRiseFall注册回调,同时检测上升沿和下降沿 - 按键按下时记录时间戳,按键释放时计算按下时长判断短按/长按
- 通过
PB_Get(0)读取当前按键状态,确认按键的实际电平
3.2.6 主函数实现
int main(void)
{
printf("Button LED Frequency Control Example\n");
printf("Short press: Toggle LED blink on/off\n");
printf("Long press: Adjust blink frequency (1Hz->5Hz->1Hz)\n");
SysTick_Config(SystemCoreClock / 1000);
LED_Init();
PB_Init();
MXC_NVIC_SetVector(TMR0_IRQn, LED_Blink_Handler);
NVIC_EnableIRQ(TMR0_IRQn);
Set_LED_Frequency(current_freq);
PB_RegisterCallbackRiseFall(0, PB_Callback);
while (1) {
if (btn_state == BTN_PRESSED) {
uint32_t now = Get_Ticks();
uint32_t press_duration = now - btn_press_time;
if (press_duration >= LONG_PRESS_THRESHOLD && btn_state != BTN_LONG_PRESS) {
btn_state = BTN_LONG_PRESS;
printf("Long press detected, adjusting frequency...\n");
}
}
if (btn_state == BTN_LONG_PRESS) {
uint32_t now = Get_Ticks();
if ((now - last_freq_update) >= FREQ_ADJUST_INTERVAL) {
float new_freq = current_freq + (FREQ_STEP * freq_direction);
if (new_freq >= FREQ_MAX) {
new_freq = FREQ_MAX;
freq_direction = -1;
} else if (new_freq <= FREQ_MIN) {
new_freq = FREQ_MIN;
freq_direction = 1;
}
if (new_freq != current_freq) {
Set_LED_Frequency(new_freq);
printf("Freq: %.1fHz\r", (double)current_freq);
}
last_freq_update = now;
}
}
MXC_Delay(MXC_DELAY_MSEC(1));
}
}
实现说明:
- 主循环采用非阻塞方式,通过状态机处理长按频率调节
- 每1ms检查一次按键状态,确保响应实时性
- 使用
\r回车符实现频率信息的实时覆盖显示
四、功能展示

4.1 UART输出示例
系统启动后,串口输出欢迎信息:
Button LED Frequency Control Example
Short press: Toggle LED blink on/off
Long press: Adjust blink frequency (1Hz->5Hz->1Hz)
短按按键:
Button pressed
LED blink ON, freq=1.0Hz
再次短按:
Button pressed
LED blink OFF
长按按键:
Button pressed
Long press detected, adjusting frequency...
Freq: 1.1Hz
Freq: 1.2Hz
...
Freq: 5.0Hz
Freq: 4.9Hz
...
Long press released, freq=3.5Hz
4.2 LED闪烁效果
操作 | LED状态 | 说明 |
|---|---|---|
系统上电 | 熄灭 | 默认关闭状态 |
短按按键 | 1Hz闪烁 | 开启闪烁,默认频率1Hz |
长按按键 | 频率逐渐增加 | 从1Hz线性增加到5Hz |
继续长按 | 频率逐渐降低 | 到达5Hz后反向降低到1Hz |
再次短按 | 停止闪烁 | 关闭LED |

五、总结
本项目成功实现了基于MAX32690EVKIT的按键控制LED闪烁频率功能。代码编译成功,无错误和警告,占用资源极少,可直接下载到MAX32690EVKIT开发板上运行测试。
- 按键短按识别: 成功识别短按事件(<500ms),实现LED闪烁开关控制
- 按键长按识别: 成功识别长按事件(>500ms),实现频率连续调节
- 频率循环调节: 频率在1Hz~5Hz之间平滑循环调节,到达边界自动反向
- 软件去抖: 20ms去抖延时,有效防止按键抖动误触发
- UART调试: 完整的调试信息输出,便于功能验证
附件下载
Funpack_5-3.zip
项目源码
团队介绍
业余电子爱好者
团队成员
鲜de芒果
评论
0 / 100
查看更多
猜你喜欢
Funpack5-3 - 基于MAX32690EVKIT的按键控制LED闪烁该项目使用了Analog Devices MAX32690 微控制器的 GPIO 模块和硬件定时器中断,实现了双模式 LED 控制的设计,它的主要功能为:通过一个按键同时控制两个 LED —— 第一个 LED 实时跟随按键状态(按下亮、松手灭);第二个 LED 通过按键切换工作状态(常灭 ↔ 以1HZ闪烁)。。
知足常乐
28
Funpack5-3 - 基于MAX32690EVKIT实现按键控制LED闪烁该项目使用了ADI的评估套件MAX32690EVKIT,实现了按键控制LED闪烁的设计,它的主要功能为:单次按键 → LED开始闪烁;再次按键 → LED停止闪烁。
子午鼠
29
Funpack5-3 - 基于 MAX32690EVKIT 实现 SW2 按键控制 LED 闪烁该项目使用了MAX32690EVKIT 评估套件,实现了按键控制 LED 闪烁的设计,它的主要功能为:外部中断的形式检测按键按下,并进行一定消抖后控制led闪烁。
BOBOEMS
25


