跳转至

exs_pca9555 扩展库

作者:沈园园 | 最后修改:2026-07-30

一、概述

exs_pca9555 是 NXP PCA9555 16 位 I2C GPIO 扩展芯片的 LuatOS 扩展库。PCA9555 提供 16 位并行 I/O 扩展,通过 I2C 串行接口与主控通信,广泛应用于需要额外 GPIO 的场景。

PCA9555 提供 2 个 8 位端口(Port 0 和 Port 1),共 16 个 GPIO,支持输入、输出和中断三种工作模式,并支持极性反转功能。

1.1 主要特性

  • 16 个 I/O 引脚,分为 2 组 8 位端口(Port 0: P0.0~P0.7,Port 1: P1.0~P1.7)

  • 每个 I/O 可独立配置为输入或输出模式

  • 支持 INT 中断引脚,输入电平变化时触发中断通知主控

  • 支持极性反转寄存器,适应不同硬件设计需求

  • I2C 接口速率可达 400kHz

  • 3 个硬件地址引脚(A0、A1、A2),支持 8 种 I2C 地址(0x20~0x27)

  • 工作电压 2.3V~5.5V

  • 工作温度 -40℃~+85℃

1.2 加载方式

-- 扩展库需要 require 加载后才能调用
local exs_pca9555 = require "exs_pca9555"

1.3 注意事项

  • I2C 上拉电阻:SDA 和 SCL 需外接 4.7kΩ~10kΩ 上拉电阻到 VCC

  • INT 引脚:PCA9555 的 INT 引脚为开漏输出,需外接上拉电阻

  • GPIO ID 编码规则

  • 0x00 ~ 0x07:Port 0 的 P0.0 ~ P0.7
  • 0x10 ~ 0x17:Port 1 的 P1.0 ~ P1.7

  • 中断模式:使用中断功能时,必须在 init() 中传入 gpio_int_id 参数,并将 PCA9555 的 INT 引脚连接到主机的对应 GPIO

  • 多设备支持:通过 A0、A1、A2 引脚配置不同 I2C 地址,最多可在同一 I2C 总线上连接 8 个 PCA9555 设备

1.4 硬件连接

  ┌──────────────┐                    ┌──────────────────┐
  │    主控      │                    │    PCA9555       │
  │  (AirXXX)    │                    │  GPIO 扩展芯片   │
  │              │                    │                  │
  │ I2C_SDA ─────┼────────────────────┼──→ SDA           │
  │              │                    │  (需外接上拉电阻)│
  │ I2C_SCL ─────┼────────────────────┼──→ SCL           │
  │              │                    │  (需外接上拉电阻)│
  │ GPIO_INT ←───┼────────────────────┼──→ INT           │
  │              │                    │  (开漏输出,     │
  │              │                    │   需外接上拉电阻)│
  │              │                    │                  │
  │ VCC 3V3 ─────┼────────────────────┼──→ VCC           │
  │              │                    │                  │
  │ GND      ────┼────────────────────┼──→ GND           │
  │              │                    │                  │
  │              │                    │ A0~A2 ──────────┼──→ 地址配置
  │              │                    │                  │
  │              │                    │ P0.0~P0.7 ──────┼──→ 扩展 GPIO 端口0
  │              │                    │ P1.0~P1.7 ──────┼──→ 扩展 GPIO 端口1
  └──────────────┘                    └──────────────────┘

1.5 寄存器映射

寄存器 地址 位 7 位 6 位 5 位 4 位 3 位 2 位 1 位 0
Input Port 0 0x00 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0
Input Port 1 0x01 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
Output Port 0 0x02 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0
Output Port 1 0x03 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
Polarity Inversion 0 0x04 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0
Polarity Inversion 1 0x05 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
Configuration 0 0x06 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0
Configuration 1 0x07 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0

Configuration 寄存器说明:1 = 输入模式,0 = 输出模式

Polarity Inversion 寄存器说明:1 = 极性反转,0 = 正常


