跳转至

01 AirGPIO_1000

作者:沈园园

一、AirGPIO_1000概述

AirGPIO_1000 是合宙推出的一款I2C转16路GPIO配件板,其中:

  1. I2C转16路GPIO(输入输出可配置);
  2. 关键元器件:TAC9555;
  3. 适用于Air780系列/Air8000系列/Air8101系列/Air6101系列,尤其适合GPIO较少的Air8101系列/Air6101系列;

二、演示功能概述

AirGPIO_1000是合宙设计生产的一款I2C转16路扩展GPIO的配件板;

本demo演示的核心功能为:

Air8000核心板+AirGPIO_1000配件板,演示I2C扩展16路GPIO功能;

分输出、输入和中断三种应用场景来演示;

三、准备硬件环境

1、Air8000核心板一块

2、TYPE-C USB数据线一根

3、AirGPIO_1000配件板

4、母对母的杜邦线8根

5、Air8000核心板和数据线的硬件接线方式为

  • Air8000核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
  • 核心板正面的 供电/充电 拨动开关 拨到供电一端;
  • 核心板背面的 USB ON/USB OFF 拨动开关 拨到USB ON一端;

6、Air8000核心板和AirGPIO_1000配件板的硬件接线方式为

Air8000核心板 AirGPIO_1000配件板
VDD_EXT 3V3
GND GND
I2C1_SDA SDA
I2C1_SCL SCL
GPIO2 INT
  • 扩展GPIO输出演示时,无需接线;通过万用表或者示波器检测AirGPIO_1000配件板上的P00电平即可;
  • 扩展GPIO输入演示时,将AirGPIO_1000配件板上的P10和P11两个引脚通过杜邦线短接;软件上会将P10配置为输出(第一秒输出低电平,第二秒输出高电平,如此循环输出),将P11配置为输入,通过检测P11引脚输入电平的状态来演示;
  • 扩展GPIO中断演示时,将AirGPIO_1000配件板上的P03和P04两个引脚通过杜邦线短接,将AirGPIO_1000配件板上的P13和P14两个引脚通过杜邦线短接;软件上会将P03和P13配置为输出(第一秒输出低电平,第二秒输出高电平,如此循环输出),将P04和P14配置为中断,通过检测中断函数的触发状态来演示。

四、准备软件环境

4.1 软件环境

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

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

2、内核固件:Air8000 最新版本的内核固件

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

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

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

4.2 API 介绍

I2C库:https://docs.openluat.com/osapi/core/i2c/

五、程序结构

AirGPIO_1000/
│── main.lua
│── gpio_app.lua
│── AirGPIO_1000.lua
│── readme.md

5.1 文件说明

  1. main.lua:主程序入口文件。
  2. gpio_app.lua:AirGPIO_1000扩展GPIO输出测试,输入测试,GPIO中断测试。
  3. AirGPIO_1000.lua:AirGPIO_1000驱动配置文件。

六、代码详解

6.1 main.lua

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

6.2 gpio_app.lua

AirGPIO_1000扩展GPIO输出测试,输入测试,GPIO中断测试。

6.2.1 GPIO输出测试

--AirGPIO_1000扩展GPIO输出测试
--P00每隔一秒切换输出一次高低电平,可以通过示波器或者万用表测量AirGPIO_1000上P00引脚电平
local function gpio_output_task_func()
    air_gpio.setup(0x00, 0)

    while true do
        air_gpio.set(0x00, 0)
        sys.wait(1000)
        air_gpio.set(0x00, 1)
        sys.wait(1000)
    end
end

6.2.2 GPIO输入测试

--AirGPIO_1000扩展GPIO输入测试
--P10配置为输出模式,每隔一秒切换输出一次高低电平
--P11配置为输入模式,每隔一秒调用get接口读取一次输入的电平
--将P10和P11两个引脚短接
local function gpio_input_task_func()
    air_gpio.setup(0x10, 0)
    air_gpio.setup(0x11)

    while true do
        air_gpio.set(0x10, 0)
        sys.wait(1000)
        log.info("air_gpio.get(0x11)", air_gpio.get(0x11))
        air_gpio.set(0x10, 1)
        sys.wait(1000)
        log.info("air_gpio.get(0x11)", air_gpio.get(0x11))
    end
end

6.2.3 GPIO中断测试

