立创·庐山派K230CanMV开发板的入门学习——GPIO和FPIOA

学习目标:立创·庐山派K230CanMV开发板的入门学习

第3课:立创·庐山派K230CanMV开发板的GPIO和FPIOA
2/2 :实践部分

学习内容:

5 点亮板载RGB灯

如果说学C语言的第一个程序是Hello world!,那么我们学习嵌入式板子的第一个程序就应该是点亮一个LED灯。RGB灯其实就是一种由三个LED灯组成的灯,由三个基本颜色的 LED 组成:红色、绿色和蓝色。通过调整这三种颜色的亮度,我们可以混合出几乎任何颜色,不过庐山派CanMV开发板的这个RGB灯为了节约多功能的IO,并没有连接到具有PWM功能的IO上,所以只能控制个LED灯的亮灭而改变不了亮度。初学时我们可以只点亮其中的一个灯。

5.1 LED 灯结构组成

LED 灯(发光二极管)是一种半导体光源,主要结构包括以下部分:

  • 外壳:通常由塑料或玻璃制成,用于保护内部元件。
  • 发光材料:LED 最核心的部分,由特殊半导体材料制成,例如:常见的 InGaN(氮化铟镓)或 AlInGaP(铝铟镓磷)。
  • 芯片:用于产生光的发光二极管芯片。
  • 引线:提供电连接的金属引线。
  • 焊点:将LED芯片与引线连接在一起的焊接点。
  • 电极:负责连接半导体材料与外部电路,通常由金属制成。
  • 反射腔:用于增强发光效果的一个结构,将发出的光反射到正面。

5.2 LED 灯发光原理
LED(发光二极管)发光原理基于半导体特性。在半导体中,存在着两类载流子:电子(n型半导体)和空穴(p型半导体)。当n型与p型半导体材料接触时,会在交界处形成一个层结。当施加适当的电压时,层结中空穴和电子可重组并释放能量。这个能量以光子的形式释放出来,产生光。

5.3 LED 灯驱动原理
LED 驱动指的是通过稳定的电源为 LED 提供合适的电流和电压,使其正常工作点亮。LED 驱动方式主要有恒流和恒压两种。限定电流的恒流驱动是最常见的方式,因为 LED 灯对电流敏感,电流大于其额定值可能导致损坏。恒流驱动保证了稳定的电流,从而确保了 LED 安全。 LED 灯的驱动比较简单,只需要给将对应的正负极接到单片机的正负极即可驱动。LED的接法也分有两种,灌入电流和输出电流。

TIP

在庐山派开发板中,我们使用的为共阳级的RGB灯,详情请看后面的原理图。

在这里插入图片描述

  • 灌入电流指的是LED的供电电流是由外部提供电流,将电流灌入我们的MCU。
  • 输出电流指的是由MCU提供电压电流,将电流输出给LED;如果使用 MCU的GPIO 直接驱动 LED,则驱动能力较弱,可能无法提供足够的电流驱动 LED。
  • 需要注意的是 LED灯的颜色不同,对应的电压也不同。电流不可过大,通常需要接入220欧姆到10K欧姆左右的限流电阻,限流电阻的阻值越大,LED的亮度越暗。

5.4 RGB灯原理图

结合之前介绍,我们已经知道了LED(发光二极管)灯通常只有一个发光二极管,它能产生单一颜色的光。比如,一个红色 LED 只会发出红光,而一个蓝色 LED 只会发出蓝光。而本庐山派开发板和泰山派一样,板载了一个RGB灯,他是红色、绿色和蓝色 LED 灯的组合,可以单独控制每个 LED 的亮灭。

那么我们先来看一下开发板上的RGB灯分别连接的是哪些引脚,看一下原理图:
在这里插入图片描述

这里的LED1就是我们需要控制的用户指示灯,结合左上角的短接符我们可以了解到以下信息:

  • 这是一个共阳级的RGB灯,当对应颜色引脚为低电平时对应引脚就会亮。
  • 这个RGB灯内部有三个不同颜色的灯珠,红灯,绿灯,蓝灯分别接到了GPIO62,GPIO20GPIO63上面。

5.5 基础点灯试验

接下来我们实现一个让RGB灯里面的红灯每1秒闪烁一次的程序:

from machine import Pin
from machine import FPIOA
import time

# 创建FPIOA对象,用于初始化引脚功能配置
fpioa = FPIOA()

