跳转至

04 AirKEY_1000

作者:沈园园 | 最后修改:2026-06-04

一、AirKEY_1000 概述

AirKEY_1000是合宙推出的一款支持8个独立按键的配件板,其中:

  1. 按键板,用于测试GPIO中断功能;
  2. 适用于Air780E系列/Air1601系列/Air8101系列;

二、演示功能概述

AirKEY_1000是合宙设计生产的一款支持8个独立按键的配件板;

本demo演示的核心功能为:

Air1601开发板+AirKEY_1000配件板,使用Air1601开发板的GPIO中断检测AirKEY_1000配件板上8个独立按键的按下或者弹起状态;

三、准备硬件环境

参考:硬件环境清单,准备以及组装好硬件环境。

1、Air1601开发板一块

2、TYPE-C USB数据线一根

3、AirSHT30_1000配件板

4、母对母的杜邦线4根

5、Air1601开发板和数据线的硬件接线方式为

  • Air1601开发板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
  • 在 Air1601 开发板上丝印标注 USB1,为芯片烧录下载接口;
  • 若遇到因电脑 USB 端口供电不足导致的烧录失败,也可改用外部稳压电源通过开发板上的 VIN 引脚进行供电;

Air1601开发板与AirKEY_1000配件板连接方式如下:

Air1601 开发板 AirKEY_1000配件板
RX1/GPIO3 K1
TX1/GPIO2 K2
RX2/GPIO55 K3
TX2/GPIO54 K4
CS0/GPIO8 K5
CLK1/GPIO9 K6
MISO1/GPIO10 K7
GPIO12 K8
GND G

Air1601 开发板购买链接:Air1601开发板 多功能5寸RGB屏 支持AirUI 摄像头 代开发固件-淘宝网

AirKEY_1000 购买链接:AirKEY_1000 8路独立按键小板-淘宝网

四、准备软件环境

4.1 软件环境

在开始实践本示例之前,先筹备一下软件环境:

1、烧录工具:Luatools 下载调试工具

2、内核固件:本demo开发测试时使用的固件为LuatOS-SoC_V1012_Air1601_101.soc,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试。

3、脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air1601_Air1602/demo/accessory_board/AirKEY_1000

4、lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件

准备好软件环境之后,接下来查看如何烧录项目文件到 Air1601 开发板中,将本篇文章中演示使用的项目文件烧录到Air1601开发板 中。

4.2 API 介绍

GPIO库:https://docs.openluat.com/osapi/core/gpio/

五、程序结构

AirKEY_1000/
│── main.lua
│── key_app.lua
│── AirKEY_1000.lua
│── readme.md

5.1 文件说明

  1. main.lua:主程序入口文件。
  2. key_app.lua:每隔1秒读取一次温湿度数据。
  3. AirKEY_1000.lua:AirKEY_1000驱动文件。

六、代码详解

6.1 main.lua

主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。

6.2 key_app.lua

使用Air1601开发板的GPIO中断检测AirKEY_1000配件板上8个独立按键的按下或者弹起状态。

6.2.1 检测按键的按下或者弹起状态

--AirKEY_1000上8个按键对应的Air1601的GPIO ID
local KEY1_GPIO_ID = 3
local KEY2_GPIO_ID = 2
local KEY3_GPIO_ID = 55
local KEY4_GPIO_ID = 54
local KEY5_GPIO_ID = 8
local KEY6_GPIO_ID = 9
local KEY7_GPIO_ID = 10
local KEY8_GPIO_ID = 12


--按键1的中断处理函数
--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
--gpio_id:number类型,air_key.setup函数配置按键1时,对应的Air1601上的GPIO ID
--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
local function key1_int_cbfunc(int_level, gpio_id)
    log.info("key1_int_cbfunc pressup", gpio_id, int_level)

    --如果需要执行耗时较长的动作,不要在这里直接执行
    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
    sys.publish("KEY1_PRESSUP_IND")
end

--按键2的中断处理函数
--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
--gpio_id:number类型,air_key.setup函数配置按键2时,对应的Air1601上的GPIO ID
--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
local function key2_int_cbfunc(int_level, gpio_id)
    log.info("key2_int_cbfunc pressup", gpio_id, int_level)

    --如果需要执行耗时较长的动作,不要在这里直接执行
    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
    sys.publish("KEY2_PRESSUP_IND")
end

