GPRS(Air202) Lua开发: 串口

2020-05-26 16:42:43 浏览数 (1)

硬件说明

模块有三个串口:

调试下载口: 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)

其它方案,请参考官方例程,推荐使用上面的方案,简洁实用!

0 人点赞