跳转至

08 pins

作者:马亚丹 | 最后修改:2026-04-13

一、pins 核心库

合宙 pins 核心库是针对合宙嵌入式硬件平台设计的硬件引脚管理工具库,主要用于简化硬件引脚的配置与操作,是合宙 Lua 脚本开发环境中控制硬件外设的基础库之一。

pins 核心库的 API 属于高级用法, 仅动态配置管脚时使用,这个功能是为了动态修改管脚复用。

通常使用 LuaTools 的可视化工具 https://docs.openluat.com/air780epm/common/luatio/进行管脚配置,仅动态配置管脚时才会使用到本库。

本库是专门用于管理合宙模组管脚外设复用、硬件配置加载与调试的核心工具库,核心作用是实现 “管脚功能灵活分配” 与 “硬件配置高效管理”,适配不同外设(如 UART、I2C、GPIO 等)的使用需求,具体可拆解为 3 个核心能力:

核心作用 1:管脚外设复用配置(最核心功能)

合宙模组的管脚支持 “复用”(同一管脚可对应不同外设功能,如某管脚既可选作 GPIO,也可选作 UART_TX),pins.setup() 函数是实现这一功能的关键,作用是在启用外设前,指定管脚的具体外设功能,确保外设能正常工作。

  • 支持的外设类型:涵盖常见硬件接口,包括 “UART(串口)、I2C(两线式串行总线)、SPI(串行外设接口)、PWM(脉冲宽度调制)、CAN(控制器局域网)、GPIO(通用输入输出)、ONEWIRE(单总线)”。
  • 实际用途:比如将 Air780EPM 的 PIN67 脚配置为 “GPIO18”(用于简单的高低电平控制),或把 PIN55/PIN56 分别配置为 “UART2_RX”“UART2_TX”(用于串口通信),满足不同硬件交互需求。

核心作用 2:管脚状态重置与安全控制

当某个管脚不再使用时,pins.close() 函数可将其设置为高阻态或输入态,避免管脚持续对外输出信号干扰其他电路,起到 “释放管脚资源、保障电路安全” 的作用。

  • 例如:Air780EPM 的 PIN67 脚使用完 GPIO 功能后,调用 pins.close(67),该管脚会停止对外输出,避免误触发其他硬件模块。

核心作用 3:调试辅助(问题排查)

pins.debug() 函数可开启 / 关闭调试模式,开启后会输出更多管脚配置相关的日志,作用是帮助开发者排查管脚配置失败的原因。

下面就跟着教程用合宙模组实际操作演示一下 pins 核心库的实际应用。

二、功能演示概述

本文演示合宙 4G 模组使用 LuatOS 开发时, pins 核心库的功能应用.

使用 Air780EHV 核心板下载 Air780EHV 的 LuatOS 示例代码中 pins 的例程进行验证,例程中演示了两种使用方式,核心业务逻辑为:

pins_default.lua:

1.烧录管脚配置文件 pins_air780ehv.json 配置管脚功能

2.烧录 pins_air780ehv.json 前,

pin28 默认功能是 UART2_RXD

pin29 默认功能是 UART2_TXD

pin55 默认功能是 CAM_RX0

pin56 默认功能是 CAM_RX1

烧录了 pins_air780ehv.json 后,在内核固件运行时,已经自动加载 pins_air780ehv.json,并且按照 pins_air780ehv.json 的配置初始化所有 io 引脚功能,

文件中把 pin28 由原 UART2_RXD 功能配置为 GPIO12,

pin29 由原 UART2_TXD 功能配置为 GPIO13,

pin55 由原 CAM_RX0 功能配置为 UART2_RXD,

pin56 由原 CAM_RX1 功能配置为 UART2_TXD,

3.演示重新配置的串口管脚的功能,通过串口工具收发数据。

pins_dynamic.lua:

1.加载自定义的管脚配置文件 my.json 配置管脚功能

文件中配置

pin28 功能是 UART2_RXD

pin29 功能是 UART2_TXD

pin55 功能是 CAM_RX0

