硬件说明
模块有三个串口:
调试下载口: HOST_TXD;HOST_RXD
串口1: UART1_TXD;UART1_RXD
串口2: UART2_TXD;UART2_RXD
开发板的串口1连接了485/422
1.配置串口1,回环模式
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模块连接如下
注:如果使用422连接,
A+,A- 为422输出,连接另一端的输入
B+.B- 为422的输入,连接另一端的输出
2.打开485连接的串口调试助手发送数据
3.注意:上面的接收数据并不能是接收到一条完整的数据以后进入,可能把整个数据分为好几段
修改程序打印下长度
log.info("testUart.readLen",#data)
4.解决方案1:(自己添加定时器空闲检测)
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:
可以用 官方提供的内部订阅发布函数
-- 串口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)
其它方案,请参考官方例程,推荐使用上面的方案,简洁实用!