--AirGPIO_1000扩展GPIO中断测试
--P03配置为输出模式,每隔一秒切换输出一次高低电平
--P04配置为中断模式,并且配置中断处理函数P04_int_cbfunc
--将P03和P04两个引脚短接
--P13配置为输出模式,每隔一秒切换输出一次高低电平
--P14配置为中断模式,并且配置中断处理函数P14_int_cbfunc
--将P13和P14两个引脚短接
local function gpio_int_task_func()
    air_gpio.setup(0x03, 0)
    air_gpio.setup(0x04, P04_int_cbfunc)

    air_gpio.setup(0x13, 0)
    air_gpio.setup(0x14, P14_int_cbfunc)

    while true do
        air_gpio.set(0x03, 0)
        air_gpio.set(0x13, 0)
        sys.wait(1000)
        air_gpio.set(0x03, 1)
        air_gpio.set(0x13, 1)
        sys.wait(1000)
    end
end

6.2.4 初始化Air8000和AirGPIO_1000之间的通信参数

--初始化Air8000和AirGPIO_1000之间的通信参数
--使用Air8000的I2C0
--使用Air8000的GPIO2做为中断引脚
--Air8000核心板和AirGPIO_1000配件板的接线方式如下
--Air8000核心板             AirGPIO_1000配件板
--VDD_EXT(3.3V)-----------------3V3
--       GND-----------------GND
--     I2C1_SDA-----------------SDA
--     I2C1_SCL-----------------SCL
--     GPIO2-----------------INT
air_gpio.init(1, 2)

6.3 AirGPIO_1000.lua

AirGPIO_1000驱动配置文件。

6.3.1 寄存器配置和读写

-- 从机硬件上有三个引脚A0 A1 A2可以配置I2C从设备的地址
-- 当A0 A1 A2都接地时的从设备基地址为(0x40 >> 1)
-- A0 A1 A2有0到7一共八种排序组合,基地址+0/1/2/3/4/5/6/7即为八种从设备的地址
-- AirGPIO_1000默认A0 A1 A2都接地,所以AirGPIO_1000的从设备地址默认也为(0x40 >> 1)
local SALVE_ADDRESS_HIGH_4BIT = (0x40 >> 1)

-- 寄存器地址
local REG_INPUT_PORT_0 = 0x00    -- 输入端口0
local REG_INPUT_PORT_1 = 0x01    -- 输入端口1
local REG_OUTPUT_PORT_0 = 0x02   -- 输出端口0
local REG_OUTPUT_PORT_1 = 0x03   -- 输出端口1
local REG_POL_INV_0 = 0x04       -- 极性反转端口0
local REG_POL_INV_1 = 0x05       -- 极性反转端口1
local REG_CONFIG_0 = 0x06        -- 配置端口0
local REG_CONFIG_1 = 0x07        -- 配置端口1


-- 写入AirGPIO_1000的寄存器

--reg:number类型;
--         表示AirGPIO_1000上的寄存器地址;
--         取值范围:0x00到0x07,参考本文件上方的寄存器地址列表;
--         必须传入,不允许为空;

--value:number类型;
--         表示要写入到AirGPIO_1000寄存器中的数据;
--         取值范围:0x00到0xFF,1个字节的长度;
--         必须传入,不允许为空;

--返回值:成功返回true,失败返回false
local function write_register(reg, value)
    local data = {reg, value}
    local result = i2c.send(AirGPIO_1000.i2c_id, AirGPIO_1000.slave_address, data)
    return result
end

-- 读取AirGPIO_1000的寄存器

--reg:number类型;
--         表示AirGPIO_1000上的寄存器地址;
--         取值范围:0x00到0x07,参考本文件上方的寄存器地址列表;
--         必须传入,不允许为空;

--返回值:成功返回1个字节的number类型,失败返回nil
local function read_register(reg)
    i2c.send(AirGPIO_1000.i2c_id, AirGPIO_1000.slave_address, reg)
    local data = i2c.recv(AirGPIO_1000.i2c_id, AirGPIO_1000.slave_address, 1)
    if data and #data == 1 then
        return string.byte(data, 1)
    end
    return nil
end

6.3.2 主机上的中断引脚处理函数

--主机上的中断引脚处理函数
local function gpio_int_callback()
    log.info("gpio_int_callback")
    --在中断处理函数中不能直接执行耗时较长的动作
    --所以在此处publish一个"AirGPIO_1000_INT"消息
    --在其他位置订阅这个消息,进行异步处理
    --异步处理这个消息的函数可以直接执行耗时较长的动作
    sys.publish("AirGPIO_1000_INT")
end