pin56 功能是 CAM_RX1

2.通过 pins.setup 接口动态修改管脚复用功能,

这里演示把 pin28 由原 UART2_RXD 功能配置为 GPIO12,

pin29 由原 UART2_TXD 功能配置为 GPIO13,

pin55 由原 CAM_RX0 功能配置为 UART2_RXD,

pin56 由原 CAM_RX1 功能配置为 UART2_TXD,

3.演示重新配置的串口管脚的功能,通过串口工具收发数据。

三、准备硬件环境

3.1 参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。

3.2 TYPE-C USB 数据线一根 ,Air780EHV 核心板和数据线的硬件接线方式为:

  • Air780EHV 核心板通过 TYPE-C USB 口供电;(外部供电/USB 供电 拨动开关 拨到 USB 供电一端)
  • TYPE-C USB 数据线直接插到开发板的 TYPE-C USB 座子,另外一端连接电脑 USB 口;

3.3 USB 转 TTL 串口线一根,串口线 usb 口连接电脑 USB 口,Air780EHV 核心板和串口线,按以下方式接线:

Air780EHV核心板
串口线
pin55/CAM_RX0
uart_tx
pin56/CAM_RX1
uart_rx
GND
GND

四、准备软件环境

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

  1. Luatools 工具,如果是第一次使用 Luatools 工具,请仔细阅读此链接教程。

  2. SSCOM 串口通信工具,请仔细阅读此链接教程

  3. 内核固件文件(底层 core 固件文件):

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

  4. luatos 需要的脚本和资源文件:LuatOS: Powerful embedded Lua Engine for loT devices, withmany components - Gitee.com

    main.lua:主程序入口。

    my.json: 自定义管脚配置示例文件,用于演示 pins.loadjson(path)接口加载自定义管脚配置文件的功能,该文件手动编写容易出错,建议使用合宙 LuatIO 可视化工具 LuatIO 初始化配置工具 自动生成。

    pins_air780ehv.json: Air780EHV 核心板管脚配置示例文件,底层自动加载该文件完成管脚配置,使用合宙 LuatIO 可视化工具自动生成。

    pins_default.lua:功能演示模块,在 main.lua 中加载运行。

    pins_dynamic.lua:功能演示模块,在 main.lua 中加载运行。

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

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

五、API 接口说明

六、示例代码和功能展示

6.1 流程介绍

1、搭建好硬件环境

2、main.lua 中加载 pins_default.lua 或者 pins_dynamic.lua

3、Luatools 烧录内核固件和 main.lua、pins_default.lua和pins_Air780EHV.json、或者 pins_dynamic.lua和my.json 脚本代码。

4、烧录成功后,自动开机运行,查看打印日志,如果正常运行,会打印管脚配置结果、数据发送等日志。

6.2 代码和 log

main.lua 代码示例

点击查看 pins 的完整 demo)

PROJECT = "Air780EHV/EHV/EGH_pins"
VERSION = "001.000.000"


-- 在日志中打印项目名和项目版本号
log.info("main", PROJECT, VERSION)


-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
if wdt then
    --配置喂狗超时时间为9秒钟
    wdt.init(9000)
    --启动一个循环定时器,每隔3秒钟喂一次狗
    sys.timerLoopStart(wdt.feed, 3000)
end


-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
-- 启动errDump日志存储并且上传功能,600秒上传一次
-- if errDump then
--     errDump.config(true, 600)
-- end


-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
-- 可以使用合宙的iot.openluat.com平台进行远程升级
-- 也可以使用客户自己搭建的平台进行远程升级
-- 远程升级的详细用法,可以参考fota的demo进行使用


-- 启动一个循环定时器
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
-- 方便分析内存使用是否有异常
-- sys.timerLoopStart(function()
--     log.info("mem.lua", rtos.meminfo())
--     log.info("mem.sys", rtos.meminfo("sys"))
-- end, 3000)





--加载"pins_default"功能模块
-- require"pins_default"

--加载"pins_dynamic"功能模块
require"pins_dynamic"

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

