Skip to content

概念先知道

  • 上拉输入:内部电阻把引脚“默认拉高”到高电平;按键按下把引脚接地时,读到低电平(0)。
  • 电平:引脚只有两种状态——高电平(1,约 3.3V)和低电平(0,约 0V),判断按键按下/松开就看电平变化。
  • 按键抖动:机械按键按下/松开的瞬间会反复通断几次(抖动),例程演示用轮询读取,实际项目要加消抖。

例程功能简介

本页对应博流官方 SDK 的 gpio_input_output 例程(examples/peripherals/gpio/gpio_input_output),本页聚焦其中的输入部分:

  • GPIO2 配置为上拉输入(Ai-M6x 各开发板按键统一接 GPIO2),每 2 秒读取一次输入电平;
  • 读取结果通过串口打印:GPIO_PIN_2=0(低电平,按键按下)/ GPIO_PIN_2=1(高电平,按键松开)。
  • 同族例程examples/peripherals/gpio/):gpio_interrupt(外部中断)、gpio_output_with_input(输出与输入联动)、gpio_validation_cli(命令行验证)。

例程同时把 GPIO0 配置为推挽输出做电平翻转,GPIO 输出(点亮 LED)见 GPIO输出(点亮LED)

操作步骤

1
硬件准备

Ai-M6x 各开发板的按键统一接 GPIO2,直接用板载按键即可(若用外接按键,一端接 GPIO2、另一端接 GND)。例程把 GPIO2 配置为内部上拉输入,按键按下时引脚被拉低(读到 0),松开时恢复高电平(读到 1)。

2
进入例程目录

在终端进入 SDK 的 GPIO 例程目录(前提:已按快速开始(Linux)Windows搭建好环境):

cd examples/peripherals/gpio/gpio_input_output
3
编译工程

执行编译命令。Ai-M62(BL616)与 Ai-M61(BL618)同属一个系列,统一填写引脚最少的 bl616 即可:

make CHIP=bl616 BOARD=bl616dk
4
烧录固件

用 USB 线连接开发板,按住 BOOT 键(Ai-M61-32S-Kit 为 IO2)不放、短按 EN/RST 进入下载模式,然后执行烧录(把串口号换成实际值):

make flash CHIP=bl616 COMX=/dev/ttyUSB0
5
运行验证

烧录完成后按一下复位键,打开串口助手(波特率 2000000)。例程每 2 秒读取一次 GPIO2:串口打印 GPIO_PIN_2=0 表示按键已按下,打印 GPIO_PIN_2=1 表示松开。

代码执行流程

例程从启动到运行的完整流程如下(图中的循环箭头表示反复执行):

例程调用的 API 介绍

bflb_device_get_by_name("gpio")

获取 GPIO 外设的设备句柄,后续所有 GPIO 操作都要通过该句柄进行。

参数

  • name:外设名称字符串,GPIO 固定传 "gpio"

返回值struct bflb_device_s * 设备句柄

bflb_gpio_init(gpio, pin, mode)

把指定引脚配置为输入模式。按键检测场景使用 GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0 组合:内部上拉保证按键松开时读到高电平,施密特触发提高抗干扰能力。

参数

  • gpio:GPIO 设备句柄
  • pin:引脚号,如 GPIO_PIN_2(GPIO2,Ai-M6x 开发板按键)
  • mode:模式组合,输入用 GPIO_INPUT,可叠加 GPIO_PULLUP(内部上拉)、GPIO_SMT_EN(施密特触发)

返回值:成功返回 0;失败返回负值错误码

bflb_gpio_read(gpio, pin)

读取指定引脚当前的输入电平,用于判断按键是否按下。

参数

  • gpio:GPIO 设备句柄
  • pin:已配置为输入的引脚号

返回值0 低电平(按键按下);1 高电平(按键松开)

bflb_mtimer_delay_ms(ms)

软件延时指定毫秒数,控制按键的轮询周期。

参数

  • ms:延时毫秒数,例程为 2000(2 秒)

返回值:无

完整代码

以下为 gpio_input_output/main.c 完整源码,与官方示例(examples/peripherals/gpio/gpio_input_output)一致;点灯引脚已适配 Ai-M61/62-32S-Kit 板载 RGB 灯,默认折叠,点击展开:

📜 点击展开 gpio_input_output/main.c 完整代码
c
#include "bflb_gpio.h"
#include "board.h"

struct bflb_device_s *gpio;

int main(void)
{
    board_init();

    gpio = bflb_device_get_by_name("gpio");
    printf("gpio output\r\n");
    bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
    /* Ai-M6x 各开发板按键统一接 GPIO2,配置为内部上拉输入 */
    bflb_gpio_init(gpio, GPIO_PIN_2, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);

    while (1) {
        bflb_gpio_set(gpio, GPIO_PIN_0);
        printf("GPIO_PIN_2=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_2));
        bflb_mtimer_delay_ms(2000);

        bflb_gpio_reset(gpio, GPIO_PIN_0);
        printf("GPIO_PIN_2=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_2));
        bflb_mtimer_delay_ms(2000);
    }
}

FAQ

串口一直打印 GPIO_PIN_2=1,按键无效

检查按键接线:一端接 GPIO2、另一端接 GND;确认引脚号与代码一致(默认 GPIO_PIN_2)。

按键按下时读到的是 1 而不是 0

说明按键接到了 VCC 而不是 GND,或按键模块是“高有效”设计。把按键另一端改接 GND,或者把输入配置从内部上拉改为内部下拉并调整判断逻辑。

轮询周期太慢/太快

例程每 2 秒读取一次,是演示用频率。实际项目可把 bflb_mtimer_delay_ms(2000) 改小(如 20),配合按键消抖逻辑使用。

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23