--遍历用户扩展GPIO中断函数表,进行处理
local function user_gpio_int_callback()
    if AirGPIO_1000.ints then
        --遍历用户扩展GPIO中断函数表
        for k,v in pairs(AirGPIO_1000.ints) do
            if v then
                --读取扩展GPIO的输入电平
                local cur_level = AirGPIO_1000.get(k)
                --如果输入电平和上一次输入电平不一致
                --则执行用户扩展GPIO中断函数
                if v.old_level~=cur_level then
                    v.old_level = cur_level
                    if v.cb_func then v.cb_func(k, cur_level) end
                end
            end
        end
    end
end

--订阅"AirGPIO_1000_INT"消息的处理函数user_gpio_int_callback
--当其他位置publish "AirGPIO_1000_INT"消息时,会执行user_gpio_int_callback
sys.subscribe("AirGPIO_1000_INT", user_gpio_int_callback)

6.3.3 配置主机和AirGPIO_1000之间的通信参数

--配置主机和AirGPIO_1000之间的通信参数;

--i2c_id:number类型;
--        主机使用的I2C ID,用来控制AirGPIO_1000;
--        取值范围:仅支持0和1;
--        如果没有传入此参数,则默认为0;
--int_id:number类型;
--        主机使用的中断引脚GPIO ID,和AirGPIO_1000上的INT引脚相连;
--        AirGPIO_1000可以扩展出来16个GPIO,这些GPIO支持配置为输入;
--        AirGPIO_1000上的任意一个输入GPIO的状态发生上升沿或者下降沿变化时,会通过INT引脚通知到主机的int_id中断引脚;
--        此时主机可以通过I2C接口立即读取AirGPIO_1000上配置为输入模式的扩展GPIO的电平状态,从而判断是哪些扩展GPIO的输入电平发生了变化;
--        如果没有传入此参数,则默认为空,表示不使用中断通知功能;

--返回值:成功返回true,失败返回false
function AirGPIO_1000.init(i2c_id, gpio_int_id)
    --检查参数的合法性
    if not (i2c_id == 0 or i2c_id == 1) then
        log.error("AirGPIO_1000.init", "invalid i2c_id", i2c_id)
        return false
    end

    AirGPIO_1000.i2c_id = i2c_id
    AirGPIO_1000.gpio_int_id = gpio_int_id

    --初始化I2C
    if i2c.setup(i2c_id, i2c.FAST) ~= 1 then
        log.error("AirGPIO_1000.init", "i2c.setup error", i2c_id)
        return false
    end

    --自动识别从设备地址
    --AirGPIO_1000上使用的TCA9555芯片有三个引脚,A2 A1 A0,可以配置三个bit的I2C从设备地址
    --从 0 0 0 到 1 1 1,也就是十进制的0到7,一共可以配置8种;
    --依次读取这8个从设备地址上的一个寄存器地址数据
    --如果返回应答数据,则从设备地址自动识别成功
    for i=0,7 do
        i2c.send(i2c_id, SALVE_ADDRESS_HIGH_4BIT+i, REG_INPUT_PORT_0)
        local data = i2c.recv(i2c_id, SALVE_ADDRESS_HIGH_4BIT+i, 1)
        if data~=nil then
            AirGPIO_1000.slave_address = SALVE_ADDRESS_HIGH_4BIT+i
            log.error("AirGPIO_1000.init", "slave_address", SALVE_ADDRESS_HIGH_4BIT+i, data:byte())
            break
        end
    end

    --自动识别从设备地址失败
    if not AirGPIO_1000.slave_address then
        log.error("AirGPIO_1000.init", "slave_address unknown")
        i2c.close(i2c_id)
        return false
    end


    --配置主机上的中断GPIO,用来实时检测从机上扩展GPIO的输入电平变化
    if gpio_int_id then
        gpio.setup(gpio_int_id, gpio_int_callback, gpio.PULLUP, gpio.FALLING)
    end

    return true
end

6.3.4 关闭主机和AirGPIO_1000之间的通信

--关闭主机和AirGPIO_1000之间的通信;

--返回值:成功返回true,失败返回false
function AirGPIO_1000.deinit()
    --关闭主机I2C
    if AirGPIO_1000.i2c_id then
        i2c.close(AirGPIO_1000.i2c_id)
        AirGPIO_1000.i2c_id = nil
        AirGPIO_1000.slave_address = nil
    end

    --关闭主机中断GPIO
    if AirGPIO_1000.gpio_int_id then
        gpio.close(AirGPIO_1000.gpio_int_id)
        AirGPIO_1000.gpio_int_id = nil
    end

    --清空用户注册的扩展GPIO中断处理表
    if type(AirGPIO_1000.ints)=="table" then
        for k,v in pairs(AirGPIO_1000.ints) do
            AirGPIO_1000.ints[k] = nil
        end        
        AirGPIO_1000.ints = nil
    end