pins_default.lua 核心代码

点击查看 pins 的完整 demo)

--如果需要debug,在任何需要的地方添加这一行
--log.info ("打开debug",pins.debug(true))

--如果打开debug后需要关闭debug,在任何需要的地方添加这一行
--log.info ("打开debug",pins.debug(false))

--烧录pins_Air780EHV.json前,
--pin28默认功能是UART2_RXD
--pin29默认功能是UART2_TXD
--pin55默认功能是CAM_RX0
--pin56默认功能是CAM_RX1

--烧录了pins_Air780EHV.json后,在内核固件运行时,已经自动加载pins_Air780EHV.json,并且按照pins_Air780EHV.json的配置初始化所有io引脚功能,
--文件中把pin28由原UART2_RXD功能配置为GPIO12,
--pin29由原UART2_TXD功能配置为GPIO13,
--pin55由原CAM_RX0功能配置为UART2_RXD,
--pin56由原CAM_RX1功能配置为UART2_TXD,





--如果需要debug,在任何需要的地方添加这一行
--log.info ("打开debug",pins.debug(true))

--如果打开debug后需要关闭debug,在任何需要的地方添加这一行
--log.info ("打开debug",pins.debug(false))







--========验证复用的管脚的功能=========--
local uartid = 2

--初始化 参数都可以根据实施情况修改
uart.setup(
--串口id
    uartid,
    --波特率
    115200,
    8, --数据位
    1  --停止位
)

