【CanMV K210】基础实验 轻触按键输入与双色 LED 切换
在智能硬件项目中按键和 LED 是最常见的一组交互组合。按键负责接收外部输入LED 负责给出状态反馈。开发板上的一次按下动作经过 GPIO 输入检测、中断触发、状态判断和输出控制后会转化成真实可见的灯光变化。这类实验看起来简单却包含了硬件编程中非常核心的输入、输出和事件响应思想。本实验使用 CanMV K210 开发板控制一个双色 LED 模块和一个轻触按键。程序运行后双色 LED 默认显示红色每按下一次轻触按键LED 会在红色和绿色之间切换。代码中使用 GPIO 输出控制红色 LED 与绿色 LED使用 GPIO 输入读取按键状态并通过下降沿中断捕捉按键按下动作。为了避免机械按键抖动造成多次误触发程序还加入了 200 毫秒的软件消抖判断。学习目标说明理解 GPIO 输入输出掌握按键输入和 LED 输出之间的基本控制关系掌握 FPIOA 映射理解物理 IO、GPIO 功能和代码变量之间的对应关系学会 GPIO 中断使用下降沿中断捕捉按键按下瞬间理解按键消抖认识机械按键抖动问题并通过时间间隔过滤误触发建立事件处理思路将中断检测和主循环处理拆开提高程序稳定性这个实验的重点不只是“按一下灯变色”而是理解输入事件如何影响输出状态。按键是输入端双色 LED 是输出端中断函数负责记录事件主循环负责处理事件。后续的按键控制蜂鸣器、按键切换菜单、按键确认任务、传感器触发报警等实验都可以复用这种事件处理结构。文章目录理论基础硬件设施软件代码扩展应用总结理论基础GPIO 实验通常可以分成两类一类是输出控制例如点亮 LED、控制蜂鸣器、驱动继电器另一类是输入检测例如读取按键、检测开关状态、判断传感器数字输出。本实验同时包含输入和输出双色 LED 由 GPIO 输出控制轻触按键由 GPIO 输入检测。普通轮询读取按键时程序需要不断在主循环中读取按键电平。如果主循环中还有其他任务按键按下的瞬间可能被错过。中断机制可以解决这个问题。程序提前告诉 GPIO当按键引脚出现指定电平变化时自动触发回调函数。这样按键动作就不再依赖主循环反复读取而是像事件一样通知程序。本实验中的轻触按键使用上拉输入。未按下时引脚保持高电平按下后引脚被拉到低电平。因此按键按下瞬间对应的是从高电平变成低电平也就是下降沿。程序使用GPIO.IRQ_FALLING捕捉这个下降沿再通过中断回调函数记录一次按键事件。轻触按键未按下为高电平按下瞬间IO6 变为低电平GPIOHS0 输入中断下降沿触发button_irq_handler消抖判断并记录事件button_event True交给主循环处理toggle_led_color切换当前颜色状态GPIO0 / GPIO1 输出控制双色 LED显示结果红灯 / 绿灯切换软件消抖DEBOUNCE_MS 200状态变量current_color这张流程图展示的是按键控制双色 LED 的事件链路。按键按下后IO6 产生下降沿GPIOHS0 捕捉到变化后进入中断回调中断函数只负责消抖和记录事件主循环检测到事件后再执行 LED 颜色切换。这样做的好处是中断函数保持简短业务逻辑放在主循环中处理程序更清晰也更便于后续扩展。机械按键还存在抖动问题。一次真实按下动作在电气信号上可能表现为短时间内多次高低电平跳变。如果没有消抖处理程序可能把一次按下误判成多次按下。本实验使用time.ticks_ms()获取当前时间再用time.ticks_diff()计算两次有效按下之间的间隔。只有间隔大于DEBOUNCE_MS时才认为这是一次新的有效按键事件。硬件设施本实验围绕轻触按键和双色 LED 展开。双色 LED 的红色控制端和绿色控制端分别接到不同 IO 引脚由程序输出高低电平控制亮灭。轻触按键接入输入引脚通过上拉输入方式保持默认高电平按下时变为低电平。代码没有使用 LCD、摄像头、蜂鸣器、传感器等模块因此这些硬件不作为本节重点。接线关系可以先通过下面这张图建立整体印象。实验重点关注 IO7、IO8、IO6 三个连接点IO7 连接红色 LED 控制端IO8 连接绿色 LED 控制端IO6 连接轻触按键 S 端。硬件 / 软件作用说明CanMV / K210 开发板实验运行平台负责执行 MicroPython 程序并通过 GPIO 完成输入检测和输出控制双色 LED 模块状态显示对象红色 LED 和绿色 LED 分别由两个 GPIO 输出端控制轻触按键外部输入对象按下时触发 GPIO 电平变化用于切换 LED 颜色IO7红色 LED 控制引脚根据代码配置为 GPIO0 输出用于控制红色 LEDIO8绿色 LED 控制引脚根据代码配置为 GPIO1 输出用于控制绿色 LEDIO6按键输入引脚根据代码配置为 GPIOHS0 输入用于捕捉按键下降沿中断maix.GPIOGPIO 控制模块用于创建输入、输出对象并设置电平或读取电平fpioa_manager.fm引脚映射模块用于把物理 IO 引脚注册成指定 GPIO 功能time时间控制模块用于获取毫秒时间、计算时间差和控制主循环延时实验中用到的核心模块如下。双色 LED 用来显示当前状态轻触按键用来触发状态变化CanMV K210 负责运行程序并完成输入输出控制。这个实验不需要复杂外设但对接线顺序和电平逻辑比较敏感。接线关系来自代码中的硬件连接说明和fm.register()映射。红色 LED 控制端连接 IO7绿色 LED 控制端连接 IO8轻触按键 S 端连接 IO6。由于代码中使用的是双色 LED 常见的低电平点亮方式所以LED_ON_LEVEL 0LED_OFF_LEVEL 1。按键使用上拉输入未按下时为高电平按下时为低电平。物理引脚GPIO 功能代码变量对应硬件说明IO7GPIO0red_led红色 LED 控制端输出低电平时红色 LED 点亮IO8GPIO1green_led绿色 LED 控制端输出低电平时绿色 LED 点亮IO6GPIOHS0button轻触按键 S 端使用上拉输入按下时产生下降沿GND公共地线无LED / 按键模块地线保证输入输出电平有统一参考VCC模块供电无LED / 按键模块供电端根据模块标识连接对应供电端完成接线后的整体效果如下。检查时重点看三处双色 LED 的红绿控制端是否分别接到 IO7 和 IO8轻触按键 S 端是否接到 IO6模块供电和 GND 是否连接正确。程序运行后默认红色 LED 亮起每按下一次按键红绿状态切换一次。实验现象正常表现异常提示程序启动默认红色 LED 亮起红灯不亮时检查 IO7、LED 电平逻辑和模块供电按下一次按键LED 从红色切换为绿色无反应时检查 IO6、按键 S 端和上拉输入再按一次按键LED 从绿色切换回红色若方向不符合预期检查红绿 LED 控制端是否接反快速按键程序按消抖规则过滤误触发一次按下切换多次时适当增大DEBOUNCE_MS程序停止进入停止分支后关闭双色 LED异常退出时 LED 可能保持当前状态软件代码本实验代码围绕 GPIO 输入、GPIO 输出和中断事件处理展开。程序将 IO7、IO8 注册为普通 GPIO 输出用于控制双色 LED将 IO6 注册为 GPIOHS0 输入用于接收轻触按键的下降沿中断。按键触发后程序不会在中断函数里直接执行复杂逻辑而是先记录一次按键事件再由主循环完成 LED 颜色切换。软件环境作用检查重点CanMV IDE编辑、运行和调试 K210 程序能识别开发板串口并能正常运行基础测试程序CanMV 固件提供maix.GPIO、fpioa_manager等模块固件环境需要支持当前 GPIO 与 FPIOA 写法USB 串口驱动让电脑识别开发板串口串口工具或 IDE 中能看到对应端口串口终端查看程序运行日志能看到实验启动和颜色切换提示maix.GPIOGPIO 输入输出控制创建 LED 输出对象和按键输入对象fpioa_manager.fm引脚功能映射将 IO7、IO8、IO6 映射到对应 GPIO 功能time时间与延时控制用于按键消抖和主循环延时#!/usr/bin/env python3# -*- coding: utf-8 -*- CanMV K210 轻触按键控制双色 LED 实验 Demo 实验说明 按下轻触按键后双色 LED 在红色和绿色之间切换。 本实验主要练习 GPIO 输入、GPIO 输出、中断触发、按键消抖和状态切换。 硬件连接 红色 LED 控制端 - IO7 绿色 LED 控制端 - IO8 轻触按键 S 端 - IO6 importtimefrommaiximportGPIOfromfpioa_managerimportfm# # 硬件配置区# RED_LED_PIN7GREEN_LED_PIN8BUTTON_PIN6RED_LED_GPIOfm.fpioa.GPIO0 GREEN_LED_GPIOfm.fpioa.GPIO1 BUTTON_GPIOfm.fpioa.GPIOHS0# 双色 LED 模块常见为低电平点亮LED_ON_LEVEL0LED_OFF_LEVEL1# 按键使用上拉输入未按下为 1按下为 0BUTTON_PRESS_LEVEL0# 按键消抖时间单位毫秒DEBOUNCE_MS200# # 全局状态# red_ledNonegreen_ledNonebuttonNonecurrent_colorredbutton_eventFalselast_press_time0# # 初始化函数# defsetup():初始化 GPIOglobalred_led,green_led,button fm.register(RED_LED_PIN,RED_LED_GPIO,forceTrue)fm.register(GREEN_LED_PIN,GREEN_LED_GPIO,forceTrue)fm.register(BUTTON_PIN,BUTTON_GPIO,forceTrue)red_ledGPIO(GPIO.GPIO0,GPIO.OUT)green_ledGPIO(GPIO.GPIO1,GPIO.OUT)buttonGPIO(GPIO.GPIOHS0,GPIO.IN,GPIO.PULL_UP)# 默认显示红色set_red()# 下降沿触发按键从未按下的高电平变成按下的低电平button.irq(button_irq_handler,GPIO.IRQ_FALLING)print(按键控制双色 LED 实验启动)print(当前状态红灯亮起)# # LED 控制函数# defled_all_off():关闭双色 LEDred_led.value(LED_OFF_LEVEL)green_led.value(LED_OFF_LEVEL)defset_red():显示红色globalcurrent_color red_led.value(LED_ON_LEVEL)green_led.value(LED_OFF_LEVEL)current_colorreddefset_green():显示绿色globalcurrent_color red_led.value(LED_OFF_LEVEL)green_led.value(LED_ON_LEVEL)current_colorgreendeftoggle_led_color():切换双色 LED 状态ifcurrent_colorred:set_green()print(按键触发切换为绿色)else:set_red()print(按键触发切换为红色)# # 按键中断函数# defbutton_irq_handler(pin): 按键中断回调函数 注意 中断函数里只记录事件不直接执行复杂逻辑。 真正的 LED 切换放到主循环中处理。 globalbutton_event,last_press_time nowtime.ticks_ms()iftime.ticks_diff(now,last_press_time)DEBOUNCE_MS:ifpin.value()BUTTON_PRESS_LEVEL:button_eventTruelast_press_timenow# # 主循环# defloop():主循环检测按键事件并切换 LEDglobalbutton_eventwhileTrue:ifbutton_event:button_eventFalsetoggle_led_color()time.sleep_ms(20)# # 程序入口# if__name____main__:try:setup()loop()exceptKeyboardInterrupt:led_all_off()print(程序已停止双色 LED 已关闭)这段程序可以分成配置区、状态区、初始化函数、LED 控制函数、按键中断函数和主循环。配置区集中保存引脚、电平规则和消抖时间状态区保存当前 LED 颜色和按键事件标记初始化函数负责建立 FPIOA 映射、创建 GPIO 对象并设置中断LED 控制函数负责红绿灯状态切换中断函数只负责记录有效按键事件主循环负责真正执行颜色切换。代码中LED_ON_LEVEL 0和LED_OFF_LEVEL 1表示双色 LED 采用低电平点亮逻辑。如果实际模块是高电平点亮只需要调整这两个常量。BUTTON_PRESS_LEVEL 0表示按键按下时为低电平这与GPIO.PULL_UP和GPIO.IRQ_FALLING的使用方式一致。DEBOUNCE_MS 200用于过滤短时间内的重复触发避免一次按下被识别成多次切换。函数名功能对应现象setup()初始化引脚映射、GPIO 对象、默认灯光和按键中断程序启动后红色 LED 默认亮起按键进入可触发状态led_all_off()关闭红色和绿色 LED程序停止或需要清空状态时双色 LED 全部熄灭set_red()点亮红色 LED关闭绿色 LED双色 LED 显示红色set_green()关闭红色 LED点亮绿色 LED双色 LED 显示绿色toggle_led_color()根据当前颜色切换 LED 状态每按下一次按键LED 在红色和绿色之间切换button_irq_handler(pin)按键中断回调完成消抖和事件记录按键按下时记录一次有效切换事件loop()主循环检测按键事件并执行颜色切换程序持续运行等待按键触发 LED 改变颜色这个实验中的关键设计是“中断函数只记录事件不直接处理复杂业务”。按键按下时中断回调函数判断是否满足消抖条件满足后只把button_event设置为True。主循环检测到这个标记后再调用toggle_led_color()切换 LED。这样可以避免在中断环境中执行较复杂的输出逻辑也方便后续把 LED 切换替换成蜂鸣器提示、屏幕刷新或模式切换。扩展应用按键控制 LED 的实验容易出现灯不亮、按键无反应、一次按下切换多次等情况。排查时应围绕供电、接线、电平规则、GPIO 映射、中断触发方式和消抖参数进行确认不需要把问题扩大到无关模块。问题现象可能原因处理思路红色和绿色 LED 都不亮供电异常、LED 接线错误、低电平点亮规则不匹配检查开发板供电和双色 LED 接线确认LED_ON_LEVEL与实际模块点亮电平一致默认状态不是红灯亮起红绿 LED 控制端接反或 LED 模块电平逻辑不同核对 IO7、IO8 与双色 LED 红绿通道的连接必要时交换变量或调整电平常量按键按下没有反应IO6 接线错误、按键没有接到 S 端、GPIOHS0 映射不正确检查BUTTON_PIN 6是否对应实际按键连接位置确认按键按下时电平会变成 0一次按下切换多次机械按键抖动较明显消抖时间偏短适当增大DEBOUNCE_MS例如从 200 调整到 300按键松开时才触发按键电路电平变化方向与代码设置不一致当前代码使用下降沿触发如现象不一致需要重新确认上拉、下拉和触发边沿程序停止后 LED 仍保持点亮程序异常退出没有执行清理逻辑手动执行led_all_off()或重新运行程序后正常停止按键偶尔无响应按下时间过短、接线松动或消抖时间过长检查按键接线适当调整DEBOUNCE_MS红绿切换顺序混乱状态变量与实际 LED 接线不一致检查current_color、set_red()、set_green()和实际红绿通道连接按键控制双色 LED 的实验不只是一个简单开关案例它对应了智能硬件中常见的“输入触发状态变化”模型。按键相当于外部事件入口LED 相当于状态反馈出口程序负责把按键动作转换成设备状态变化。这个模式可以扩展到模式切换、菜单选择、设备启动确认、异常状态提示和教学交互演示等场景。应用场景实现思路可扩展能力设备模式切换每按下一次按键切换一种运行状态并用不同颜色 LED 显示当前模式可扩展为多色 LED、RGB 灯或屏幕状态显示启动确认提示开机默认红灯按键确认后切换绿灯表示设备进入工作状态可扩展为设备初始化流程中的人工确认环节异常状态复位红灯表示异常按键触发后执行复位逻辑成功后显示绿灯后续可结合蜂鸣器形成声光反馈教学交互实验使用按键触发变量变化使用 LED 显示变量状态适合讲解输入、输出、中断、状态变量和条件判断调试状态标记按键触发不同调试模式LED 颜色显示当前调试阶段可扩展为多按键、多状态的硬件调试面板简单人机交互按键负责输入指令双色 LED 负责显示反馈结果后续可扩展 LCD、传感器或网络通信模块按键控制蜂鸣器按键中断记录事件主循环控制蜂鸣器提示音可形成声音反馈实验按键切换屏幕页面按键事件切换页面编号LCD 显示不同内容可作为菜单系统基础从工程结构看这段代码已经具备较好的扩展基础。硬件引脚、电平规则和消抖时间集中放在配置区LED 控制逻辑被拆成set_red()、set_green()和toggle_led_color()按键中断只负责记录事件主循环负责处理状态切换。后续增加更多状态时可以继续围绕current_color或新的状态变量扩展而不需要推翻整段程序结构。总结本实验通过 CanMV K210 开发板完成了轻触按键控制双色 LED 的红绿切换核心能力包括 FPIOA 引脚映射、GPIO 输出、GPIO 上拉输入、下降沿中断、按键消抖、状态变量管理和主循环事件处理。代码把硬件连接关系转换成程序对象再把按键输入转化成 LED 输出变化完整展示了硬件交互程序从输入检测到状态反馈的基本流程。这类实验非常适合作为 GPIO 输入输出课程的过渡案例。LED 实验侧重输出控制按键实验开始引入外部输入中断机制又让程序从单纯循环执行变成事件驱动响应。理解这套结构后后续可以继续扩展到按键控制蜂鸣器、按键切换屏幕页面、传感器触发 LED 状态、摄像头识别结果反馈、AI 硬件交互控制等方向。硬件编程的核心并不是单个模块如何运行而是让输入、处理和输出形成稳定可靠的闭环。