二、核心示例

  • 核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码

  • 核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单

  • 更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/sensor/PCA9555

2.1 GPIO 输出示例

-- 加载扩展库
local exs_pca9555 = require "exs_pca9555"

-- 应用主函数
local function pca9555_output_demo()
    -- 初始化 PCA9555(使用 I2C1)
    local result = exs_pca9555.init(1)

    if not result then
        log.error("exs_pca9555", "PCA9555 初始化失败")
        return
    end
    log.info("exs_pca9555", "PCA9555 初始化成功")

    -- 配置 P0.0 为输出模式,初始输出低电平
    exs_pca9555.setup(0x00, 0)

    -- 循环切换 P0.0 电平
    while true do
        exs_pca9555.set(0x00, 0)  -- 输出低电平
        sys.wait(1000)
        exs_pca9555.set(0x00, 1)  -- 输出高电平
        sys.wait(1000)
    end
end

-- 启动任务
sys.taskInit(pca9555_output_demo)

2.2 GPIO 输入示例

-- 加载扩展库
local exs_pca9555 = require "exs_pca9555"

-- 应用主函数
local function pca9555_input_demo()
    -- 初始化 PCA9555
    local result = exs_pca9555.init(1)

    if not result then
        log.error("exs_pca9555", "PCA9555 初始化失败")
        return
    end

    -- 配置 P1.0 为输出模式(用于产生测试信号)
    exs_pca9555.setup(0x10, 0)

    -- 配置 P1.1 为输入模式
    exs_pca9555.setup(0x11)

    -- 循环读取 P1.1 电平
    -- 注意:需将 P1.0 和 P1.1 短接
    while true do
        exs_pca9555.set(0x10, 0)
        sys.wait(1000)
        local level = exs_pca9555.get(0x11)
        log.info("exs_pca9555", "P1.1 电平:", level)

        exs_pca9555.set(0x10, 1)
        sys.wait(1000)
        level = exs_pca9555.get(0x11)
        log.info("exs_pca9555", "P1.1 电平:", level)
    end
end

sys.taskInit(pca9555_input_demo)

2.3 GPIO 中断示例

-- 加载扩展库
local exs_pca9555 = require "exs_pca9555"

-- P0.4 中断回调函数
-- id:触发中断的 GPIO ID
-- level:触发中断后读取到的电平(0=低,1=高)
local function P04_int_cbfunc(id, level)
    log.info("exs_pca9555", "P0.4 中断触发,ID:", id, "电平:", level)
end

-- 应用主函数
local function pca9555_int_demo()
    -- 初始化 PCA9555,使用 GPIO2 作为中断引脚
    local result = exs_pca9555.init(1, 2)

    if not result then
        log.error("exs_pca9555", "PCA9555 初始化失败")
        return
    end

    -- 配置 P0.3 为输出模式(用于触发 P0.4 中断)
    exs_pca9555.setup(0x03, 0)

    -- 配置 P0.4 为中断模式
    -- 注意:需将 P0.3 和 P0.4 短接
    exs_pca9555.setup(0x04, P04_int_cbfunc)

    -- 循环切换 P0.3 电平,触发 P0.4 中断
    while true do
        exs_pca9555.set(0x03, 0)
        sys.wait(1000)
        exs_pca9555.set(0x03, 1)
        sys.wait(1000)
    end
end

sys.taskInit(pca9555_int_demo)

2.4 多 GPIO 批量控制示例

local exs_pca9555 = require "exs_pca9555"

exs_pca9555.init(1)

-- 批量配置 Port 0 为输出,Port 1 为输入
for i = 0, 7 do
    exs_pca9555.setup(0x00 + i, 0)  -- P0.0~P0.7 输出模式
    exs_pca9555.setup(0x10 + i)     -- P1.0~P1.7 输入模式
end

-- 流水灯效果
local function led_chase()
    while true do
        for i = 0, 7 do
            exs_pca9555.set(0x00 + i, 1)
            sys.wait(100)
            exs_pca9555.set(0x00 + i, 0)
        end
    end
