硬件说明
模块有三个串口:
调试下载口: HOST_TXD;HOST_RXD
串口1: UART1_TXD;UART1_RXD
串口2: UART2_TXD;UART2_RXD
开发板的串口1连接了485/422
1.配置串口1,回环模式
代码语言:javascript复制module(...,package.seeall)
local UART_ID = 1 --串口ID,1对应uart1,如果要修改为uart2,把UART_ID赋值为2即可
--串口接收回调函数
local function read()
local data = ""
--底层core中,串口收到数据时:
--如果接收缓冲区为空,则会以中断方式通知Lua脚本收到了新数据;
--如果接收缓冲器不为空,则不会通知Lua脚本
--所以Lua脚本中收到中断读串口数据时,每次都要把接收缓冲区中的数据全部读出,这样才能保证底层core中的新数据中断上来,此read函数中的while语句中就保证了这一点
while true do
data = uart.read(UART_ID,"*l")
if not data or string.len(data) == 0 then break end
uart.write(UART_ID,data) --返回接收的数据
end
end
--串口发送完成回调函数
local function writeOk()
log.info("writeOk")
end
--注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据
uart.on(UART_ID,"receive",read)
--注册串口的数据发送完成函数
uart.on(UART_ID,"sent",writeOk)
--配置并且打开串口
uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1)
--如果需要打开“串口发送数据完成后,通过异步消息通知”的功能,则使用下面的这行setup,注释掉上面的一行setup
--uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1,nil,1)
测试
A ,A- 作为485通信时的接收和发送数据接口,另作为422通信时的发送数据接口
B ,B- 作为422通信时的接收数据接口
1.用485模块连接如下
2.打开485连接的串口调试助手发送数据
3.注意:上面的接收数据并不能是接收到一条完整的数据以后进入,可能把整个数据分为好几段
修改程序打印下长度
代码语言:javascript复制log.info("testUart.readLen",#data)
4.解决方案1:(自己添加定时器空闲检测)
代码语言:javascript复制local UART_ID = 1 --串口ID,1对应uart1,如果要修改为uart2,把UART_ID赋值为2即可
local UsartReceiveData="";
local UsartReceiveDataCopy="";
local UsartReceiveFlage=false;
local UsartIdleCnt = 0;
--1ms定时器
function UsartIdleTimer(param)
if (UsartReceiveFlage == true) then --串口接收到数据
UsartIdleCnt = UsartIdleCnt 1; --空闲时间加1
if(UsartIdleCnt>10)then --空闲时间达到10ms
UsartIdleCnt=0; --清零空闲时间
UsartReceiveFlage = false; --清零接收标志
UsartReceiveDataCopy = UsartReceiveData;--拷贝数据
UsartReceiveData="";--清空接收缓存
--UsartReceiveDataCopy:为待处理的数据
uart.write(UART_ID,UsartReceiveDataCopy) --返回接收的数据
end
end
end
--串口接收回调函数
local function read()
local data = ""
while true do
data = uart.read(UART_ID,"*l")
if not data or string.len(data) == 0 then break end
UsartReceiveData = UsartReceiveData..data;--缓存数据
UsartReceiveFlage = true;--接收标志
UsartIdleCnt = 0;--如果有数据则清零空闲累加变量
end
end
--注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据
uart.on(UART_ID,"receive",read)
--配置并且打开串口
uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1)
5.解决方案2:
可以用 官方提供的内部订阅发布函数
代码语言:javascript复制-- 串口ID,串口读缓冲区
local UART_ID=1
local sendQueue = {} --接收数据缓存
local uartimeout=25 -- 串口接收超时时间
local recvReady = "UART_RECV_ID" --串口准备好后发布的消息
uart.on(1, "receive", function(uid)
table.insert(sendQueue, uart.read(uid, 1460))
sys.timerStart(sys.publish, uartimeout, recvReady)--发布消息,消息主题为 :UART_RECV_ID
end)
-- 订阅串口发布消息的主题
sys.subscribe(recvReady, function()
local str = table.concat(sendQueue) --把每一条数据拼接成一条数据
uart.write(UART_ID, str) --返回接收的数据
sendQueue = {} -- 串口的数据读完后清空缓冲区
end)
uart.setup(UART_ID, 115200, 8, uart.PAR_NONE, uart.STOP_1)
其它方案,请参考官方例程,推荐使用上面的方案,简洁实用!