--按键3的中断处理函数
--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
--gpio_id:number类型,air_key.setup函数配置按键3时,对应的Air1601上的GPIO ID
--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
local function key3_int_cbfunc(int_level, gpio_id)
    log.info("key3_int_cbfunc pressup", gpio_id, int_level)

    --如果需要执行耗时较长的动作,不要在这里直接执行
    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
    sys.publish("KEY3_PRESSUP_IND")
end

--按键4的中断处理函数
--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
--gpio_id:number类型,air_key.setup函数配置按键4时,对应的Air1601上的GPIO ID
--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
local function key4_int_cbfunc(int_level, gpio_id)
    log.info("key4_int_cbfunc pressup", gpio_id, int_level)

    --如果需要执行耗时较长的动作,不要在这里直接执行
    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
    sys.publish("KEY4_PRESSUP_IND")
end


--按键5、6、7、8的中断处理函数
--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
--gpio_id:number类型,air_key.setup函数配置按键5、6、7、8时,对应的Air1601上的GPIO ID
--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
local function key5678_int_cbfunc(int_level, gpio_id)
    log.info("key5678_int_cbfunc", gpio_id, int_level)

    --如果需要执行耗时较长的动作,不要在这里直接执行
    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
    if gpio_id==KEY5_GPIO_ID then
        log.info("key5 pressdown")
        sys.publish("KEY5_PRESSDOWN_IND")
    elseif gpio_id==KEY6_GPIO_ID then
        log.info("key6 pressdown")
        sys.publish("KEY6_PRESSDOWN_IND")
    elseif gpio_id==KEY7_GPIO_ID then
        log.info("key7 pressdown")
        sys.publish("KEY7_PRESSDOWN_IND")
    elseif gpio_id==KEY8_GPIO_ID then
        log.info("key8 pressdown")
        sys.publish("KEY8_PRESSDOWN_IND")
    end    
end

--本demo中,Air1601开发板和AirKEY_1000配件板的接线方式如下
--Air1601开发板             AirKEY_1000配件板
--     RX1/GPIO3-----------------K1
--     TX1/GPIO2-----------------K2
--     RX2/GPIO55-----------------K3
--     TX2/GPIO54-----------------K4
--     CS0/GPIO8-----------------K5
--     CLK1/GPIO9-----------------K6
--     MISO1/GPIO10-----------------K7
--     GPIO12-----------------K8
--       GND-----------------G



--AirKEY_1000上的1、2、3、4,四个按键的引脚
--分别和Air1601的KEY1_GPIO_ID、KEY2_GPIO_ID、KEY3_GPIO_ID、KEY4_GPIO_ID四个引脚相连
--GPIO配置为上升沿触发中断,可以实时检测到按键弹起的动作
--按键弹起时,会执行对应的中断处理函数key1_int_cbfunc、key2_int_cbfunc、key3_int_cbfunc、key4_int_cbfunc
--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
air_key.setup(1, KEY1_GPIO_ID, gpio.RISING, key1_int_cbfunc)
air_key.setup(2, KEY2_GPIO_ID, gpio.RISING, key2_int_cbfunc)
air_key.setup(3, KEY3_GPIO_ID, gpio.RISING, key3_int_cbfunc)
air_key.setup(4, KEY4_GPIO_ID, gpio.RISING, key4_int_cbfunc)

--AirKEY_1000上的5、6、7、8,四个按键的引脚
--分别和Air1601的KEY5_GPIO_ID、KEY6_GPIO_ID、KEY7_GPIO_ID、KEY8_GPIO_ID四个引脚相连
--GPIO配置为下降沿触发中断,可以实时检测到按键按下的动作
--按键按下时,会执行对应的中断处理函数key5678_int_cbfunc
--这四个按键共用了同一个中断处理函数,可以通过函数传入的GPIO ID来区分是哪一个按键被按下
--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
air_key.setup(5, KEY5_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)
air_key.setup(6, KEY6_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)
air_key.setup(7, KEY7_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)
air_key.setup(8, KEY8_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)

6.3 AirKEY_1000.lua

AirKEY_1000驱动配置文件。

6.3.1 配置主机和AirKEY_1000之间的控制参数

--本文件中的主机是指Air1601开发板
--AirKEY_1000是合宙设计生产的一款8路独立按键的配件板

local AirKEY_1000 = {}


--配置主机和AirKEY_1000之间的控制参数;