end

6.3.5 配置AirGPIO_1000上的扩展GPIO管脚功能

--[[
配置AirGPIO_1000上的扩展GPIO管脚功能;
支持配置为输出,输入和中断三种模式;

@api AirGPIO_1000.setup(gpio_id, gpio_mode)

@number
gpio_id
表示AirGPIO_1000上的扩展GPIO ID;
取值范围:0x00到0x07,0x10到0x17,一共16种,分别对应16个扩展GPIO引脚;
必须传入,不允许为空或者nil;

@number or function or nil or 空
gpio_mode
number类型时,表示输出模式,取值范围为0和1,0表示默认输出低电平,1表示默认输出高电平;
nil或者空类型时,表示输入模式;
function类型时,表示中断模式,此function为中断回调函数,函数的定义格式如下:
function cb_func(id, level)
    --id:表示触发中断的AirGPIO_1000上的扩展GPIO ID,取值范围为0x00到0x07,0x10到0x17,一共16种,分别对应16个扩展GPIO引脚;
    --level:触发中断后,某一时刻,扩展GPIO输入的电平状态,高电平为1, 低电平为0;并不是指触发中断的电平状态;
end

@return bool
成功返回true,失败返回false

@usage
-- GPIO ID 0x00配置为输出模式,默认输出低电平
AirGPIO_1000.setup(0x00, 0)

-- GPIO ID 0x11配置为输入模式
AirGPIO_1000.setup(0x11)


--P04引脚中断处理函数
--id:0x04
--level:触发中断后,某一时刻,扩展GPIO输入的电平状态,高电平为1, 低电平为0
local function P04_int_cbfunc(id, level)
    log.info("P04_int_cbfunc", id, level)
end

-- GPIO ID 0x04配置为中断模式,中断处理函数为P04_int_cbfunc
AirGPIO_1000.setup(0x04, P04_int_cbfunc)
]]
function AirGPIO_1000.setup(gpio_id, gpio_mode)
    --检查参数的合法性
    if not check_gpio_id_valid(gpio_id) then
        log.error("AirGPIO_1000.setup", "invalid gpio_id", gpio_id)
        return false
    end

    if not (gpio_mode==0 or gpio_mode==1 or gpio_mode==nil or type(gpio_mode)=="function") then
        log.error("AirGPIO_1000.setup", "invalid gpio_mode", type(gpio_mode), gpio_mode)
        return false
    end    

    log.info("AirGPIO_1000.setup", "enter", gpio_id, type(gpio_mode), gpio_mode)


    --根据扩展GPIO ID识别当前扩展GPIO使用的配置寄存器地址
    --0x0x开头的ID为REG_CONFIG_0,0x01开头的ID为REG_CONFIG_1
    local reg_addr = ((gpio_id>>4) == 0) and REG_CONFIG_0 or REG_CONFIG_1
    --读取从机中输出寄存器当前的值
    local reg_data = read_register(reg_addr)

    if reg_data==nil then
        log.error("AirGPIO_1000.setup", "read config register error", reg_addr)
        return false
    end    

    local mask = 1<<(gpio_id&0x0F)
    local value
    --GPIO配置为输出模式
    if gpio_mode==0 or gpio_mode==1 then
        value = reg_data & (~mask)
    --GPIO配置为输入模式
    elseif gpio_mode==nil or type(gpio_mode)=="function" then
        value = reg_data | mask
    end

    --如果寄存器新值和旧值相比,发生变化
    --写新值到从机的配置寄存器中
    if reg_data~=value then
        if not write_register(reg_addr, value) then
            log.error("AirGPIO_1000.setup", "config write error", reg_addr, value)
            return false
        end
    end

    log.info("AirGPIO_1000.setup", "config", reg_addr, reg_data, value)

    --如果是中断模式,并且用户注册了中断处理函数
    if type(gpio_mode)=="function" then
        if AirGPIO_1000.ints==nil then
            AirGPIO_1000.ints = {}
        end
        if AirGPIO_1000.ints[gpio_id]==nil then
            AirGPIO_1000.ints[gpio_id] = {}
        end
        --存储中断处理函数
        AirGPIO_1000.ints[gpio_id].cb_func = gpio_mode
        --读取当前时刻GPIO的输入电平状态
        AirGPIO_1000.ints[gpio_id].old_level = AirGPIO_1000.get(gpio_id)
    end

    --如果配置的是输入模式或者中断模式,可以直接返回了
    if gpio_mode~=0 and gpio_mode~=1 then return true end


    --如果配置的输出模式,初始化输出的电平为gpio_mode
    if not AirGPIO_1000.set(gpio_id, gpio_mode) then
        log.error("AirGPIO_1000.setup", "output set error")
        return false
    end

    log.info("AirGPIO_1000.setup", "output", reg_addr, reg_data, value)

    return true    