log.info("uart", "uart2配置完成")
local function ur_rec(id, len)
    local s = ""
    repeat
        s = uart.read(id, 128)
        -- #s 是取字符串的长度
        if #s > 0 then
            -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
            log.info("uart", "receive", id, #s, s)
            -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到,可以用以hex格式打印
            log.info("uart", "receive(hex)", id, #s, s:toHex())
        end
    until s == ""
end
-- 收取数据会触发回调, 这里的 "receive" 是固定值不要修改。
uart.on(uartid, "receive", ur_rec)


--向串口发送数据
local function uart_test()
    local n = 0
    while n < 10 do
        sys.wait(2000)
        log.info("这是第" .. n .. "次向串口发数据")
        -- 写入可见字符串
        --uart.write(uartid, "test data.")
        -- 写入十六进制字符串
        uart.write(uartid, string.char(0x55, 0xAA, 0x4B, 0x03, 0x86))
        n = n + 1
        sys.wait(2000)
    end
end



sys.taskInit(uart_test)
例程 log 打印如下:
[2025-11-10 10:56:02.315][000000000.233] D/pins /luadb/pins_air780ehv.json 加载和配置完成
[2025-11-10 10:56:02.321][000000000.236] D/main loadlibs luavm 4194296 16096 16096
[2025-11-10 10:56:02.328][000000000.236] D/main loadlibs sys   3211688 104004 113640
[2025-11-10 10:56:02.332][000000000.236] D/main loadlibs psram 3211688 104112 113640
[2025-11-10 10:56:02.339][000000000.256] I/user.main Air780EHV/EHV/EGH_pins 001.000.000
[2025-11-10 10:56:02.344][000000000.262] Uart_ChangeBR 1338:uart2, 115200 115203 26000000 3611
[2025-11-10 10:56:02.347][000000000.262] I/user.uart uart2配置完成
[2025-11-10 10:56:03.889][000000002.262] I/user.这是第0次向串口发数据
[2025-11-10 10:56:07.880][000000006.263] I/user.这是第1次向串口发数据
[2025-11-10 10:56:11.881][000000010.263] I/user.这是第2次向串口发数据
[2025-11-10 10:56:15.893][000000014.263] I/user.这是第3次向串口发数据
[2025-11-10 10:56:19.881][000000018.263] I/user.这是第4次向串口发数据
[2025-11-10 10:56:23.880][000000022.263] I/user.这是第5次向串口发数据
[2025-11-10 10:56:27.881][000000026.263] I/user.这是第6次向串口发数据
[2025-11-10 10:56:31.882][000000030.263] I/user.这是第7次向串口发数据
[2025-11-10 10:56:35.879][000000034.263] I/user.这是第8次向串口发数据
[2025-11-10 10:56:39.882][000000038.263] I/user.这是第9次向串口发数据
[2025-11-10 10:57:17.518][000000075.902] I/user.uart receive 2 11 123456789

[2025-11-10 10:57:17.528][000000075.902] I/user.uart receive(hex) 2 11 3132333435363738390D0A 22
[2025-11-10 10:57:18.404][000000076.781] I/user.uart receive 2 11 123456789

[2025-11-10 10:57:18.413][000000076.782] I/user.uart receive(hex) 2 11 3132333435363738390D0A 22
luatools 页面显示:

luatools 页面和 sscom 工具页面显示如下:图片中蓝框是 SSCOM 串口工具收到模组发来的消息,红框是模组收到 SSCOM 串口工具发来的消息。

pins_dynamic.lua 核心代码

点击查看 pins 的完整 demo)

--如果需要debug,在任何需要的地方添加这一行
--log.info ("打开debug",pins.debug(true))

--如果打开debug后需要关闭debug,在任何需要的地方添加这一行
--log.info ("打开debug",pins.debug(false))


--自定义配置文件要通过pins.loadjson加载
--如果烧录了pins_Air780EHV.json,在内核固件运行时,已经自动加载pins_Air780EHV.json,并且按照pins_Air780EHV.json的配置初始化所有io引脚功能,
--此处再加载my.json文件,会覆盖pins_Air780EHV.json中配置的所有io引脚功能,按照my.json的配置再次初始化所有io引脚功能,
--my.json文件中:
--pin28默认为UART2_RXD,
--pin29默认为UART2_TXD,
--pin55默认为CAM_RX0,
--pin56默认为CAM_RX1,
--通过下面的配置管脚复用的代码将这四个脚重新配置:
--pin28由默认UART2_RXD修改配置为GPIO12,
--pin29由默认UART2_TXD修改配置为GPIO13,
--pin55由默认CAM_RX0配置为UART2_RXD,
--pin56由默认CAM_RX1配置为UART2_TXD

--烧录多个.json文件时以最后一个文件的配置初始化所有io引脚功能
log.info("加载自定义的配置文件", pins.loadjson("/luadb/my.json"))

--=======配置管脚复用=========--

log.info("uart", "重新配置uart2到新管脚")
uart.close(2)
local r1 = pins.setup(28, "GPIO12")
log.info("配置pin28脚即UART2_RXD为GPIO12", r1)
local r2 = pins.setup(29, "GPIO13")
log.info("配置pin29脚即UART2_TXD为GPIO13", r2)
gpio.close(12)
gpio.close(13)

local r3 = pins.setup(55, "UART2_RX")
log.info("配置pin55脚即CAM_RX0为UART2_RXD", r3)
local r4 = pins.setup(56, "UART2_TX")
log.info("配置pin56脚即CAM_RX1为UART2_TXD", r4)



--========验证复用的管脚的功能=========--
local uartid = 2

--初始化 参数都可以根据实施情况修改
uart.setup(
--串口id
    uartid,
    --波特率
    115200,
    8, --数据位
    1  --停止位
)

log.info("uart", "uart2重新配置完成")
local function ur_rec(id, len)
    local s = ""
    repeat
        s = uart.read(id, 128)
        -- #s 是取字符串的长度
        if #s > 0 then
            -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
            log.info("uart", "receive", id, #s, s)
            -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到,可以用以hex格式打印
            log.info("uart", "receive(hex)", id, #s, s:toHex())
        end
    until s == ""
end
-- 收取数据会触发回调, 这里的 "receive" 是固定值不要修改。
uart.on(uartid, "receive", ur_rec)


--向串口发送数据
local function uart_test()
    local n = 0
    while n < 10 do
        sys.wait(2000)
        log.info("这是第" .. n .. "次向串口发数据")
        -- 写入可见字符串
        --uart.write(uartid, "test data.")
        -- 写入十六进制字符串
        uart.write(uartid, string.char(0x55, 0xAA, 0x4B, 0x03, 0x86))
        n = n + 1
        sys.wait(2000)
    end
end



sys.taskInit(uart_test)
例程 log 打印如下:
[2025-11-10 10:47:00.089][000000000.233] D/pins /luadb/pins_air780ehv.json 加载和配置完成
[2025-11-10 10:47:00.100][000000000.237] D/main loadlibs luavm 4194296 16096 16096
[2025-11-10 10:47:00.105][000000000.237] D/main loadlibs sys   3211688 104004 113640
[2025-11-10 10:47:00.110][000000000.237] D/main loadlibs psram 3211688 104112 113640
[2025-11-10 10:47:00.117][000000000.256] I/user.main Air780EHV/EHV/EGH_pins 001.000.000
[2025-11-10 10:47:00.124][000000000.269] I/user.加载自定义的配置文件 true 0
[2025-11-10 10:47:00.130][000000000.269] I/user.uart 重新配置uart2到新管脚
[2025-11-10 10:47:00.135][000000000.269] Uart_TxStop 1180:uart2,br 0
[2025-11-10 10:47:00.142][000000000.269] I/user.配置pin28脚即UART2_RXD为GPIO12 true
[2025-11-10 10:47:00.149][000000000.270] I/user.配置pin29脚即UART2_TXD为GPIO13 true
[2025-11-10 10:47:00.157][000000000.270] I/user.配置pin55脚即CAM_RX0为UART2_RXD true
[2025-11-10 10:47:00.162][000000000.270] I/user.配置pin56脚即CAM_RX1为UART2_TXD true
[2025-11-10 10:47:00.166][000000000.270] Uart_ChangeBR 1338:uart2, 115200 115203 26000000 3611
[2025-11-10 10:47:00.172][000000000.271] I/user.uart uart2重新配置完成
[2025-11-10 10:47:01.559][000000002.272] I/user.这是第0次向串口发数据
[2025-11-10 10:47:05.565][000000006.272] I/user.这是第1次向串口发数据
[2025-11-10 10:47:09.558][000000010.272] I/user.这是第2次向串口发数据
[2025-11-10 10:47:13.556][000000014.272] I/user.这是第3次向串口发数据
[2025-11-10 10:47:15.206][000000015.917] I/user.uart receive 2 11 123456789

[2025-11-10 10:47:15.214][000000015.918] I/user.uart receive(hex) 2 11 3132333435363738390D0A 22
[2025-11-10 10:47:16.336][000000017.042] I/user.uart receive 2 11 123456789

[2025-11-10 10:47:16.348][000000017.043] I/user.uart receive(hex) 2 11 3132333435363738390D0A 22
[2025-11-10 10:47:17.561][000000018.272] I/user.这是第4次向串口发数据
[2025-11-10 10:47:21.565][000000022.272] I/user.这是第5次向串口发数据
[2025-11-10 10:47:25.561][000000026.272] I/user.这是第6次向串口发数据
[2025-11-10 10:47:29.564][000000030.272] I/user.这是第7次向串口发数据
[2025-11-10 10:47:33.559][000000034.272] I/user.这是第8次向串口发数据
[2025-11-10 10:47:37.565][000000038.272] I/user.这是第9次向串口发数据
luatools 页面显示:

luatools 页面和 sscom 工具页面显示如下:图片中蓝框是 SSCOM 串口工具收到模组发来的消息,红框是模组收到 SSCOM 串口工具发来的消息。

七、总结

本文档主要介绍 4G 模组 LuatOS 开发中 pins 的应用。

结合 demo 例程讲解了 pins 使用基本原理,介绍了 pins 主要 API,旨在最简单的快速上手 Air780EHV 的 LuatOS 的 pins 应用.

八、常见问题

本教程主要是演示复用后的串口使用,如果收发失败,注意查看端口打开是否正确,波特率设置是否与脚本中初始化一致,串口线接线是否正确,串口线是否正常。