跳转至

UART - 串口操作库。

作者:魏健强

一、概述

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种常用的串行通信协议,广泛应用于单片机或各种嵌入式设备之间的通信;

二、核心示例

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

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

3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/uart;

local uartid = 1 -- 根据实际设备选取不同的uartid

uart_mode_zbuff = true -- 是否使用zbuff方式收发数据收发

if uart_mode_zbuff then
    local rxbuff = zbuff.create(10240) -- 接收数据的zbuff
    local txbuff = zbuff.create(10240) -- 发送数据的zbuff

    local function uart_cb(id, len)  -- 串口接收数据回调函数
        while 1 do
            log.info("uart", "缓冲区", uart.rxSize(id)) -- 缓冲区中的数据数量
            local len = uart.rx(id, rxbuff)
            if len <= 0 then
                break
            end
            log.info("uart", "receive", id, rxbuff:used(), rxbuff:toStr())
            rxbuff:seek(0)
        end
    end

    txbuff:write("测试数据")    -- 向发送数据的zbuff写入数据

    local uartid = 1 -- 根据实际设备选取不同的uartid

    -- 初始化
    uart.setup(uartid, -- 串口id
    115200, -- 波特率
    8, -- 数据位
    1, -- 停止位
    uart.NONE, -- 校验位,可选 uart.None/uart.Even/uart.Odd。默认 uart.None 无校验
    uart.LSB, -- 大小端,默认小端 uart.LSB, 可选 uart.MSB
    10240 -- 缓冲区大小,默认值1024,接收大数据时需要根据数据大小增大缓冲区
    )
    uart.on(uartid, "receive", uart_cb)

    sys.taskInit(function()
        -- 循环两秒向串口发一次数据
        while true do
            sys.wait(10000)
            --发送数据
            uart.tx(uartid, txbuff)
        end
    end)