end



--设置AirGPIO_1000上配置为输出模式的扩展GPIO的输出电平

--gpio_id:number类型;
--         表示AirGPIO_1000上的扩展GPIO ID;
--         取值范围:0x00到0x07,0x10到0x17,一共16种,分别对应16个扩展GPIO引脚;
--         必须传入,不允许为空;
--output_level:number类型;
--              表示配置为输出模式的扩展GPIO对外输出的电平;
--              取值范围:0和1,0表示输出低电平,1表示输出高电平;
--              必须传入,不允许为空;

--返回值:成功返回true,失败返回false
function AirGPIO_1000.set(gpio_id, output_level)
    --检查参数的合法性
    if not check_gpio_id_valid(gpio_id) then
        log.error("AirGPIO_1000.set", "invalid gpio_id", gpio_id)
        return false
    end

    if not (output_level==0 or output_level==1) then
        log.error("AirGPIO_1000.set", "invalid output_level", type(output_level), output_level)
        return false
    end    

    log.info("AirGPIO_1000.set", "enter", gpio_id, output_level)

    --根据扩展GPIO ID识别当前扩展GPIO使用的输出寄存器地址
    --0x0x开头的ID为REG_OUTPUT_PORT_0,0x01开头的ID为REG_OUTPUT_PORT_1
    local reg_addr = ((gpio_id>>4) == 0) and REG_OUTPUT_PORT_0 or REG_OUTPUT_PORT_1
    --读取从机中输出寄存器当前的值
    local reg_data = read_register(reg_addr)

    if reg_data==nil then
        log.error("AirGPIO_1000.set", "read output register error", reg_addr)
        return false
    end    

    local mask = 1<<(gpio_id&0x0F)
    local value

    --输出低电平
    if output_level==0 then
        value = reg_data & (~mask)
    --输出高电平
    elseif output_level==1 then
        value = reg_data | mask
    end

    --如果寄存器新值和旧值相比,发生变化
    --写新值到从机的输出寄存器中
    if reg_data~=value then
        if not write_register(reg_addr, value) then
            log.error("AirGPIO_1000.set", "output write error", reg_addr, value)
            return false
        end
    end

    log.info("AirGPIO_1000.set", "output", reg_addr, reg_data, value)

    return true
end


--读取AirGPIO_1000上配置为输入或者中断模式的扩展GPIO的输入电平

--gpio_id:number类型;
--         表示AirGPIO_1000上的扩展GPIO ID;
--         取值范围:0x00到0x07,0x10到0x17,一共16种,分别对应16个扩展GPIO引脚;
--         必须传入,不允许为空;

--返回值:number类型,表示输入的电平,0表示低电平,1表示高电平;如果读取失败,返回false
function AirGPIO_1000.get(gpio_id)
    --检查参数的合法性
    if not check_gpio_id_valid(gpio_id) then
        log.error("AirGPIO_1000.get", "invalid gpio_id", gpio_id)
        return false
    end

    --根据扩展GPIO ID识别当前扩展GPIO使用的输入寄存器地址
    --0x0x开头的ID为REG_INPUT_PORT_0,0x01开头的ID为REG_INPUT_PORT_1
    local reg_addr = ((gpio_id>>4) == 0) and REG_INPUT_PORT_0 or REG_INPUT_PORT_1
    --读取从机中输入寄存器当前的值
    local value = read_register(reg_addr)

    if not value then
        log.error("AirGPIO_1000.get", "read_register error", reg_addr)
        return false
    end

    --返回输入寄存器的值和GPIO对应的bit位的值
    return ((value>>(gpio_id&0x0F)) & 0x01)
end

6.6.6 关闭AirGPIO_1000上的扩展GPIO功能