end

sys.taskInit(led_chase)

三、常量解释

扩展库常量,顾名思义是由合宙 LuatOS 扩展库中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用,本扩展库没有常量。


四、函数详解

4.1 初始化与控制

4.1.1 exs_pca9555.init(i2c_id, gpio_int_id)

功能

初始化 PCA9555,配置 I2C 通信参数,自动识别从设备地址

参数

i2c_id

参数含义:主机使用的 I2C ID,用来控制 PCA9555
数据类型:number
取值范围:平台有效的 I2C 总线编号(如 0 或 1)
是否必选:是
注意事项:调用前必须先用 i2c.setup(i2c_id, i2c.FAST) 初始化该总线
参数示例:1

gpio_int_id

参数含义:主机使用的中断引脚 GPIO ID,与 PCA9555 的 INT 引脚相连
数据类型:number
取值范围:有效的 GPIO 编号
是否必选:否
注意事项:可选,不传则不使用中断通知功能。传入后,PCA9555 上配置为中断模式的 GPIO 电平变化时,会通过 INT 引脚触发主机中断
参数示例:2

返回值

local init_result = exs_pca9555.init(i2c_id, gpio_int_id)

init_result

含义说明:初始化是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:初始化失败时请检查接线、供电和 I2C 地址配置
返回示例:true

示例

-- 基础初始化(不使用中断)
local result = exs_pca9555.init(1)

-- 使用中断功能(主机 GPIO2 作为中断引脚)
local result = exs_pca9555.init(1, 2)

4.1.2 exs_pca9555.deinit()

功能

关闭 PCA9555 通信,释放所有资源(I2C、GPIO、中断表)

参数

返回值

local result = exs_pca9555.deinit()

result

含义说明:释放是否成功
数据类型:boolean
取值范围:true(成功)
注意事项:释放后所有 GPIO 配置将失效,如需使用需重新 init
返回示例:true

示例

exs_pca9555.deinit()

4.2 GPIO 配置与操作

4.2.1 exs_pca9555.setup(gpio_id, gpio_mode)

功能

配置 PCA9555 扩展 GPIO 管脚功能,支持输出、输入和中断三种模式

参数

gpio_id

参数含义:PCA9555 上的扩展 GPIO ID
数据类型:number
取值范围:
  - 0x00 ~ 0x07:Port 0 的 P0.0 ~ P0.7
  - 0x10 ~ 0x17:Port 1 的 P1.0 ~ P1.7
是否必选:是
注意事项:超出范围将返回错误
参数示例:0x00

gpio_mode

参数含义:GPIO 工作模式,支持三种类型
数据类型:number | function | nil
取值说明:
  - number (0):输出模式,默认输出低电平
  - number (1):输出模式,默认输出高电平
  - nil 或不传:输入模式
  - function:中断模式,参数为回调函数
    回调函数格式:function cb_func(id, level) end
    - id:触发中断的 GPIO ID(number 类型)
    - level:触发中断后读取到的电平(0=低,1=高)
是否必选:是
注意事项:中断模式需要在 init() 中传入 gpio_int_id 参数
参数示例:0

返回值

local result = exs_pca9555.setup(gpio_id, gpio_mode)

result

含义说明:配置是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:配置中断模式时,需确保 init() 已配置 gpio_int_id
返回示例:true

示例

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

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

-- GPIO 0x04 配置为中断模式
local function P04_int_cbfunc(id, level)
    log.info("P04_int_cbfunc", id, level)
end
exs_pca9555.setup(0x04, P04_int_cbfunc)

4.2.2 exs_pca9555.set(gpio_id, output_level)

功能

设置 PCA9555 扩展 GPIO 的输出电平

参数

gpio_id

参数含义:PCA9555 上的扩展 GPIO ID
数据类型:number
取值范围:0x00~0x07 或 0x10~0x17
是否必选:是
注意事项:必须先通过 setup() 配置为输出模式
参数示例:0x03

output_level