else
    local function uart_cb(id, len)
        local s = ""
        repeat
            s = uart.read(id, 10240) -- 一次性读出所有缓冲区中的数据,避免分包
            if #s > 0 then -- #s 是取字符串的长度
                -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
                log.info("uart", "receive", id, #s, s)
                -- log.info("uart", "receive", id, #s, s:toHex()) --如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
            end
        until s == ""
    end

    -- 初始化
    uart.setup(uartid, -- 串口id
    115200, -- 波特率
    8, -- 数据位
    1, -- 停止位
    uart.NONE, -- 校验位,可选 uart.None/uart.Even/uart.Odd。默认 uart.None 无校验
    uart.LSB, -- 大小端,默认小端 uart.LSB, 可选 uart.MSB
    10240 -- 缓冲区大小,默认值1024,接收大数据时需要根据数据大小增大缓冲区
    )

    -- 收取数据会触发回调, 这里的"receive" 是固定值
    uart.on(uartid, "receive", uart_cb)

    sys.taskInit(function()
        -- 循环两秒向串口发一次数据
        while true do
            sys.wait(2000)
            uart.write(uartid, "test data.")
        end
    end)

end

三、常量详解

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

3.1 uart.Odd

常量含义:串口校验方式:奇校验;
数据类型:number
取值范围:1
示例代码: uart.setup(1, 115200, 8, 1, uart.Odd)

3.2 uart.Even

常量含义:串口校验方式:偶校验;
数据类型:number
取值范围:2
示例代码: uart.setup(1, 115200, 8, 1, uart.Even)

3.3 uart.None

常量含义:串口校验方式:无校验;
数据类型:number
取值范围:0
示例代码: uart.setup(1, 115200, 8, 1, uart.None)

3.4 uart.LSB

常量含义:数据存储方式:小端模式;
数据类型:number
取值范围:0
示例代码: uart.setup(1, 115200, 8, 1, uart.None, uart.LSB)

3.5 uart.MSB

常量含义:数据存储方式:大端模式;
数据类型:number
取值范围:1
示例代码: uart.setup(1, 115200, 8, 1, uart.None, uart.MSB)

3.6 uart.VUART_0

常量含义:usb虚拟端口
数据类型:number
取值范围:32
示例代码: uart.setup(uart.VUART_0, 115200, 8, 1)

3.7 uart.ERROR_DROP

常量含义:遇到错误时抛弃缓冲区中的数据;
数据类型:number
取值范围:214
示例代码: uart.setup(1, 115200, 8, 1, uart.NONE, nil, 1024, nil, nil, nil, nil, uart.ERROR_DROP)

3.8 uart.DEBUG

常量含义:开启调试功能;
数据类型:number
取值范围:62
示例代码: uart.setup(1, 115200, 8, 1, uart.NONE, nil, 1024, nil, nil, nil, uart.DEBUG, uart.ERROR_DROP)

四、函数详解

4.1 uart.setup(id, baud_rate, data_bits, stop_bits, partiy, bit_order, buff_size, rs485_gpio, rs485_level, rs485_delay, debug_enable, error_drop)

功能

配置串口参数,并开启串口功能;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.setup(1)

baud_rate

参数含义:波特率;
数据类型:number
取值范围:可选择波特率表:{2000000,921600,460800,230400,115200,57600,38400,19200,9600,4800,2400}
是否必选:可选;
注意事项:默认115200
参数示例:uart.setup(1, 115200)

data_bits

参数含义:数据位;
数据类型:number
取值范围:7/8
是否必选:可选;
注意事项:默认8
参数示例:uart.setup(1, 115200, 8)

stop_bits

参数含义:停止位;
数据类型:number
取值范围:0.5/1/1.5/2等;
是否必选:可选;
注意事项:默认为1
参数示例:uart.setup(1, 115200, 81)

partiy

参数含义:校验位;
数据类型:number
取值范围:uart.None/uart.Even/uart.Odd
是否必选:可选;
注意事项:默认为uart.None无校验
参数示例:uart.setup(1, 115200, 8, 1, uart.None)

bit_order

参数含义:数据存储方式:大小端;
数据类型:number
取值范围:uart.LSB/uart.MSB
是否必选:可选;
注意事项:默认小端 uart.LSB
参数示例:uart.setup(1, 115200, 8, 1, uart.Noneuart.LSB)

buff_size

参数含义:缓冲区大小;
数据类型:number
取值范围:根据设备可用内存设置,默认1024
是否必选:可选;
注意事项:默认1024
参数示例:uart.setup(1, 115200, 8, 1, uart.Noneuart.LSB1024)

rs485_gpio

参数含义:485模式下的转换GPIO
数据类型:number
取值范围:根据设备选择可用的gpio
是否必选:可选;
注意事项:默认0xffffffff 无;
参数示例:uart.setup(1, 115200, 8, 1, uart.NONE, uart.LSB, 1024, 10, 0, 2000)

rs485_level

参数含义:485模式下的rx方向GPIO的电平
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:默认值0
参数示例:uart.setup(1, 115200, 8, 1, uart.NONE, uart.LSB, 1024, 10, 0, 2000)

rs485_delay

参数含义:485模式下tx向rx转换的延迟时间
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:单位us, 9600波特率填20000
参数示例:uart.setup(1, 115200, 8, 1, uart.NONE, uart.LSB, 1024, 10, 0, 2000)

debug_enable

参数含义:是否开启调试功能;
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:默认使能,填写uart.DEBUG或者非数字使能,其他值都是关闭;
参数示例:uart.setup(1, 115200, 8, 1, uart.NONE, nil, 1024, nil, nil, nil, uart.DEBUG)

error_drop

参数含义:遇到接收错误是否放弃缓冲数据;
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:默认使能,填写uart.ERROR_DROP或者非数字使能,其他值都是关闭;
参数示例:uart.setup(1, 115200, 8, 1, uart.NONE, nil, 1024, nil, nil, nil, uart.DEBUG, uart.ERROR_DROP)

返回值

  • 0:成功,其他:失败

示例

local result = uart.setup(1, 115200, 8, 1, uart.NONE)

4.2 uart.write(id, data,len)

功能

串口发送数据;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.write(1, "rdy\r\n")

data

参数含义:需要发送的数据;
数据类型:string
取值范围:暂无;
是否必选:必选;
注意事项:如果是zbuff会从指针起始位置开始读
参数示例: uart.write(1, "rdy\r\n")

len

参数含义:要发送的数据长度;
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:默认全发;
参数示例:uart.write(1, "1234567890"5)

返回值

  • number,发送成功的数据长度

示例

local result = uart.write(1, "1234567890"5)

4.3 uart.read(id, len)

功能

串口读取缓冲区中的数据;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.read(id, 1024)

len

参数含义:期望读取数据的长度;
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:不填时读取缓冲区中的全部数据,无论写多少,最多读取当前缓冲区所有数据;
参数示例:uart.read(id, 1024)

返回值

  • string,读取到的字符串数据

示例

local function uart_cb(id, len)
    local s = ""
    repeat
        s = uart.read(id, 1024) -- 一次性读出所有缓冲区中的数据,避免分包
        if #s > 0 then -- #s 是取字符串的长度
            -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
            log.info("uart", "receive", id, #s, s)
            -- log.info("uart", "receive", id, #s, s:toHex()) --如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
        end
    until s == ""
end

4.4 uart.close(id)

功能

关闭串口;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.close(1)

返回值

无返回值

示例

uart.close(1)

4.5 uart.on(id, event, func)

功能

注册串口事件回调函数

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.on(1, "receive", uart_cb)

event

参数含义:触发的事件名称,相应事件发生时触发uart_cb回调函数
数据类型:string
取值范围:"receive"等同于"recv":新数据接收完成或者接收缓冲满了   "sent":发送结束;
是否必选:必选;
注意事项:暂无;
参数示例:uart.on(1, "receive", uart_cb)

func

参数含义:读取串口缓冲区收到的数据,或者打印发送成功的信息;
        回调函数接收以下两个参数: 
        -- 参数含义:串口id, uart0写0, uart1写1, 如此类推;
        -- 数据类型:number;
        -- 取值范围:最大值取决于设备;
        -- 是否必选:必选;
        -- 注意事项:暂无;
        id

        -- 参数含义:期望读取数据的长度;
        -- 数据类型:number;
        -- 取值范围:暂无;
        -- 是否必选:可选;
        -- 注意事项:缓冲区的数据长度;
        len

参数含义:回调函数;
数据类型:function
取值范围:无;
是否必选:必选;
注意事项:无;
参数示例:-- string方式读取数据
         local function uart_cb(id, len)
             local data = uart.read(id, len)
             log.info("uart", id, len, data)
         end
        -- 或者zbuff方式读取数据
         local function uart_cb(id, len)  -- 串口接收数据回调函数
             while 1 do
                 log.info("uart", "缓冲区", uart.rxSize(id)) -- 缓冲区中的数据数量
                 local len = uart.rx(id, rxbuff)
                 if len <= 0 then
                     break
                 end
                 log.info("uart", "receive", id, rxbuff:used(), rxbuff:toStr())
                 rxbuff:seek(0)
             end
         end

返回值

示例

    local function uart_cb(id, len)
        local data = uart.read(id, len)
        log.info("uart", id, len, data)
    end
    uart.on(uartid, "receive", uart_cb)

4.6 uart.rx(id, buff)

功能

buff形式读串口,一次读出全部数据存入buff中;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.rx(1, rxbuff)

buff

参数含义:zbuff对象,用于接收串口缓冲区中的数据;
数据类型:zbuff
取值范围:暂无;
是否必选:必选;
注意事项:需要先创建zbuff对象 local rxbuff = zbuff.create(1024)
参数示例:uart.rx(1, rxbuff)
返回值

  • 返回读到的长度,并把zbuff指针后移

示例

local function uart_cb(id, len)  -- 串口接收数据回调函数
    while 1 do
        log.info("uart", "缓冲区", uart.rxSize(id)) -- 缓冲区中的数据数量
        local len = uart.rx(id, rxbuff)
        if len <= 0 then
            break
        end
        log.info("uart", "receive", id, rxbuff:used(), rxbuff:toStr())
        rxbuff:seek(0)
    end
end

4.7 uart.rxSize(id)

功能

读串口Rx缓冲中剩余数据量;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.rxSize(1)

返回值

  • 返回缓冲区数据的长度

示例

local function uart_cb(id, len)  -- 串口接收数据回调函数
    log.info("uart", "缓冲区", uart.rxSize(id)) -- 缓冲区中的数据数量
end

4.8 uart.rxClear(id)

功能

清除串口Rx缓冲中剩余数据量;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.rxClear(1)

返回值

示例

uart.rxClear(1)

4.9 uart.tx(id, buff, start, len)

功能

zbufff方式发送串口数据;

参数

id

参数含义:串口id, uart0写0, uart1写1, 如此类推;
数据类型:number
取值范围:最大值取决于设备;
是否必选:必选;
注意事项:暂无;
参数示例:uart.tx(uartid, txbuff01024)

buff

参数含义:zbuff对象,待写入的数据,会从指针起始位置开始读;
数据类型:zbuff
取值范围:暂无;
是否必选:必选;
注意事项:需要创建zbuff对象并写有待发送的数据
参数示例:local txbuff = zbuff.create(1024)
         txbuff:write("测试数据")
         uart.write(1, txbuff)

start

参数含义:要发送的数据起始位置,默认为0
数据类型:number
取值范围:0-zbuff的最大空间
是否必选:可选;
注意事项:暂无;
参数示例:uart.tx(1, txbuff01024)

len

参数含义:要发送的数据长度;
数据类型:number
取值范围:0-zbuff的最大空间
是否必选:可选;
注意事项:默认为zbuff内有效数据,最大值不超过zbuff的最大空间
参数示例:uart.tx(1, txbuff01024)

返回值

示例

 uart.tx(1, txbuff)

4.10 uart.list(max)

功能

获取可用串口号列表,PC模拟器专用接口;

参数

max

参数含义:最多获取多少个串口;
数据类型:number
取值范围:暂无;
是否必选:可选;
注意事项:默认256
参数示例:uart.list()

返回值

  • table,获取到的可用串口号列表

示例

uart.list()

五、产品支持说明

支持 LuatOS 开发的所有产品都支持 uart 核心库。