--关闭AirGPIO_1000上的扩展GPIO功能
--实际上是恢复为默认状态(配置为输入)

--gpio_id:number类型;
--         表示AirGPIO_1000上的扩展GPIO ID;
--         取值范围:0x00到0x07,0x10到0x17,一共16种,分别对应16个扩展GPIO引脚;
--         必须传入,不允许为空;

--返回值:成功返回true,失败返回false
function AirGPIO_1000.close(gpio_id)
    local result = AirGPIO_1000.setup(gpio_id)

    if not result then
        log.error("AirGPIO_1000.close", "error", gpio_id)
    end

    return result
end

七、运行结果展示

(1) 通过万用表或者示波器检测AirGPIO_1000配件板上的P00电平,持续1秒输出0V的低电平,持续1秒输出3.3V的高电平,循环输出,表示GPIO输出测试正常;

(2) 通过观察Luatools的运行日志,首先打印 air_gpio.get(0x11) 0, 再隔一秒打印 air_gpio.get(0x11) 1,再隔一秒打印 air_gpio.get(0x11) 0,如此循环输出,表示GPIO输入测试正常;

(3) 通过观察Luatools的运行日志,首先打印 P04_int_cbfunc 4 0 P14_int_cbfunc 20 0, 再隔一秒打印 P04_int_cbfunc 4 1 P14_int_cbfunc 20 1,再隔一秒打印 P04_int_cbfunc 4 0 P14_int_cbfunc 20 0,如此循环输出,表示GPIO中断测试正常;

出现类似于下面的日志,就表示运行成功:

[2025-09-24 16:15:09.221][000000054.571] I/user.air_gpio.get(0x11) 1
[2025-09-24 16:15:09.223][000000054.572] I/user.AirGPIO_1000.set enter 16 0
[2025-09-24 16:15:09.223][000000054.573] I/user.AirGPIO_1000.set output 3 255 254
[2025-09-24 16:15:09.228][000000054.573] I/user.gpio_int_callback
[2025-09-24 16:15:09.290][000000054.635] I/user.AirGPIO_1000.set enter 3 0
[2025-09-24 16:15:09.290][000000054.636] I/user.AirGPIO_1000.set output 2 254 246
[2025-09-24 16:15:09.295][000000054.636] I/user.AirGPIO_1000.set enter 19 0
[2025-09-24 16:15:09.300][000000054.637] I/user.AirGPIO_1000.set output 3 254 246
[2025-09-24 16:15:09.300][000000054.638] I/user.gpio_int_callback
[2025-09-24 16:15:09.305][000000054.639] I/user.P04_int_cbfunc 4 0
[2025-09-24 16:15:09.310][000000054.640] I/user.P14_int_cbfunc 20 0
[2025-09-24 16:15:10.184][000000055.532] I/user.AirGPIO_1000.set enter 0 1
[2025-09-24 16:15:10.187][000000055.533] I/user.AirGPIO_1000.set output 2 246 247
[2025-09-24 16:15:10.228][000000055.573] I/user.air_gpio.get(0x11) 0
[2025-09-24 16:15:10.228][000000055.574] I/user.AirGPIO_1000.set enter 16 1
[2025-09-24 16:15:10.233][000000055.575] I/user.AirGPIO_1000.set output 3 246 247
[2025-09-24 16:15:10.238][000000055.575] I/user.gpio_int_callback
[2025-09-24 16:15:10.288][000000055.638] I/user.AirGPIO_1000.set enter 3 1
[2025-09-24 16:15:10.288][000000055.639] I/user.AirGPIO_1000.set output 2 247 255
[2025-09-24 16:15:10.293][000000055.639] I/user.AirGPIO_1000.set enter 19 1
[2025-09-24 16:15:10.298][000000055.640] I/user.AirGPIO_1000.set output 3 247 255
[2025-09-24 16:15:10.298][000000055.641] I/user.gpio_int_callback
[2025-09-24 16:15:10.305][000000055.642] I/user.P04_int_cbfunc 4 1
[2025-09-24 16:15:10.308][000000055.643] I/user.P14_int_cbfunc 20 1
[2025-09-24 16:15:11.190][000000056.534] I/user.AirGPIO_1000.set enter 0 0
[2025-09-24 16:15:11.200][000000056.535] I/user.AirGPIO_1000.set output 2 255 254

八、总结

通过本章内容的学习,你可以学习到Air8000核心板+AirGPIO_1000配件板,通过I2C转16路GPIO功能(输出、输入和中断)的应用。