zoukankan      html  css  js  c++  java
  • GPRS(Air202) Lua开发: 串口

    硬件说明

    模块有三个串口:

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

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

  • 相关阅读:
    基于keepalived双主模型的高可用LVS
    ViewFlipper实现ViewPager的页面切换效果
    C++,Python,Go对照学习-01
    matlab figure 调整大小、字体、线宽
    学术研究 —— 常用结论、说法
    学术研究 —— 常用结论、说法
    OpenGL(十六) 鼠标、键盘交互响应事件
    N+1:创新点的设计
    N+1:创新点的设计
    数学中的物理、几何概念与含义
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/12962076.html
Copyright © 2011-2022 走看看