Skip to content

概念先知道

  • 中断(EXTI):像“门铃”——事件发生时芯片主动停下当前工作去处理,处理完再回来;不用像轮询那样一直盯着引脚。
  • 触发方式:下降沿(电平从高变低)、上升沿(从低变高)、低电平、高电平。按键按下接地产生的是下降沿。
  • 中断回调:触发后系统自动调用你注册的函数(本例打印 Interrupt Trigger!),不要在回调里做耗时操作。

例程功能简介

本页对应博流官方 SDK 的 gpio_interrupt 例程(examples/peripherals/gpio/gpio_interrupt),演示 GPIO 外部中断(EXTI)功能:

  • 通过串口 shell 命令 gpio_int_test <gpio> <mode> 把指定引脚配置为中断输入;
  • 支持 4 种触发方式:0 下降沿、1 上升沿、2 低电平、3 高电平;
  • 引脚电平变化满足触发条件时,进入中断回调函数,串口打印 Interrupt Trigger!
  • 同族例程examples/peripherals/gpio/):gpio_input_output(输入输出基础)、gpio_output_with_input(输出与输入联动)、gpio_validation_cli(命令行验证)。

操作步骤

1
硬件准备

Ai-M6x 各开发板的按键统一接 GPIO2,直接用板载按键即可;若用外接按键/杜邦线,一端接 GPIO2、另一端接 GND,用来手动模拟电平变化触发中断。

2
进入例程目录

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

cd examples/peripherals/gpio/gpio_interrupt
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),例程启动后打印 gpio interrupt。在串口输入命令 gpio_int_test 2 0 回车,把 GPIO2(板载按键)配置为下降沿触发中断,然后按下按键(或把杜邦线接地再松开),串口会打印 Interrupt Trigger!

代码执行流程

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

更多触发方式

输入 gpio_int_test 2 1(上升沿)、gpio_int_test 2 2(低电平)、gpio_int_test 2 3(高电平)可以体验其他触发模式;也可以换其他引脚,如 gpio_int_test 3 0 使用 GPIO3。

例程调用的 API 介绍

bflb_device_get_by_name("gpio")

获取 GPIO 外设的设备句柄。

参数

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

返回值struct bflb_device_s * 设备句柄

bflb_gpio_init(gpio, pin, mode)

把指定引脚配置为输入模式(中断场景使用 GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN)。

参数

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

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

bflb_gpio_int_init(gpio, pin, mode)

初始化指定引脚的中断触发方式。

参数

  • gpio:GPIO 设备句柄
  • pin:引脚号
  • mode:触发方式,GPIO_INT_TRIG_MODE_SYNC_FALLING_EDGE(下降沿)/ SYNC_RISING_EDGE(上升沿)/ SYNC_LOW_LEVEL(低电平)/ SYNC_HIGH_LEVEL(高电平)

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

bflb_gpio_irq_attach(pin, isr)

为指定引脚注册中断回调函数,触发后由系统调用该回调。

参数

  • pin:引脚号
  • isr:回调函数,形如 void isr(uint8_t pin)

返回值:无

bflb_irq_enable(irq_num)

使能外设中断。例程先用 bflb_irq_disable(gpio->irq_num) 关中断做配置,配置完成后再使能。

参数

  • irq_num:外设中断号,GPIO 使用 gpio->irq_num

返回值:无

完整代码

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

📜 点击展开 gpio_interrupt/main.c 完整代码
c
#include "bflb_gpio.h"
#include "bflb_mtimer.h"
#include "board.h"
#include "shell.h"
#include "bflb_uart.h"

struct bflb_device_s *gpio;
struct bflb_device_s *uart0;
static uint8_t gpio_int_pin = GPIO_PIN_2; /* Ai-M6x 开发板按键 */

void gpio0_isr(uint8_t pin)
{
    if (pin == gpio_int_pin) {
        printf("Interrupt Trigger!\r\n");
    }
}

int gpio_int_test(int argc, char **argv)
{
    printf("Set gpio interrupt triggle mode\r\n");

    if ((argc != 3) || (atoi(argv[1]) >= GPIO_PIN_MAX) || (atoi(argv[2]) > 3)) {
        printf("Usage: gpio_int_test <gpio> <mode>\r\n"
               "    0: GPIO_INT_TRIG_MODE_SYNC_FALLING_EDGE\r\n"
               "    1: GPIO_INT_TRIG_MODE_SYNC_RISING_EDGE\r\n"
               "    2: GPIO_INT_TRIG_MODE_SYNC_LOW_LEVEL\r\n"
               "    3: GPIO_INT_TRIG_MODE_SYNC_HIGH_LEVEL\r\n");
        return 1;
    }

    printf("Set gpio%d interrupt triggle mode to %d\r\n", atoi(argv[1]), atoi(argv[2]));

    bflb_irq_disable(gpio->irq_num);
    gpio_int_pin = atoi(argv[1]);
    bflb_gpio_init(gpio, atoi(argv[1]), GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN);
    bflb_gpio_int_init(gpio, atoi(argv[1]), atoi(argv[2]));
    bflb_gpio_irq_attach(atoi(argv[1]), gpio0_isr);
    bflb_irq_enable(gpio->irq_num);

    return 0;
}

int main(void)
{
    int ch;
    board_init();

    gpio = bflb_device_get_by_name("gpio");
    uart0 = bflb_device_get_by_name("uart0");
    printf("gpio interrupt\r\n");

    shell_init();

    while (1) {
        while ((ch = bflb_uart_getchar(uart0)) != -1) {
            shell_handler(ch);
        }
    }
}
SHELL_CMD_EXPORT_ALIAS(gpio_int_test, gpio_int_test, shell gpio_int_test.);

FAQ

输入命令后没有任何反应

确认串口助手波特率为 2000000;命令格式为 gpio_int_test <gpio> <mode>,例如 gpio_int_test 2 0(GPIO2 下降沿),注意参数之间用空格分隔,输入后回车。

按键按下没有触发中断

检查触发方式与信号方向是否匹配:按键按下接地产生的是下降沿,应使用模式 0;如果是高有效接线,请使用上升沿或高电平模式。

中断触发多次/抖动

机械按键按下和松开时会有抖动,可能触发多次中断。实际项目可在中断回调中做软件消抖(延时后再次读取电平确认),或改用低电平触发。

相关最佳实践

遇到问题?

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

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