文章目录
- 1 前言
- 2 uart示例
-
- 2.1 示例--esp32
- 2.2 示例--LuatOS
- 3 esp32-uart硬件
- 4 数据发送
-
- 4.1 代码
- 4.2 结果
- 5 数据接收
-
- 5.1 接口
- 5.2 代码
- 5.3 结果
- 6 小结
1 前言
测试合宙esp32c3的uart接口。
2 uart示例
2.1 示例–esp32
LuatOS-ESP32\test\uartTest.lua
local uartTest = {
}local tag = "uartTest"local uartList = {
}if MOD_TYPE == "air101" thenuartList = {
}
elseif MOD_TYPE == "air103" thenuartList = {
}
elseif MOD_TYPE == "ESP32C3" thenuartList = {
1}
endlocal receiveBuff = {
}
local testData = string.rep(tag, 1)local function getSerialData(id)local tmp = receiveBuff[id]receiveBuff[id] = ""return tmp
endfunction uartTest.test()if uart == nil thenlog.error(tag, "this fireware is not support uart")returnendlog.info(tag, "START")for _, v in pairs(uartList) doreceiveBuff[v] = ""assert(uart.setup(v, 115200, 8, 1) == 0, tag .. ".setup ERROR")uart.on(v, "receive", function(id, len)receiveBuff[id] = receiveBuff[id] .. uart.read(id, len)sys.publish("UART_RECEIVE_" .. v)end)assert(uart.write(v, testData) == #testData, tag .. ".write ERROR")sys.waitUntil("UART_RECEIVE_" .. v)assert(receiveBuff[v] == testData)uart.close(v)endlog.info(tag, "DONE")
endreturn uartTest
2.2 示例–LuatOS
LuatOS-master\LuatOS\demo\uart\main.lua
官方示例
-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "uart_irq"
VERSION = "1.0.0"log.info("main", PROJECT, VERSION)-- 引入必要的库文件(lua编写), 内部库不需要require
local sys = require "sys"if wdt then--添加硬狗防止程序卡死,在支持的设备上启用这个功能wdt.init(15000)--初始化watchdog设置为15ssys.timerLoopStart(wdt.feed, 10000)--10s喂一次狗
endlog.info("main", "uart demo")local uartid = 1 -- 根据实际设备选取不同的uartid--初始化
local result = uart.setup(uartid,--串口id115200,--波特率8,--数据位1--停止位
)--循环发数据
sys.timerLoopStart(uart.write,1000, uartid, "test")
-- 收取数据会触发回调, 这里的"receive" 是固定值
uart.on(uartid, "receive", function(id, len)local s = ""repeat-- 如果是air302, len不可信, 传1024-- s = uart.read(id, 1024)s = uart.read(id, len)if #s > 0 then -- #s 是取字符串的长度-- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到-- 关于收发hex值,请查阅 https://doc.openluat.com/article/583log.info("uart", "receive", id, #s, s)-- log.info("uart", "receive", id, #s, s:toHex())enduntil s == ""
end)-- 并非所有设备都支持sent事件
uart.on(uartid, "sent", function(id)log.info("uart", "sent", id)
end)-- sys.taskInit(function()
-- while 1 do
-- sys.wait(500)
-- end
-- end)-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
3 esp32-uart硬件
购买一个usb转ttl的串口线。
连接方式,如上图,注意串口线的电压是5v还是3.3v。
然后esp32的u1_rx连接串口线的TX,u1_tx连接串口线的RX
白色的线是esp32的下载线,蓝色口的是usb2ttl
4 数据发送
4.1 代码
tag_uart = "test5_uart"id = 1
len = 1024function init_uart()-- uart.on(1, "recv", function(id, len)-- local data = uart.read(1, 1024)-- log.info("uart2", data)-- -- libgnss.parse(data)-- end)log.info(tag_uart,"test5_init_uart")uart.setup(1, 115200)timex = sys.timerLoopStart(uart_send,1000)log.info(tag_uart,"time:",timex)
endfunction uart_send()log.info("uart_send")uart.write(id, "test")
end
timerLoopStart是创建定时器
sys.timerLoopStart(uart_send,1000)
这句话的意思是创建一个定时器,每1000ms触发uart_send函数。
/*LuatOS-master\LuatOS\luat\modules\luat_lib_sys_doc.c*/
/* 创建一个循环定时器.非Task,函数里不能直接sys.waitXXX @api sys.timerLoopStart(func, timeout, arg1, arg2, argN) @function 待执行的函数,可以是匿名函数, 也可以是local或全局函数 @int 延时时长,单位毫秒 @any 需要传递的参数1,可选 @any 需要传递的参数2,可选 @any 需要传递的参数N,可选 @return int 定时器id @usage sys.timerLoopStart(function(a, b, c)log.info("task", a, b, c) -- 1000毫秒后才会执行, 打印 task A B C end, 1000, "A", "B", "N") */
void doc_sys_timerLoopStart(void){
};
注意如下几点
- uart号,esp32支持uart0和uart1
- 串口波特率设定需要和串口工具匹配
- 串口的vcc电压5v/3.3v
4.2 结果
注意串口选择正确,然后点击打开串口。
我使用的是sscom串口工具
5 数据接收
5.1 接口
接口uart.on
/*LuatOS-master\LuatOS\luat\modules\luat_lib_uart.c*/
/* 注册串口事件回调 @api uart.on(id, event, func) @int 串口id, uart0写0, uart1写1 @string 事件名称 @function 回调方法 @return nil 无返回值 @usage uart.on(1, "receive", function(id, len)local data = uart.read(id, len)log.info("uart", id, len, data) end) */
static int l_uart_on(lua_State *L) {
int uart_id = luaL_checkinteger(L, 1);if (!luat_uart_exist(uart_id)) {
lua_pushliteral(L, "no such uart id");return 1;}const char* event = luaL_checkstring(L, 2);if (!strcmp("receive", event) || !strcmp("recv", event)) {
if (uart_cbs[uart_id].received != 0) {
luaL_unref(L, LUA_REGISTRYINDEX, uart_cbs[uart_id].received);uart_cbs[uart_id].received = 0;}if (lua_isfunction(L, 3)) {
lua_pushvalue(L, 3);uart_cbs[uart_id].received = luaL_ref(L, LUA_REGISTRYINDEX);}}else if (!strcmp("sent", event)) {
if (uart_cbs[uart_id].sent != 0) {
luaL_unref(L, LUA_REGISTRYINDEX, uart_cbs[uart_id].sent);uart_cbs[uart_id].sent = 0;}if (lua_isfunction(L, 3)) {
lua_pushvalue(L, 3);uart_cbs[uart_id].sent = luaL_ref(L, LUA_REGISTRYINDEX);}}luat_setup_cb(uart_id, uart_cbs[uart_id].received, uart_cbs[uart_id].sent);return 0;
}
5.2 代码
tag_uart = "test5_uart"id = 1
len = 1024function init_uart()-- uart.on(1, "recv", function(id, len)-- local data = uart.read(1, 1024)-- log.info("uart2", data)-- -- libgnss.parse(data)-- end)log.info(tag_uart,"test5_init_uart")uart.setup(1, 115200)-- 接收数据uart.on(id, "receive",uart_receive)-- 定时发送数据timex = sys.timerLoopStart(uart_send,1000)log.info(tag_uart,"time:",timex)
endfunction uart_send()-- log.info("uart_send")uart.write(id, "test")
endfunction uart_receive()log.info("uart_receive")local s = ""s = uart.read(id, len)if #s > 0 then -- #s 是取字符串的长度-- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到-- 关于收发hex值,请查阅 https://doc.openluat.com/article/583log.info("uart", "receive", id, #s, s)-- log.info("uart", "receive", id, #s, s:toHex())end
end
5.3 结果
6 小结
本章测试了lua语言编写的uart收发函数。