RDK(X3/X5)button_led.py 代码完整详解

适用平台:地平线 RDK X3、RDK X5;

库:Hobot.GPIO(地平线自研 Python GPIO 库,语法高度兼容 RPi.GPIO)

功能简述:读取按键输入,同步控制 LED 输出

按键电平状态直接映射到 LED,按键按下 LED 点亮、松开熄灭。

一、硬件接线说明

python

运行

led_pin = 31 # BOARD物理引脚31 → LED阳极(串220Ω限流电阻)
but_pin = 37 # BOARD物理引脚37 → 按键一端

推荐接线方案:

  1. LED 回路Pin31 → 220Ω电阻 → LED正极 → GND
  2. 按键回路(上拉推荐)
    • 方案 A(开发板内部上拉):按键一端 Pin37,另一端接 GND
    • 方案 B(外部):Pin37 外接 10k 上拉电阻到 3.3V,按键另一端接 GND

⚠️ BOARD 编码 = 开发板 40Pin 排针丝印物理编号,不需要记忆芯片 GPIO 编号,新手首选。


二、逐段源码解析

1. 文件头 & 导入模块

python

运行

#!/usr/bin/env python3
################################################################################
# Apache2.0开源协议声明
################################################################################
import sys
import signal
import Hobot.GPIO as GPIO
import time
  • #!/usr/bin/env python3:指定解释器,可直接chmod +x ./xxx.py直接运行
  • Hobot.GPIO地平线 RDK 平台专用 GPIO 库,RDK 系统预装,无需手动 pip 安装

2. Ctrl+C 信号捕获函数

python

运行

def signal_handler(signal, frame):
    sys.exit(0)

作用:捕获 SIGINT(键盘 Ctrl+C 中断信号),优雅退出程序。

补充:真正的资源释放放在finally块,信号 handler 只负责退出循环。

3. 全局引脚定义

python

运行

led_pin = 31 # BOARD 编码 31(输出)
but_pin = 37 # BOARD 编码 37(输入)
GPIO.setwarnings(False)
  • GPIO.setwarnings(False)关闭警告;当引脚已经被其他进程占用时,库默认打印警告,调试稳定后可以关闭。

4. 核心主函数 main ()

python

运行

def main():
    prev_value = None
    # ========== 引脚初始化 ==========
    GPIO.setmode(GPIO.BOARD)       # 使用【物理丝印编号模式】
    GPIO.setup(led_pin, GPIO.OUT)  # 31号设置为输出
    GPIO.setup(but_pin, GPIO.IN)   # 37号设置为输入

    GPIO.output(led_pin, GPIO.LOW) # LED初始状态:熄灭
    print("Starting demo now! Press CTRL+C to exit")

    try:
        while True:
            curr_value = GPIO.input(but_pin) # 读取按键当前电平
            # 判断电平是否发生跳变(按键按下/松开)
            if curr_value != prev_value:
                GPIO.output(led_pin, curr_value) # 按键电平直接输出给LED
                prev_value = curr_value
                print("Outputting {} to Pin {}".format(curr_value, led_pin))
            time.sleep(1) # 循环间隔1秒
    finally:
        GPIO.cleanup() # 【重点】程序退出时,释放所有GPIO资源
关键逻辑拆解
  1. GPIO.setmode(GPIO.BOARD) 引脚编号模式一共 4 种:
    • BOARD(电路板编号模式):40Pin 排针物理丝印号(推荐,此 demo 使用)
    • BCM模仿树莓派 BCM 编号
    • SOC:芯片内核原始 GPIO 号(查阅芯片手册使用)
    • CVM:连接器信号名称字符串
  2. 电平跳变检测 prev_value保存上一次按键状态;只有按键电平发生变化,才修改 LED 状态,避免重复输出。
  3. time.sleep(1) 轮询

    ⚠️【缺陷提醒】这种是轮询查询方式最低 1 秒才能识别一次按键动作,按键快速按放会丢失事件; 优化方案:使用中断边沿检测 GPIO.add_event_detect()(后面补充优化代码)

  4. try ... finally 结构 无论程序正常结束、Ctrl+C 强制退出、异常崩溃,finally块一定会执行; GPIO.cleanup() 把 GPIO 恢复为默认输入状态,防止引脚持续输出电平造成硬件隐患

5. 程序入口

python

运行

if __name__ == '__main__':
    signal.signal(signal.SIGINT, signal_handler)
    main()
  • signal.signal(SIGINT, handler):注册 Ctrl+C 中断回调
  • Python 标准写法,防止代码被其他文件 import 时自动执行

三、运行操作步骤(RDK X5 实测)

  1. 赋予执行权限

bash

运行

chmod +x button_led.py
  1. 必须使用 root 权限操作 GPIO(硬件权限限制)

bash

运行

sudo python3 button_led.py
  1. 操作:按下按键 → LED 点亮;松开按键 → LED 熄灭;控制台打印电平变化日志

四、原生代码优缺点

✅ 优点:逻辑极简,新手入门,容易理解输入输出映射关系 ❌ 缺点:

  1. 轮询延时 1s,响应慢,快速按键会丢失;
  2. CPU 持续循环占用资源;
  3. 没有启用内部上下拉电阻,浮空输入容易出现电平抖动。

五、进阶优化版本(中断方式,推荐项目使用)

使用边沿中断,不需要 while 轮询,实时响应按键,节省 CPU

python

运行

#!/usr/bin/env python3
import sys
import signal
import Hobot.GPIO as GPIO
import time

led_pin = 31
but_pin = 37
GPIO.setwarnings(False)

def signal_handler(signal, frame):
    GPIO.cleanup()
    sys.exit(0)

# 按键中断回调函数
def button_callback(channel):
    val = GPIO.input(but_pin)
    GPIO.output(led_pin, val)
    print(f"Button state changed: {val}, LED set to {val}")

def main():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(led_pin, GPIO.OUT)
    # 启用内部上拉电阻,防止浮空抖动
    GPIO.setup(but_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.output(led_pin, GPIO.LOW)

    # 注册双边沿中断:上升沿+下降沿都触发
    GPIO.add_event_detect(but_pin, GPIO.BOTH, callback=button_callback, bouncetime=200)
    print("Waiting button trigger, CTRL+C exit")

    while True:
        time.sleep(0.1)

if __name__ == '__main__':
    signal.signal(signal.SIGINT, signal_handler)
    main()

重点新增特性:

  1. pull_up_down=GPIO.PUD_UP:开启芯片内部上拉电阻,解决浮空杂波;
  2. add_event_detect 硬件边沿中断;
  3. bouncetime=200:消抖,防止机械按键抖动多次触发;
  4. 无需高频轮询,空闲时 CPU 低负载。

六、常见踩坑清单(RDK 开发高频问题)

  1. 报错 Permission denied ✅ 解决:GPIO 操作必须加sudo运行
  2. 按键没反应,电平一直不变 检查:接线、上下拉配置、确认引脚没有被系统设备树复用(串口 / SPI 等功能占用)
  3. LED 不亮 检查 LED 正负极、限流电阻,确认输出引脚是 BOARD 编号
  4. 引脚被占用警告 ✅ 临时关闭:GPIO.setwarnings(False);长期方案:确认没有其他程序占用同一引脚
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