VisualHMI 自由串口协议(主动):uart_recv/calc_crc16 与 XGUS 映射

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

自由串口协议(主动)是上一篇「被动」的进阶:HMI 不只接收设备主动发的数据,还能主动向设备发查询帧、读响应,HMI 当总线主。核心 API 是 uart_recv(),配合协程+元表搭一个非阻塞通信框架,对接 XGUS 私有协议。适用 HMI&M 시리즈&Dx 시리즈。

1. 新增 API(相对被动模式)

函数parameter说明
uart_rxsize(ch)ch 串口号,通常 0查询接收缓冲区待读字节数。返回 N 表示有 N byte,0 表示无新数据
uart_recv(ch, size)size 期望读取字节数,必须 ≥1主动从接收缓冲区读指定数量字节。返回下标从 1 的字节表,如 {0xAA,0x55,0x01,0x02}
uart_rxclear(ch)ch 串口号清空接收缓冲区。通信初始化/错误恢复/协议同步时清残留
calc_crc16(데이터)데이터 字节表,下标从 1Modbus CRC-16 Verification calculation,返回 0~65535,低字节在前(符合 Modbus 小端序)

另外 uart_send(ch, packet) 和被动模式一样:向指定串口通道发字节数组,packet 下标从 1 开始,每元素 0~255。ch=0 主串口,1/2…副串口(依硬件型号)。通道必须处于自由协议模式(未被 Modbus/XGUS 等系统协议占用)。

2. ⚠️ 关键前置:禁用接收回调

主动读串口必须先在工程属性里:串口设置 → 接收回调 → 禁用(新版软件有这个选项)。不禁用的话,uart_recv() 和 on_uart_recv 回调会抢数据,帧全乱。

VisualHMI 自由串口协议(主动):uart_recv/calc_crc16 与 XGUS 映射插图

3. 案例:XGUS 协议映射到系统寄存器

目标:把 XGUS 协议中地址 ≥0x1000 的读写,映射到 HMI 系统寄存器 LW1000~LWFFFF。外部设备用 XGUS 帧读写 HMI 内部变量,HMI 也主动给设备发读写请求。

3.1 XGUS 帧格式

fieldLength说明
帧头2 바이트0x5AA5
Length1 바이트指令+데이터+校验的字节数
指令1 바이트0x82 写 / 0x83 读(0x80/0x81 另有用)
데이터最大 249 byte주소(2字节) + 数据内容(nbyte),Length = n+2
CRC2 바이트(可选)CRC-16 (x16+x15+x2+1)

例:向变量地址 0x1000 in simulation...' : '시작 simulation 2(不启用 CRC):5A A5 05 82 10 00 00 02——05 是长度(指令1+주소2+데이터2),按字写入。

3.2 初始化:load XGUS.lua

官方提供了基于协程+元表的 XGUS.lua 框架。main.lua 里创建实例:

function on_init()
  dofile("XGUS.lua")
  xgus = XGUS:new(0, 0x55AA, true, true)
  -- parameter:串口号, 帧头, OpenCRC, 开启写应答
end

-- on_run 里跑协程,非阻塞轮询
_EN_SET_데이터_ = false
function on_run(screen)
  _EN_SET_데이터_ = true
  xgus:run()
  _EN_SET_데이터_ = false
end

XGUS:run() 用协程实现:检查串口数据 → 凑够「帧头+指令+Length+주소」6 byte → Parse → 按长度收剩余数据 → CRC verification → 处理。协程可以打断/恢复任务,不阻塞 on_run 主循环,适合耗时流程。

3.3 指令解析:地址分流

function XGUS:processMsg()
  local func = self.func
  if func == XGUSFunction.write then
    -- 写指令
    if self.addr >= 0x1000 then
      -- 用户寄存器区:解析数据写入 LW
      local 데이터s = {}
      for i = 1, write_count do
        데이터s[i] = self.req[5+i*2]<>8), (self.head&0xFF), 0x03, 0x82, 0x4F, 0x4B})
    end
  elseif func == XGUSFunction.read then
    -- 读指令
    if self.addr >= 0x1000 then
      -- 组应答 frame: 读 LW 值回发
      local 데이터s = {(self.head>>8), (self.head&0xFF), 4+self.req[7]*2,
                     0x83, (self.addr>>8), (self.addr&0xFF), (self.req[7]*2)&0xFF}
      for i = 1, self.req[7] do
        local num = get_uint16(VT_LW, self.addr+(i-1))
        데이터s[6+i*2] = (num>>8) & 0xFF
        데이터s[7+i*2] = num & 0xFF
      end
      self:sendMsg(데이터s)
    else
      on_cmd_resp_xgus(self.addr, self.req[7], func, {})
    end
  end
end

-- 系统寄存器区读写回调(main.lua 里定义)
function on_cmd_resp_xgus(addr, count, wr, 데이터)
  if wr == 0x82 then
    print("write addr num : "..count)
  elseif wr == 0x83 then
    print("read addr num : "..count)
  end
end

3.4 主动发送:XGUS:데이터Send(addr, 데이터)

主动向设备发写指令,데이터 可以是 number 或 table:

-- 写单个值
xgus:데이터Send(0x1000, 1234)
-- 写一组值(table)
xgus:데이터Send(0x2000, {0x12, 0x34, 0x56})

-- 内部 send():开 CRC 时自动补 2 바이트校验再 uart_send
function XGUS:send(resp)
  if self.crc == true then
    resp[3] = resp[3] + 2   -- 长度加 CRC 2 바이트
    local crc_buff = {}
    for i = 4, #resp do crc_buff[i-3] = resp[i] end
    local crc_check = calc_crc16(crc_buff)
    resp[#resp+1] = (crc_check>>0) & 0xFF
    resp[#resp+1] = (crc_check>>8) & 0xFF
  end
  uart_send(self.port, resp)
end
四个坑:①不禁用接收回调就 uart_recv,帧必乱——工程属性→串口设置→接收回调→禁用;②calc_crc16 低字节在前,组帧时先发低 8 位再发高 8 位;③主动读要防设备无响应——XGUS:wait() 有超时机制(内部 get_tick_count 差值判断),自己写协议务必加超时,不然 on_run 卡死;④주소 ≥0x1000 才走 LW 映射,less than 0x1000 走 on_cmd_resp_xgus 回调自己处理。副串口用之前必须 uart_setup 初始化。

整理自 广州大彩科技 VisualHMI 开发文档(hmi-doc.gz-dc.com)LUA Tutorial「自由串口协议(主动)」,版权归大彩科技所有。

Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC verification and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support

Leave a Reply

Your email 주소 will not be published. Required fields are marked *.