1 前言
测试合宙esp32c3的uart接口。
2 uart示例
2.1 示例–esp32
LuatOS-ESP32testuartTest.lua
- local uartTest = {}
- local tag = "uartTest"
- local uartList = {}
- if MOD_TYPE == "air101" then
- uartList = {}
- elseif MOD_TYPE == "air103" then
- uartList = {}
- elseif MOD_TYPE == "ESP32C3" then
- uartList = {1}
- end
- local receiveBuff = {}
- local testData = string.rep(tag, 1)
- local function getSerialData(id)
- local tmp = receiveBuff[id]
- receiveBuff[id] = ""
- return tmp
- end
- function uartTest.test()
- if uart == nil then
- log.error(tag, "this fireware is not support uart")
- return
- end
- log.info(tag, "START")
- for _, v in pairs(uartList) do
- receiveBuff[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)
- end
- log.info(tag, "DONE")
- end
- return uartTest
复制代码
2.2 示例–LuatOS
LuatOS-masterLuatOSdemouartmain.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设置为15s
- sys.timerLoopStart(wdt.feed, 10000)--10s喂一次狗
- end
- log.info("main", "uart demo")
- local uartid = 1 -- 根据实际设备选取不同的uartid
- --初始化
- local result = uart.setup(
- uartid,--串口id
- 115200,--波特率
- 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/583
- log.info("uart", "receive", id, #s, s)
- -- log.info("uart", "receive", id, #s, s:toHex())
- end
- until 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硬件
购买一个u***转ttl的串口线。
连接方式,如上图,注意串口线的电压是5v还是3.3v。
然后esp32的u1_rx连接串口线的TX,u1_tx连接串口线的RX
白色的线是esp32的下载线,蓝色口的是u***2ttl
4 数据发送
4.1 代码
- tag_uart = "test5_uart"
- id = 1
- len = 1024
- function 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)
- end
- function uart_send()
- log.info("uart_send")
- uart.write(id, "test")
- end
复制代码
timerLoopStart是创建定时器
>sys.timerLoopStart(uart_send,1000)
这句话的意思是创建一个定时器,每1000ms触发uart_send函数。
- /*LuatOS-masterLuatOSluatmodulesluat_lib_sys_doc.c*/
- /*
- 创建一个循环定时器.非Task,函数里不能直接sys.waitXXX
- [url=home.php?mod=space&uid=540586]@API[/url] sys.timerLoopStart(func, timeout, arg1, arg2, argN)
- [url=home.php?mod=space&uid=254365]@function[/url] 待执行的函数,可以是匿名函数, 也可以是local或全局函数
- [url=home.php?mod=space&uid=2021340]@int[/url] 延时时长,单位毫秒
- [url=home.php?mod=space&uid=204963]@Any[/url] 需要传递的参数1,可选
- @any 需要传递的参数2,可选
- @any 需要传递的参数N,可选
- [url=home.php?mod=space&uid=1141835]@Return[/url] 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-masterLuatOSluatmodulesluat_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 = 1024
- function 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)
- end
- function uart_send()
- -- log.info("uart_send")
- uart.write(id, "test")
- end
- function uart_receive()
- log.info("uart_receive")
- local s = ""
- s = uart.read(id, len)
- 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
- end
复制代码
5.3 结果
6 小结
本章测试了lua语言编写的uart收发函数,后续再结合air551G和esp32c3开发板,获取坐标数据。
|