# 设置引脚功能,将指定的引脚配置为普通GPIO功能,
fpioa.set_function(62,FPIOA.GPIO62)
fpioa.set_function(20,FPIOA.GPIO20)
fpioa.set_function(63,FPIOA.GPIO63)

# 实例化Pin62, Pin20, Pin63为输出,分别用于控制红、绿、蓝三个LED灯
LED_R = Pin(62, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 红灯
LED_G = Pin(20, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 绿灯
LED_B = Pin(63, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 蓝灯

# 板载RGB灯是共阳结构,设置引脚为高电平时关闭灯,低电平时点亮灯
# 初始化时先关闭所有LED灯
LED_R.high()  # 关闭红灯
LED_G.high()  # 关闭绿灯
LED_B.high()  # 关闭蓝灯

# 基础点灯试验:选择一个LED灯并让其闪烁
# 默认选择红色LED灯,后续可以通过变量改变需要控制的灯
LED = LED_R  # 当前控制的LED为红色LED

while True:
    LED.low()   # 点亮当前选择的LED
    time.sleep(0.5)  # 等待0.5秒
    LED.high()  # 熄灭当前选择的LED
    time.sleep(0.5)  # 等待0.5秒from machine import Pin

在上述程序中,首先从machine导入了 Pin 和FPIOA模块,用来初始化和控制K230的GPIO引脚,也导入了 time 模块,来调用时间延迟函数。

将对应LED灯的GPIO初始化为普通GPIO后实例化了这三个GPIO引脚,分别用于控制RGB灯的红、绿和蓝三种颜色的LED灯,都指定了对应的引脚号,输出模式,不使用上下拉,输出能力。

接下来初始化了LED灯的状态,通过让每个灯的控制引脚变为高电平来熄灭所有LED灯。

然后定义了一个变量 LED,初始设置为控制红色LED。这个小细节在后面可以轻松改变 LED 变量为其他颜色的灯(比如如 LED_G 或 LED_B),就可以控制不同的RGB颜色来闪烁了。

比如这里改成LED_G,那点亮的就是绿色LED灯了:

LED = LED_G  # 那当前控制的LED为绿色LED

改成LED_B,那点亮的就是蓝色LED了:

LED = LED_B  # 那当前控制的LED为蓝色LED

最后就是一段无限循环的代码,来控制LED变量所选RGB颜色的闪烁效果。首先用LED.low()方法点亮,然后使用time.sleep(0.5)延时0.5秒,再通过 LED.high() 熄灭LED,再次等待0.5秒后继续循环。

5.6 点亮7种不同颜色的RGB灯

接下来我们实现一个让RGB灯组合成七种不同的颜色然后每1秒闪烁一次的程序:

from machine import Pin
from machine import FPIOA
import time

# 创建FPIOA对象,用于初始化引脚功能配置
fpioa = FPIOA()

# 设置引脚功能,将指定的引脚配置为普通GPIO功能,
fpioa.set_function(62,FPIOA.GPIO62)
fpioa.set_function(20,FPIOA.GPIO20)
fpioa.set_function(63,FPIOA.GPIO63)

# 实例化Pin62, Pin20, Pin63为输出,分别控制红、绿、蓝灯
LED_R = Pin(62, Pin.OUT, pull=Pin.PULL_NONE, drive=7)
LED_G = Pin(20, Pin.OUT, pull=Pin.PULL_NONE, drive=7)
LED_B = Pin(63, Pin.OUT, pull=Pin.PULL_NONE, drive=7)

def set_color(r, g, b):
    """设置RGB灯的颜色,使用Pin.high()和Pin.low()控制"""
    if r == 0:
        LED_R.low()  # 红灯亮
    else:
        LED_R.high()  # 红灯灭

    if g == 0:
        LED_G.low()  # 绿灯亮
    else:
        LED_G.high()  # 绿灯灭

    if b == 0:
        LED_B.low()  # 蓝灯亮
    else:
        LED_B.high()  # 蓝灯灭

def blink_color(r, g, b, delay):
    """设置颜色并让灯亮一段时间后熄灭"""
    set_color(r, g, b)  # 设置颜色
    time.sleep(delay)   # 保持该颜色一段时间
    set_color(1, 1, 1)  # 熄灭所有灯(共阳:1为熄灭)
    time.sleep(delay)   # 熄灭后等待一段时间

while True:
    # 红色
    blink_color(0, 1, 1, 0.5)
    # 绿色
    blink_color(1, 0, 1, 0.5)
    # 蓝色
    blink_color(1, 1, 0, 0.5)
    # 黄色(红+绿)
    blink_color(0, 0, 1, 0.5)
    # 紫色(红+蓝)
    blink_color(0, 1, 0, 0.5)
    # 青色(绿+蓝)
    blink_color(1, 0, 0, 0.5)
    # 白色(红+绿+蓝)
    blink_color(0, 0, 0, 0.5)

前面和基础点灯试验重复的地方就不再赘述,不同的是这里实现了一个设置颜色的函数set_color(r, g, b),它用于设置 RGB 灯内部的三个LED的颜色。接受三个参数 r、g 和 b,分别代表红、绿、蓝灯的状态(0 为亮,1 为灭)。函数内部通过判断每个参数的值来控制对应 LED 灯的状态。使用 Pin.low() 让对应的灯亮,用 Pin.high() 使对应的灯灭,实现了三种颜色的灵活配置。

然后定义了一个让对应RGB颜色闪烁的函数blink_color(r, g, b, delay),它先设置所需的颜色,然后让 LED 灯保持亮起一段设定时间(通过 delay 参数调整)。然后,调用 set_color 函数将所有灯熄灭(因为我们庐山派板子上的RGB灯为共阳结构,熄灭时三个灯都设置为高电平),防止影响下一个颜色,再在熄灭状态下等待一段时间。

接下来就到无限循环了,依次调用blink_color 函数,使 板载RGB 灯以不同的颜色闪烁。

6 使用用户按键

TODO:待更新实际开发板的照片,标识出用户按键的位置

6.1 独立按键是什么
独立按键是一种简单的输入设备,广泛应用于各种电子设备中,用于实现基本的用户交互。它们的工作原理通常基于一个简单的机械开关,当按下按键时触发某些操作。独立按键可以有多种尺寸、形状和颜色,便于用户辨识和使用。

6.2 独立按键结构组成
独立按键的主要结构组成包括:按钮、外壳、弹簧、触点、导电片和引脚。由一个弹性体(如弹簧或金属片)和一个按键帽组成。当按键被用户按下时,弹性体会缩短,使按键帽压缩,使按钮顶部变得接近或触摸基底。当用户松开按钮时,弹性体恢复原状,按键返回初始位置。所以当按键未被按下时,通常触点是分开的,电路是断开的。当按下按在这里插入图片描述
键时,导电片触碰到触点,从而形成一个闭合电路。常见按键原理图示意如下:

6.3 独立按键驱动原理
独立按键驱动是为了让微控制器能识别按键的状态,而微控制器正好可以识别高电平和低电平,所以大多数的按键都是通过给按键的一端接入高电平,一端接入GPIO;或者是给按键的一端接入低电平,一端接入GPIO。通过检测连接按键的引脚有没有发生电平变化,就可以知道按键是否按下。

6.4 消抖措施
我们通常用的按键内部都是机械弹性开关,当它按下或者弹起的时候,机械触点会因为弹性作用而在闭合和断开的瞬间伴随着一连串的抖动。这种抖动会导致输入信号在高低电位之间弹跳,产生不正确的输入。这就是按键抖动现象。消抖措施主要分为软件消抖和硬件消抖:

  1. 软件消抖:主要是通过编程的方法,设定一个延迟或计时器,确保不读取按键在抖动状态时的电平,避免抖动对程序的影响。
  2. 硬件RC消抖:在按键电路中加入元器件如电阻、电容组成的RC滤波器,对按键信号进行平滑处理,降低抖动的影响。注意硬件消抖只能改善而不能消除抖动(除非你用比较大的电容,但那样会导致上升沿太缓,也会造成按钮反应时间太长)。同时,如果你只用一个电容直接并联在按键两端,当按键按下时,按键相当于短路了这个电容,但是按钮的电阻又很小,就会有很大的放电电流,造成按钮机械接触点加速老化,从而导致按钮寿命极具减少。所以这个电路的设计需要下一些功夫,一般来说即使你的硬件电路中做了硬件消抖,也是需要软件消抖来配合的。
  3. 硬件RS触发器消抖:成本极高,每个按钮都需要单独的RS电路,这里不过多介绍,想详细理解请从逻辑门电路开始。
    请添加图片描述

TIP

在本庐山派开发板中,按键部分的电路很简单(如下面的原理图所示),没有使用硬件消抖,所以在需要使用按钮来进行状态切换功能时需要进行软件消抖处理。

6.5 板载独立按键原理图
请添加图片描述
开发板原理图中,将按键一端(1号引脚)通过电阻R78接到3.3V的高电平上,另一端(2号引脚)接到K230芯片的引脚GPIO53上,3号引脚和4号引脚是我们板载侧按按钮的固定角,没有电气作用,只是用来固定按键的。这样当按键按下时,1号引脚和2号引脚就会导通,GPIO53的电平就会变为3.3V。

这里面电阻(R78)的作用是限流(害怕初学者不小心给设置成推挽输出了)。

在这里要注意的是要在芯片内部将该GPIO(GPIO53)设置为下拉输入模式,这样当按钮没被按下时,引脚为默认的低电平状态。

6.6 按键控制板载RGB灯亮灭

当用户按下用户按键时关闭对应的LED灯

from machine import Pin
from machine import FPIOA
import time

# 创建FPIOA对象,用于初始化引脚功能配置
fpioa = FPIOA()

# 设置引脚功能,将指定的引脚配置为普通GPIO功能,
fpioa.set_function(62,FPIOA.GPIO62)
fpioa.set_function(20,FPIOA.GPIO20)
fpioa.set_function(63,FPIOA.GPIO63)
fpioa.set_function(53,FPIOA.GPIO53)

# 实例化Pin62, Pin20, Pin63为输出,分别用于控制红、绿、蓝三个LED灯
LED_R = Pin(62, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 红灯
LED_G = Pin(20, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 绿灯
LED_B = Pin(63, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 蓝灯

# 按键引脚为53,按下时为高电平,所以这里设置为下拉并设置为输入模式
button = Pin(53, Pin.IN, Pin.PULL_DOWN)  # 使用下拉电阻

# 板载RGB灯是共阳结构,设置引脚为高电平时关闭灯,低电平时点亮灯
# 初始化时先关闭所有LED灯
LED_R.high()  # 关闭红灯
LED_G.high()  # 关闭绿灯
LED_B.high()  # 关闭蓝灯

# 基础控制RGB灯亮灭试验:选择一个LED灯并让其闪烁
# 默认选择红色LED灯,后续可以通过变量改变需要控制的灯
LED = LED_R  # 当前控制的LED为红色LED

while True:
    if button.value() == 1:
        LED.high()
    else:
        LED.low()

前半部分和我们在前面学习的点亮RGB灯是一样的,就是初始化灯对应的引脚。不同的是我们这里还对按键用到的GPIO(Pin53)进行了初始化,引脚62、20和63将用于控制LED灯,而引脚53将用于读取按钮的状态,将控制LED灯的引脚设置为了输出模式,将读取按钮的GPIO设置为了输入模式。

然后把按钮配置为了下拉输入模式,代表当按钮没有被按下是,输入信号为低电平(0),按下时为高电平(1)。

由于板载的LED灯是共阳结构,这里设置引脚为高电平从而所有LED灯熄灭。

接下来就到主循环了,通过不断检查按钮对应GPIO的状态来控制LED的开关,如果按钮被按下(button.value() 为 高电平(1)),LED会被设置为高电平,即熄灭。如果按钮未被按下,则LED会被设置为低电平,即点亮。

可以看到我们这里并没有进行按键消抖处理,这里按钮的作用是直接控制LED灯的熄灭,而不是在不同状态之间切换。当我们按下按钮时,LED灯熄灭;而当我们释放按钮时,LED灯将再次点亮。在上面的程序中,我们关注的是按钮是否被按下(按下就熄灭LED灯),而不是按钮有没有改变状态。如果我们需要判断按钮的改变状态来切换LED灯状态,就必须要进行消抖处理了,详情请看下面的程序。

6.7 用按键切换RGB灯状态

# 立创·庐山派-K230-CanMV开发板资料与相关扩展板软硬件资料官网全部开源
# 开发板官网:www.lckfb.com
# 技术支持常驻论坛,任何技术问题欢迎随时交流学习
# 立创论坛:www.jlc-bbs.com/lckfb
# 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
# 不靠卖板赚钱,以培养中国工程师为己任

from machine import Pin
from machine import FPIOA
import time

# 创建FPIOA对象,用于初始化引脚功能配置
fpioa = FPIOA()

# 设置引脚功能,将指定的引脚配置为普通GPIO功能,
fpioa.set_function(62,FPIOA.GPIO62)
fpioa.set_function(20,FPIOA.GPIO20)
fpioa.set_function(63,FPIOA.GPIO63)
fpioa.set_function(53,FPIOA.GPIO53)

# 实例化Pin62, Pin20, Pin63为输出,分别控制红、绿、蓝三个LED灯
LED_R = Pin(62, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 红灯
LED_G = Pin(20, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 绿灯
LED_B = Pin(63, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 蓝灯

# 按键引脚为53,按下时高电平,设置为输入模式
button = Pin(53, Pin.IN, Pin.PULL_DOWN)  # 使用下拉电阻

# 初始选择控制红灯
LED = LED_R  # 默认控制红灯

# 初始化时关闭所有LED灯(共阳:高电平时为灭灯)
LED_R.high()
LED_G.high()
LED_B.high()

# 消抖时间设置为20毫秒
debounce_delay = 20  # 毫秒
last_press_time = 0  # 上次按键按下的时间,单位为毫秒

# 记录LED当前状态,True表示亮,False表示灭
led_on = False

# 记录按键状态,用于检测按下和松开的状态变化
button_last_state = 0  # 上次按键状态

# 主循环
while True:
    button_state = button.value()  # 获取当前按键状态
    current_time = time.ticks_ms()  # 获取当前时间(单位:毫秒)

    # 检测按键从未按下(0)到按下(1)的变化(上升沿)
    if button_state == 1 and button_last_state == 0:
        # 检查按键是否在消抖时间外
        if current_time - last_press_time > debounce_delay:
            # 切换LED的状态
            if led_on:
                LED.high()  # 熄灭LED
            else:
                LED.low()   # 点亮LED

            led_on = not led_on  # 反转LED状态
            last_press_time = current_time  # 更新按键按下时间

    # 更新上次按键状态
    button_last_state = button_state

    # 简单延时,防止主循环过于频繁
    time.sleep_ms(10)

前半部分和【按键控制板载RGB灯亮灭】一样,这里不再赘述。

不同的是,在该程序中引入了按键消抖处理,以及通过按钮状态的变化来控制LED灯的亮灭切换,和前面的代码相比,不只是简单地根据按钮的按下与否来控制LED的亮灭,而是实现了按键状态的变化检测。

在这个程序中我们设置按钮的消抖时间为20毫秒,然后创建了几个变量来辅助进行状态记录,last_press_time用来记录上次按键按下的时间,单位为毫秒;led_on用来记录LED灯的亮灭状态;button_last_state用来记录上次检查按钮时的按键状态。

接下来就是主循环了,首先获取当前按钮状态和时间。如果按钮的状态从未按下(0,低电平)变为按下(1,高电平),且在消抖延迟后,程序将切换LED的状态(点亮或熄灭),然后更新LED当前状态和最后按键按下的时间。

这个程序最重要的改进就是进行了按键的消抖,确保每次按钮的状态变化都有效,避免由于机械抖动造成的错误信号。

参考资料:

1. 2.6 Pin 模块 API 手册 — CanMV K230 (canaan-creative.com)
2. class Pin – control I/O pins — MicroPython latest documentation

声明: 上述中关于立创・庐山派
K230-CanMV开发板的内容,均来源于立创开发板官方资料,包括但不限于硬件参数、功能特性、应用案例、开源资源等信息。
若您希望详细学习和了解立创・庐山派K230-CanMV开发板的更多技术细节、使用教程及相关资源,可访问立创开发板官方资料页面进行查阅,具体网址为:https://wiki.lckfb.com/zh-hans/lushan-pi-k230/


学习时间:7月20日

1.例程代码分析:

5.5 基础点灯试验

  1. 引脚功能配置(硬件抽象层操作)
# 创建FPIOA对象,用于初始化引脚功能配置
fpioa = FPIOA()

# 设置引脚功能,将指定的引脚配置为普通GPIO功能
fpioa.set_function(62, FPIOA.GPIO62)
fpioa.set_function(20, FPIOA.GPIO20)
fpioa.set_function(63, FPIOA.GPIO63)
  • 核心作用:K230 芯片的引脚是多功能的(可作为 GPIO、SPI、I2C 等),通过FPIOA(功能引脚复用控制器)将物理引脚绑定为GPIO 功能,为后续控制 LED 做准备。
  • 硬件映射:这里明确指定了物理引脚 62、20、63 分别映射为 GPIO62、GPIO20、GPIO63,建立了软件控制与硬件引脚的对应关系。
  1. LED 引脚初始化(输出模式配置)
# 实例化Pin对象为输出模式,分别控制红、绿、蓝LED
LED_R = Pin(62, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 红灯
LED_G = Pin(20, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 绿灯
LED_B = Pin(63, Pin.OUT, pull=Pin.PULL_NONE, drive=7)  # 蓝灯

参数解析:

  • Pin.OUT:设置为输出模式(可输出高低电平)
  • pull=Pin.PULL_NONE:无上下拉电阻(LED 控制无需上下拉)
  • drive=7:驱动强度设置为最大(确保能有效驱动 LED)

对象封装:通过Pin类实例化三个 LED 对象,将硬件操作抽象为软件对象,方便后续调用方法控制

  1. 初始状态设置(共阳 LED 特性适配)
# 板载RGB灯是共阳结构,高电平关闭,低电平点亮
LED_R.high()  # 关闭红灯
LED_G.high()  # 关闭绿灯
LED_B.high()  # 关闭蓝灯

硬件特性适配:共阳极 LED 的公共端接电源正极,因此:

  • 当 GPIO 输出high(高电平)时,LED 两端无电压差,灯熄灭
  • 当 GPIO 输出low(低电平)时,LED 两端形成电压差,灯点亮

初始安全状态:上电时默认关闭所有 LED,避免异常亮灯

  1. 主循环控制(闪烁逻辑实现)
while True:
    LED.low()   # 点亮当前选择的LED
    time.sleep(0.5)  # 保持点亮0.5秒
    LED.high()  # 熄灭当前选择的LED
    time.sleep(0.5)  # 保持熄灭0.5秒
  • 无限循环:while True确保程序持续运行,实现 LED 持续闪烁
  • 状态切换:通过low()和high()方法交替改变 GPIO 电平,控制 LED 的亮灭状态
  • 时序控制:time.sleep(0.5)控制每个状态的持续时间,实现 0.5 秒亮、0.5 秒灭的固定频率闪烁

核心逻辑总结
整个代码的核心是通过 “引脚功能映射→输出模式配置→电平状态控制” 的流程,将硬件操作转化为软件逻辑,最终实现 LED 的可控闪烁。其中对共阳极 LED 特性的适配(高电平灭、低电平亮)是关键的硬件知识结合点,而FPIOA的使用则体现了嵌入式系统中引脚复用的典型设计思路。

5.6 点亮7种不同颜色的RGB灯

  1. set_color(r, g, b) 函数(色彩设置核心)
def set_color(r, g, b):
    """设置RGB灯的颜色,使用Pin.high()和Pin.low()控制"""
    if r == 0:
        LED_R.low()  # 红灯亮
    else:
        LED_R.high()  # 红灯灭

    if g == 0:
        LED_G.low()  # 绿灯亮
    else:
        LED_G.high()  # 绿灯灭

    if b == 0:
        LED_B.low()  # 蓝灯亮
    else:
        LED_B.high()  # 蓝灯灭
  • 参数设计:通过r, g, b三个参数(0 或 1)分别控制红、绿、蓝三色灯的状态
    • 0 表示点亮对应颜色(输出低电平,适配共阳结构)
    • 1 表示熄灭对应颜色(输出高电平)
  • 核心逻辑:将硬件电平控制抽象为 “颜色开关” 逻辑,通过条件判断直接映射到low()/high()方法,简化了色彩控制的调用方式
  • 封装价值:屏蔽了底层 GPIO 操作细节,上层调用只需关注颜色组合,无需重复编写电平控制代码
  1. blink_color(r, g, b, delay) 函数(闪烁逻辑封装)
def blink_color(r, g, b, delay):
    """设置颜色并让灯亮一段时间后熄灭"""
    set_color(r, g, b)  # 设置颜色
    time.sleep(delay)   # 保持该颜色一段时间
    set_color(1, 1, 1)  # 熄灭所有灯(共阳:1为熄灭)
    time.sleep(delay)   # 熄灭后等待一段时间
  • 功能组合:将 “设置颜色→保持→熄灭→等待” 的闪烁流程封装为一个函数,实现了模块化复用
  • 参数作用:delay控制闪烁周期的一半(亮delay秒,灭delay秒),通过一个参数统一控制闪烁速度
  • 熄灭逻辑:set_color(1, 1, 1)利用三个 1 的组合,一次性熄灭所有 LED,避免重复调用三次high()
  1. 主循环色彩控制(混色逻辑实现)
while True:
    # 红色(只亮红灯)
    blink_color(0, 1, 1, 0.5)
    # 绿色(只亮绿灯)
    blink_color(1, 0, 1, 0.5)
    # 蓝色(只亮蓝灯)
    blink_color(1, 1, 0, 0.5)
    # 黄色(红+绿)
    blink_color(0, 0, 1, 0.5)
    # 紫色(红+蓝)
    blink_color(0, 1, 0, 0.5)
    # 青色(绿+蓝)
    blink_color(1, 0, 0, 0.5)
    # 白色(红+绿+蓝)
    blink_color(0, 0, 0, 0.5)
  • 三原色混色原理:通过控制三个基础色的亮灭组合,产生 7 种不同颜色:
    • 单色:红(0,1,1)、绿(1,0,1)、蓝(1,1,0)
    • 双色混合:黄(0,0,1)= 红 + 绿,紫(0,1,0)= 红 + 蓝,青(1,0,0)= 绿 + 蓝
    • 三色混合:白(0,0,0)= 红 + 绿 + 蓝
  • 循环执行:while True确保颜色按顺序循环闪烁,每个颜色亮灭各 0.5 秒,形成连续的色彩变化效果

核心逻辑总结
代码通过两层函数封装(set_color负责色彩设置,blink_color负责闪烁时序),将硬件操作与色彩逻辑分离,既保留了对底层的控制能力,又简化了上层的色彩组合调用。主循环则利用三原色混合原理,通过简单的 0/1 参数组合实现了多种颜色的切换展示,体现了 “抽象封装→逻辑复用→效果组合” 的嵌入式编程思路。

6.6 按键控制板载RGB灯亮灭

  1. 按键引脚配置(输入模式设置)
# 设置引脚功能,添加按键引脚配置
fpioa.set_function(53,FPIOA.GPIO53)

# 按键引脚为53,按下时为高电平,所以这里设置为下拉并设置为输入模式
button = Pin(53, Pin.IN, Pin.PULL_DOWN)  # 使用下拉电阻
  • 引脚复用配置:通过fpioa.set_function(53,FPIOA.GPIO53)将物理引脚 53 配置为 GPIO 功能,与LED 控制类似,建立硬件与软件的映射关系
  • 输入模式参数解析:
    • Pin.IN:设置为输入模式(用于读取外部信号)
    • Pin.PULL_DOWN:启用内部下拉电阻,这是针对 “按下时为高电平” 的硬件特性设计的
      • 未按下时:下拉电阻将引脚拉到低电平(默认状态为 0)
      • 按下时:外部电路将引脚置为高电平(状态变为 1)
  • 硬件适配意义:下拉电阻的使用确保了按键未操作时状态稳定(不会因悬空导致电平波动),提高了检测可靠性
  1. 主循环中的按键控制逻辑(交互核心)
while True:
    if button.value() == 1:
        LED.high()  # 按键按下时熄灭LED
    else:
        LED.low()   # 按键未按下时点亮LED
  • 状态读取:button.value()用于获取当前按键状态(1 为按下,0 为未按下)
  • 条件控制:通过判断按键状态来控制 LED 的亮灭:
  • 按键按下(值为 1)→ LED.high() → 熄灭 LED(共阳特性)
  • 按键未按下(值为 0)→ LED.low() → 点亮 LED
  • 实时响应:while True循环持续检测按键状态,实现了对按键操作的实时响应,无延迟感知

3.硬件特性与软件逻辑的结合点

  • 共阳 LED 的控制逻辑:延续了之前的设计,high()熄灭、low()点亮,确保 LED 状态符合硬件特性

  • 按键电平与状态的映射:根据 “按下为高电平” 的硬件设计,软件中直接用button.value() == 1判断按键按下状态,实现了硬件与软件的正确对接

核心逻辑总结
这段代码的核心是通过 “按键状态检测→条件判断→LED 状态控制” 的流程,实现了按键对 LED 的交互控制。其中按键的下拉电阻配置是确保检测稳定的关键,而主循环中的实时状态检测则实现了交互的即时性。整个逻辑简洁明了,体现了嵌入式开发中 “输入检测→输出控制” 的典型交互模式,为更复杂的人机交互功能奠定了基础。

6.7 用按键切换RGB灯状态

  1. 核心变量定义(状态管理基础)
# 消抖时间设置为20毫秒
debounce_delay = 20  # 毫秒
last_press_time = 0  # 上次按键按下的时间,单位为毫秒

# 记录LED当前状态,True表示亮,False表示灭
led_on = False

# 记录按键状态,用于检测按下和松开的状态变化
button_last_state = 0  # 上次按键状态
  • 消抖相关变量:debounce_delay(消抖时间)和last_press_time(上次有效按键时间)用于过滤按键机械抖动带来的误触发;
  • LED 状态变量:led_on通过布尔值记录当前 LED 是否点亮,避免直接读取硬件电平判断状态,简化逻辑;
  • 按键状态变量:button_last_state记录上一次循环的按键状态,用于检测状态变化(从 “未按下” 到 “按下” 的跳变)。
  1. 按键状态检测与消抖(可靠性核心)
button_state = button.value()  # 获取当前按键状态
current_time = time.ticks_ms()  # 获取当前时间(单位:毫秒)

# 检测按键从未按下(0)到按下(1)的变化(上升沿)
if button_state == 1 and button_last_state == 0:
    # 检查按键是否在消抖时间外(过滤抖动)
    if current_time - last_press_time > debounce_delay:
        # 有效按键:执行LED状态切换...
        last_press_time = current_time  # 更新按键按下时间

# 更新上次按键状态
button_last_state = button_state
  • 边缘检测逻辑:通过比较button_state(当前状态)和button_last_state(上次状态),只响应 “未按下(0)→
    按下(1)” 的上升沿变化,确保一次按键动作只触发一次操作(避免持续按下时重复触发);
  • 消抖处理:机械按键按下 / 松开时会有 5-20ms 的物理抖动(电平快速波动),通过判断current_time -
    last_press_time > debounce_delay,确保只有稳定超过 20ms 的高电平才被视为有效按键,过滤抖动干扰;
  • 时间基准:time.ticks_ms()提供毫秒级时间戳,用于计算两次按键的间隔,是消抖逻辑的时间基准。
  1. LED 状态切换逻辑(交互核心)
# 有效按键触发后,切换LED状态
if led_on:
    LED.high()  # 熄灭LED(共阳特性:高电平灭)
else:
    LED.low()   # 点亮LED(共阳特性:低电平亮)

led_on = not led_on  # 反转LED状态记录
  • 状态驱动控制:基于led_on变量的当前值决定 LED 的操作(亮 / 灭),而非直接依赖硬件电平,逻辑更清晰;
  • 翻转逻辑:每次有效按键后,通过led_on = not led_on反转状态,实现 “按一次亮,再按一次灭” 的toggle(切换)效果,符合用户对按键控制的直觉预期。
  1. 主循环与延时控制
while True:
    # 按键检测、消抖、状态切换逻辑...
    
    # 简单延时,防止主循环过于频繁
    time.sleep_ms(10)
  • 循环周期:time.sleep_ms(10)让主循环每 10ms 执行一次,既保证了按键响应的实时性(10ms 延迟感知不到),又避免了 CPU 无意义的高频空转,降低资源占用;
  • 持续检测:while True确保程序持续运行,实时监测按键状态变化,保证交互的即时性。

核心逻辑总结
这段代码的核心是通过 **"边缘检测 + 消抖处理"实现可靠的按键识别,再通过状态变量记录与翻转 ** 实现 LED 的切换控制。其中:

  • 消抖处理解决了机械按键的物理特性导致的误触发问题,是嵌入式交互中保证可靠性的关键;
  • 边缘检测和状态变量确保了一次按键动作只产生一次状态切换,符合用户操作习惯;
  • 整体逻辑从 “读取硬件状态” 到 “判断有效操作” 再到 “执行控制动作”,层次清晰,是嵌入式人机交互的典型设计模式。

学习产出:

  • 了解并学习用k230控制LED灯
  • 分析k230的例程
  • 例程的拓展
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芸翳&Camellia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值