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, 8,1);
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.None,uart.LSB);
buff_size
参数含义:缓冲区大小;
数据类型:number;
取值范围:根据设备可用内存设置,默认1024;
是否必选:可选;
注意事项:默认1024;
参数示例:uart.setup(1, 115200, 8, 1, uart.None,uart.LSB,1024);
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, txbuff,0,1024);
buff
参数含义:zbuff对象,待写入的数据,会从指针起始位置开始读;
数据类型:zbuff;
取值范围:暂无;
是否必选:必选;
注意事项:需要创建zbuff对象并写有待发送的数据;
参数示例:local txbuff = zbuff.create(1024)
txbuff:write("测试数据")
uart.write(1, txbuff)
start
参数含义:要发送的数据起始位置,默认为0;
数据类型:number;
取值范围:0-zbuff的最大空间;
是否必选:可选;
注意事项:暂无;
参数示例:uart.tx(1, txbuff,0,1024);
len
参数含义:要发送的数据长度;
数据类型:number;
取值范围:0-zbuff的最大空间;
是否必选:可选;
注意事项:默认为zbuff内有效数据,最大值不超过zbuff的最大空间;
参数示例:uart.tx(1, txbuff,0,1024);
返回值
无
示例
uart.tx(1, txbuff)
4.10 uart.list(max)
功能
获取可用串口号列表,PC模拟器专用接口;
参数
max
参数含义:最多获取多少个串口;
数据类型:number;
取值范围:暂无;
是否必选:可选;
注意事项:默认256;
参数示例:uart.list()
返回值
- table,获取到的可用串口号列表
示例
uart.list()
五、产品支持说明
支持 LuatOS 开发的所有产品都支持 uart 核心库。