--key_id:number类型;
--        AirKEY_1000的按键ID;
--        取值范围:1到8;
--        必须传入,不允许为空;
--gpio_id:number类型;
--         主机使用的中断引脚GPIO ID;
--         AirKEY_1000上的一个按键引脚,和主机上的一个GPIO中断引脚相连;
--         AirKEY_1000上的按键按下或者弹起,主机上的GPIO中断引脚输入电平发生变化,从而产生中断;
--int_mode:number类型;
--          表示主机GPIO中断触发类型;
--          取值范围:gpio.RISING表示上升沿触发,gpio.FALLING表示下降沿触发;
--          如果没有传入此参数,则默认为gpio.FALLING;
--int_cbfunc:function类型;
--          表示中断处理函数,函数的定义格式如下:
--                           function cb_func(level, gpio_id)
--                               --level:表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
--                               --gpio_id:表示触发中断的主机中断引脚的GPIO ID;
--                           end
--          中断函数中不要直接执行耗时较长的动作,例如写fskv,写文件,延时等,可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
--          必须传入,不允许为空;

--返回值:成功返回true,失败返回false
function AirKEY_1000.setup(key_id, gpio_id, int_mode, int_cbfunc) 
    --开启防抖,模式0-冷却,中断后马上上报,但200ms内只上报一次
    gpio.debounce(gpio_id, 200)

    if not (int_mode==gpio.RISING or int_mode==gpio.FALLING) then
        log.error("AirKEY_1000.setup error", "invalid int_mode", int_mode)
        return false
    end

    if type(int_cbfunc)~="function" then
        log.error("AirKEY_1000.setup error", "invalid int_cbfunc", type(int_cbfunc))
        return false
    end

    -- gpio.setup(gpio_id, int_cbfunc, int_mode==gpio.RISING and gpio.PULLDOWN or gpio.PULLUP, int_mode)
    gpio.setup(gpio_id, int_cbfunc, gpio.PULLUP, int_mode)

    return true
end


return AirKEY_1000

七、运行结果展示

(1) 按键1弹起时,Luatools的运行日志输出 key1_int_cbfunc pressup,表示按键1测试正常;

(2) 按键2弹起时,Luatools的运行日志输出 key2_int_cbfunc pressup,表示按键2测试正常;

(3) 按键3弹起时,Luatools的运行日志输出 key3_int_cbfunc pressup,表示按键3测试正常;

(4) 按键4弹起时,Luatools的运行日志输出 key4_int_cbfunc pressup,表示按键4测试正常;

(5) 按键5按下时,Luatools的运行日志输出 key5 pressdown,表示按键5测试正常;

(6) 按键6按下时,Luatools的运行日志输出 key6 pressdown,表示按键6测试正常;

(7) 按键7按下时,Luatools的运行日志输出 key7 pressdown,表示按键7测试正常;

(8) 按键8按下时,Luatools的运行日志输出 key8 pressdown,表示按键8测试正常;

[2026-05-07 10:33:55.428][LTOS/N][000000009.230]:I/user.key1_int_cbfunc pressup 3 0
[2026-05-07 10:34:00.192][LTOS/N][000000013.972]:I/user.key2_int_cbfunc pressup 2 0
[2026-05-07 10:34:01.987][LTOS/N][000000015.782]:I/user.key3_int_cbfunc pressup 55 0
[2026-05-07 10:34:03.509][LTOS/N][000000017.302]:I/user.key4_int_cbfunc pressup 54 0
[2026-05-07 10:34:04.949][LTOS/N][000000018.736]:I/user.key5678_int_cbfunc 8 0
[2026-05-07 10:34:04.956][LTOS/N][000000018.736]:I/user.key5 pressdown
[2026-05-07 10:34:07.130][LTOS/N][000000020.912]:I/user.key5678_int_cbfunc 9 0
[2026-05-07 10:34:07.132][LTOS/N][000000020.912]:I/user.key6 pressdown
[2026-05-07 10:34:09.357][LTOS/N][000000023.146]:I/user.key5678_int_cbfunc 10 0
[2026-05-07 10:34:09.367][LTOS/N][000000023.146]:I/user.key7 pressdown
[2026-05-07 10:34:11.084][LTOS/N][000000024.872]:I/user.key5678_int_cbfunc 12 0
[2026-05-07 10:34:11.089][LTOS/N][000000024.872]:I/user.key8 pressdown

八、总结

通过本章内容的学习,你可以学习到Air1601开发板+AirKEY_1000配件板,使用Air1601开发板的GPIO中断检测AirKEY_1000配件板上8个独立按键的按下或者弹起状态。