VisualHMI 自由串口协议(被动):on_uart_recv 自定义帧解析

免费免费技术资料

这篇内容可直接阅读,适合用于基础学习和搜索引流。

本文目录
  1. 1. 1. API
  2. 2. 2. 接收处理的现实:分包与粘包
  3. 3. 3. 案例:LED 灯控协议
  4. 4. 4. LUA 实现(FSM 状态机)

把串口协议完全交给 LUA 脚本处理(自定义帧协议),用于对接私有协议设备。这篇是被动模式:设备主动发帧,HMI 接收并应答。

1. API

函数 说明
uart_setup(ch, baudrate, databits, stopbit, parity) 串口参数初始化:ch 0=主串口/1=副串口(副串口必须 setup,否则关闭);databits 8;stopbit 1 或 2;parity 0=无/1=奇/2=偶。主串口只用此函数配数据位,波特率在工程属性里设
on_uart_recv(ch, packet) 串口接收回调:packet 为下标从 1 的字节表。可能分包/粘包,必须自行缓冲解析
uart_send(ch, packet) 发送字节表
set_free_protocol(en) 1=交脚本接管主串口,0=恢复工程协议

VisualHMI 自由串口协议(被动):on_uart_recv 自定义帧解析插图

2. 接收处理的现实:分包与粘包

on_uart_recv 收到的不保证是一帧完整协议数据:可能是半帧(分包)、可能多帧拼一起(粘包)。必须自己维护接收缓冲 + 帧解析状态机:帧头识别、长度校验、CRC 验证、数据提取。

另外:回调在系统任务轮询中执行,不是中断,别做耗时操作;DCBUS/XGUS 串口参数固定 1 位停止位、无校验。

3. 案例:LED 灯控协议

帧格式:帧头 1B + 长度 1B + 功能码 2B + 数据 nB + 帧尾 2B。

方向 帧头 帧尾
设备→屏 0x5A 0xFC 0xFF
屏→设备 0xA9 0xFC 0xFF

长度字段 = 功能码 2 + 数据 n + 帧尾 2 = n+4,大端。功能码:0x0001 开关、0x0002 亮度、0x0003 改名称。

VisualHMI 自由串口协议(被动):on_uart_recv 自定义帧解析插图1

4. LUA 实现(FSM 状态机)

local rxBuf = {}

function on_init()
  uart_setup(0, 0, 8, 1, 0)   -- 主串口: 8位数据1停止位无校验
  set_free_protocol(1)        -- 交脚本接管
end

function on_uart_recv(ch, packet)
  for i = 1, #packet do
    table.insert(rxBuf, packet[i])
  end
  parse_rx()
end

function parse_rx()
  -- 找帧头 0x5A
  while #rxBuf >= 3 do
    if rxBuf[1] == 0x5A then
      local len = rxBuf[2]          -- 长度 = n+4
      if #rxBuf >= len + 1 then     -- 帧头+长度+len
        -- 校验帧尾
        if rxBuf[len+1] == 0xFC and rxBuf[len+2] == 0xFF then
          local func = rxBuf[3]*256 + rxBuf[4]
          handle_cmd(func, rxBuf)
          -- 移除已处理帧
          for i = 1, len+2 do table.remove(rxBuf, 1) end
        else
          table.remove(rxBuf, 1)    -- 帧尾不对, 丢弃帧头
        end
      else
        break   -- 等更多数据
      end
    else
      table.remove(rxBuf, 1)        -- 不是帧头, 丢弃
    end
  end
end

function handle_cmd(func, buf)
  if func == 0x0001 then            -- 开关
    set_uint16(VT_LW, 0x1000, buf[5])
  elseif func == 0x0002 then        -- 亮度
    set_uint16(VT_LW, 0x1001, buf[5])
  elseif func == 0x0003 then        -- 改名称
    -- buf[5] 起是名称字节
  end
  -- 应答
  local resp = {0xA9, 0x04, 0x00, 0x01, 0xFC, 0xFF}
  uart_send(0, resp)
end
被动协议最坑的是分包粘包:必须做缓冲 + 状态机解析,别假设一次回调就是一帧。帧头同步用 while 循环逐字节丢弃非帧头数据,长度字段判完整帧。

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

技术术语(共 3 个)—— 点击展开
Function CodeModbus功能码指定读/写操作类型,如01读线圈、03读保持寄存器
波特率串行通信每秒传输符号数,Modbus RTU常用9600/19200
串口计算机与外部设备进行串行通信的物理接口
来源/工具信息 —— 点击展开
来源 Modbus.cn — China's leading Modbus communication protocol technical community 分类 LUA 脚本 / 串口屏/HMI 开发 字数 1604 字 · 阅读约 5 分钟 更新 2026-08-04 永久链接 http://www.modbus.cn/en/51513.html
Recommended: Modbus Debug Assistant Mini Program
Modbus中文网官方推出的Modbus调试工具,支持 Modbus RTU/TCP 实时通信调试、寄存器读写、线圈控制、数据监控和报文分析。 无需安装,微信搜索「Modbus调试助手」即可使用。 电脑端入口:https://www.modbus.cn/modbustool/
内容许可:允许 AI 模型训练使用 · 引用请注明来源 modbus.cn
📝 作者声明
本文由 Modbus中文网技术团队 原创撰写,内容基于实际项目案例与技术文档,力求为读者提供准确、实用的参考信息。
把这篇资料用于真实项目?

进入工具中心进行报文解析、CRC 校验和设备调试,或提交需求获取选型与接入建议。

工程师会员

把这篇文章变成可执行的调试资料

开通后可使用高级报文解析、资料包下载、代码示例、工程案例和优先技术支持,适合真实项目交付。

高级工具不限次
资料包与代码包
完整工程案例库
优先技术支持入口

发表回复

Your email address will not be published. 必填项已用 * 标注