参数含义:输出电平
数据类型:number
取值范围:0(低电平)或 1(高电平)
是否必选:是
注意事项:只有配置为输出模式的 GPIO 才能设置电平
参数示例:1

返回值

local result = exs_pca9555.set(gpio_id, output_level)

result

含义说明:设置是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:
返回示例:true

示例

-- GPIO 0x03 输出高电平
exs_pca9555.set(0x03, 1)

-- GPIO 0x13 输出低电平
exs_pca9555.set(0x13, 0)

4.2.3 exs_pca9555.get(gpio_id)

功能

读取 PCA9555 扩展 GPIO 的输入电平

参数

gpio_id

参数含义:PCA9555 上的扩展 GPIO ID
数据类型:number
取值范围:0x00~0x07 或 0x10~0x17
是否必选:是
注意事项:
参数示例:0x11

返回值

local level = exs_pca9555.get(gpio_id)

level

含义说明:GPIO 输入电平
数据类型:number 或 boolean
取值范围:0(低电平),1(高电平);读取失败返回 false
注意事项:
返回示例:1

示例

-- 读取 GPIO 0x11 的输入电平
local level = exs_pca9555.get(0x11)
if level ~= false then
    log.info("exs_pca9555", "GPIO 0x11 电平:", level)
end

4.2.4 exs_pca9555.close(gpio_id)

功能

关闭 PCA9555 扩展 GPIO 功能,恢复为默认输入模式

参数

gpio_id

参数含义:PCA9555 上的扩展 GPIO ID
数据类型:number
取值范围:0x00~0x07 或 0x10~0x17
是否必选:是
注意事项:
参数示例:0x03

返回值

local result = exs_pca9555.close(gpio_id)

result

含义说明:关闭是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:
返回示例:true

示例

exs_pca9555.close(0x03)

4.3 极性反转

4.3.1 exs_pca9555.set_polarity(gpio_id, invert)

功能

设置 PCA9555 扩展 GPIO 的极性反转

极性反转后,引脚实际为高电平时读取为 0,实际为低电平时读取为 1。适用于需要反相读取的硬件设计场景。

参数

gpio_id

参数含义:PCA9555 上的扩展 GPIO ID
数据类型:number
取值范围:0x00~0x07 或 0x10~0x17
是否必选:是
注意事项:
参数示例:0x02

invert

参数含义:是否反转极性
数据类型:boolean
取值范围:true(反转)、false(正常)
是否必选:是
注意事项:极性反转仅影响输入读取,不影响输出
参数示例:true

返回值

local result = exs_pca9555.set_polarity(gpio_id, invert)

result

含义说明:设置是否成功
数据类型:boolean
取值范围:true(成功), false(失败)
注意事项:
返回示例:true

示例

-- 反转 GPIO 0x02 的极性
exs_pca9555.set_polarity(0x02, true)

-- 恢复正常极性
exs_pca9555.set_polarity(0x02, false)

4.4 版本管理

4.4.1 exs_pca9555.version()

功能

获取 exs_pca9555 库的版本号

参数

返回值

local ver = exs_pca9555.version()

ver

含义说明:版本号字符串
数据类型:string
取值范围:格式 "yyyymmddhhmm",表示 yyyy年mm月dd日hh时mm分发布的版本
注意事项:无
返回示例:"202607282000"

示例

local ver = exs_pca9555.version()
log.info("exs_pca9555", "版本号:", ver)

五、版本更新说明

版本号:202607282000

  1. 更新时间:2026-07-28
  2. 更新内容:

    • 第一版,实现 PCA9555 基础驱动功能
    • 自动识别从设备地址功能(扫描 0x20~0x27)
    • 支持 16 个 GPIO 的输入、输出配置
    • 支持设置GPIO 的输出电平
    • 支持读取GPIO 的输入电平
    • 支持 GPIO 中断模式支持(通过 INT 引脚 + sys.publish 机制)

六、产品支持说明

所有支持 luatos 二次开发的模块,具体可以查看选型手册

搜索
AirMaster 实时解答