news 2026/3/19 23:07:57

UART与Modbus协议在工控行业的结合应用:通俗解释

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UART与Modbus协议在工控行业的结合应用:通俗解释

UART与Modbus RTU:工控通信的“老搭档”为何经久不衰?

在智能制造、工业物联网(IIoT)高歌猛进的今天,我们常被5G、边缘计算、TSN(时间敏感网络)等前沿技术吸引目光。但如果你走进任何一个真实的工厂车间、配电房或水处理站,会发现一种看似“过时”的组合仍在默默支撑着整个系统的运转——UART + Modbus RTU

它没有炫酷的带宽,也不依赖复杂的协议栈,却凭借极高的稳定性、极低的成本和强大的兼容性,成为工业现场最可靠的通信基石之一。今天,我们就来聊聊这对“老搭档”是如何协同工作的,以及为什么它们至今仍是工程师手中的“香饽饽”。


从一个实际问题说起

想象这样一个场景:

你负责开发一套楼宇环境监控系统,需要采集分布在整栋楼里的温湿度传感器、电能表和空调变频器的数据。这些设备来自不同厂家,接口五花八门,有的是485口,有的是RS-232,还有的干脆只留了TTL电平引脚。

怎么办?重写驱动?定制协议?成本太高,周期太长。

这时,如果所有设备都支持Modbus RTU over UART,问题就简单了——你只需要用一根双绞线把它们挂在同一个RS-485总线上,再通过一个主控制器轮询读取数据即可。不需要交换机,不需要IP地址,甚至连操作系统都可以不要。

这就是 UART 与 Modbus 结合的魅力:用最简单的硬件,跑最通用的协议,解决最现实的问题


UART:串行通信的“底层搬运工”

它到底是什么?

UART(Universal Asynchronous Receiver/Transmitter),直译为“通用异步收发器”,本质上是一个负责并转串、串转并的硬件模块。你可以把它理解成一条“数据搬运流水线”——CPU给它一个字节,它就一位一位地往外发;反过来,它收到一串比特流,也能拼成完整的字节交给CPU。

几乎每一颗MCU(比如STM32、ESP32、GD32)都内置至少一个UART外设,有些甚至有四五个。它的存在感就像空气一样稀松平常,但也正因如此,才显得不可或缺。

异步是怎么回事?

所谓“异步”,是指通信双方没有共享时钟线。不像SPI或I2C那样靠CLK信号同步采样,UART全靠事先约定好的波特率(Baud Rate)来协调节奏。

举个例子:
假设双方约定波特率为9600bps,意味着每个比特持续时间为约104.17微秒(1/9600秒)。发送方从起始位开始,按这个节奏逐位输出;接收方则在每位中间时刻进行采样,从而还原原始数据。

典型的帧格式如下:

[起始位(0)] [D0][D1][D2][D3][D4][D5][D6][D7] [校验位(可选)] [停止位(1)]

常见配置是8-N-1:8位数据、无校验、1位停止位,这也是 Modbus RTU 的标准配置。

💡 小知识:为什么叫“异步”而不是“同步”?
因为每次传输都是独立的,每帧都有自己的起始和停止位,不需要长期保持时钟同步。这牺牲了一点效率,换来了布线简化和抗干扰能力提升。

实际使用中的关键点

  • 必须严格对齐波特率:发送端是9600,接收端就不能是9610。哪怕差1%,长时间运行后也会出现采样漂移导致误码。
  • 推荐使用差分信号远传:UART原生是TTL电平(0V/3.3V或5V),抗干扰差,适合板内通信。若要走几十米甚至上百米,必须搭配RS-485 芯片(如 MAX485)转换为差分信号。
  • 支持全双工,但常工作于半双工模式:虽然TX和RX独立,但在多点RS-485总线中通常采用半双工(收发切换),节省线路资源。

下面是一个基于STM32 HAL库的UART初始化示例:

UART_HandleTypeDef huart1; void UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } }

这段代码看似简单,却是后续一切通信的基础。一旦配置错误,比如把奇校验打开而对方没开,数据就会一直校验失败。


Modbus RTU:让设备“说同一种语言”

有了UART做物理通道,接下来的问题是:怎么组织数据内容?如何确保对方能正确理解你的请求?

这就轮到Modbus协议登场了。如果说UART是公路,那Modbus就是交通规则+货运单据系统。

主从架构:谁说话,谁听话

Modbus采用经典的主从模型(Master-Slave)

  • 只有主站可以主动发起通信;
  • 所有从站只能被动响应;
  • 同一时刻只能有一个主站,但从站最多可有247个(地址1~247)。

这种设计避免了总线冲突,特别适合资源有限的嵌入式系统。例如,一台HMI作为主站,轮流问:“0x01号温湿度计,报一下当前温度”,“0x02号电表,电量多少?”……

报文结构:精简而高效

以最常见的“读保持寄存器”为例(功能码0x03),请求帧长这样:

字段值示例说明
从站地址0x01目标设备编号
功能码0x03表示“读保持寄存器”
起始地址0x00 0x00高字节在前(大端)
寄存器数量0x00 0x02连续读2个寄存器
CRC校验0x94 0x0B低字节在前

注意几个细节:
- 所有数据均采用大端字节序(Big-Endian)
- CRC校验值附加在末尾,且低字节先发
- 每帧之间要有≥3.5个字符时间的静默间隔,用于帧定界。

响应帧如下:

地址功能码字节数数据(4字节)CRC
0x010x030x040x12 0x34 0x56 0x78

其中0x12340x5678就是两个16位寄存器的实际数值。

功能码一览:设备能力的“菜单表”

Modbus定义了一系列标准化的功能码,相当于给设备列了一张“我能干啥”的菜单:

功能码名称典型用途
0x01读线圈状态查询开关量输出(如继电器)
0x02读离散输入读取数字输入信号(如按钮)
0x03读保持寄存器获取参数或测量值(最常用)
0x04读输入寄存器读模拟量输入(如ADC结果)
0x05写单个线圈控制单个继电器通断
0x06写单个保持寄存器设置某个参数(如设定温度)
0x10写多个保持寄存器批量更新配置

当你看到设备手册中标注“支持功能码03/06”,你就知道它可以被读写参数;如果只支持01/02,则大概率是个纯采集型设备。

CRC16校验:最后一道安全防线

数据传过去了,怎么判断有没有出错?答案是CRC(循环冗余校验)。Modbus RTU使用的是CRC-16/MCRF4XX算法,多项式为0x8005,初值0xFFFF

下面是实现代码:

uint16_t Modbus_CRC16(uint8_t *buf, int len) { uint16_t crc = 0xFFFF; for (int i = 0; i < len; i++) { crc ^= buf[i]; for (int j = 0; j < 8; j++) { if (crc & 0x0001) { crc = (crc >> 1) ^ 0xA001; // 0xA001 是 0x8005 的反向 } else { crc >>= 1; } } } return crc; // 返回时低字节在前 }

发送前计算CRC并追加到报文末尾;接收端重新计算接收到的数据(不含接收到的CRC),若结果一致则认为数据有效,否则丢弃。

⚠️ 常见坑点:忘记反转字节顺序!很多初学者直接返回crc而不拆分为高低字节,导致校验失败。


典型应用:一个多设备监控系统的实战拆解

让我们回到开头提到的楼宇监控系统,看看这套机制如何落地。

系统拓扑

[HMI / 工控机] ↓ (UART TTL) [MAX485 收发器] =================== RS-485 总线 =================== | | | | [温湿度传感器] [智能电表] [变频器] [PLC] 地址: 0x01 0x02 0x03 0x04
  • 所有设备通过MAX485 芯片接入同一根双绞线;
  • HMI作为主站,每隔200ms轮询一次各设备;
  • 波特率设为9600bps,兼顾距离与实时性;
  • 总线两端并联120Ω终端电阻,抑制信号反射。

通信流程实录

  1. HMI 构造请求帧:读取地址0x01设备的40001寄存器(温度)
    01 03 00 00 00 01 94 0B

  2. UART逐字节发出,MAX485将其转为差分信号广播到总线;

  3. 所有从站监听总线,只有地址匹配的传感器(0x01)开始解析;

  4. 传感器执行读操作,封装响应:
    01 03 02 1A 2B 8E E5
    其中0x1A2B= 6699,表示66.99°C(假设精度为0.01℃);

  5. HMI 接收完整帧,验证CRC成功,提取数据并在界面上显示;

  6. 延迟片刻,继续向0x02号电表发起请求……

整个过程在一个扫描周期内完成,形成稳定的“心跳式”通信。


为什么这个组合还能打?

尽管以太网、MQTT、OPC UA等新技术层出不穷,但在以下场景中,UART+Modbus RTU仍是首选方案:

场景优势体现
设备改造项目无需更换旧设备,只需增加协议解析即可接入新系统
远程监测站点如山区泵站、光伏电站,布网困难,485两根线搞定
成本敏感系统不需要路由器、交换机、IP管理,硬件成本极低
高干扰环境差分信号+低速传输,抗电磁干扰能力强
快速调试维护用USB转485工具+Modbus调试助手就能抓包分析

更别说市面上90%以上的PLC、仪表、传感器都原生支持Modbus RTU。这意味着你写的驱动、做的网关,可以直接对接海量存量设备。


工程师的实用建议

如果你想在项目中稳妥使用这套方案,记住这几个要点:

合理规划设备地址:建立清晰的地址分配表,避免冲突。
设置合理的超时机制:主站等待响应不应超过1秒,防止卡死。
启用CRC校验必选项:别图省事关掉校验,工业现场噪声太多。
注意3.5字符时间间隔:这是帧边界识别的关键,软件需精确控制。
优先使用中断或DMA收发:避免阻塞主线程,提高系统响应性。
加入日志记录功能:方便后期排查通信异常问题。

还有一个小技巧:当发现某设备偶尔掉线时,不妨先降低波特率试试。有时候不是硬件坏了,只是线路老化导致高速下误码率上升。


写在最后:经典技术的价值,在于“稳”

UART与Modbus RTU或许不够“时髦”,但它们代表了一种工程哲学:用成熟、可控、可预测的技术解决问题

在追求高性能的同时,我们往往忽略了系统的鲁棒性和可维护性。而正是这些“老旧”的协议,在关键时刻撑起了整个工业体系的底线。

对于嵌入式开发者来说,掌握UART配置、理解Modbus帧结构、能手写CRC算法,不仅是基本功,更是通往更高阶能力(如协议转换网关、边缘计算节点、多协议融合平台)的起点。

下次当你面对一堆杂乱设备不知所措时,不妨试试这个“黄金组合”——也许,最古老的路,才是最快的路。

如果你正在做类似的项目,欢迎在评论区分享你的经验和挑战。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/16 2:12:41

揭秘QQScreenShot:这款独立截图工具如何成为效率倍增神器

揭秘QQScreenShot&#xff1a;这款独立截图工具如何成为效率倍增神器 【免费下载链接】QQScreenShot 电脑QQ截图工具提取版,支持文字提取、图片识别、截长图、qq录屏。默认截图文件名为ScreenShot日期 项目地址: https://gitcode.com/gh_mirrors/qq/QQScreenShot 还在为…

作者头像 李华
网站建设 2026/3/15 9:13:36

轻松搭建个人云存储:WebDAV服务器配置全攻略

轻松搭建个人云存储&#xff1a;WebDAV服务器配置全攻略 【免费下载链接】webdav Simple Go WebDAV server. 项目地址: https://gitcode.com/gh_mirrors/we/webdav 还在为多设备文件同步烦恼吗&#xff1f;想要拥有一个安全可靠的个人云存储系统吗&#xff1f;今天让我们…

作者头像 李华
网站建设 2026/3/15 9:09:09

如何快速掌握Arknights-Mower:明日方舟智能基建管理的完整实战指南

如何快速掌握Arknights-Mower&#xff1a;明日方舟智能基建管理的完整实战指南 【免费下载链接】arknights-mower 《明日方舟》长草助手 项目地址: https://gitcode.com/gh_mirrors/ar/arknights-mower 还在为《明日方舟》基建管理而烦恼吗&#xff1f;每天花费大量时间…

作者头像 李华
网站建设 2026/3/15 14:43:02

Video2X视频无损放大完整教程:从新手到专家的终极指南

Video2X视频无损放大完整教程&#xff1a;从新手到专家的终极指南 【免费下载链接】video2x A lossless video/GIF/image upscaler achieved with waifu2x, Anime4K, SRMD and RealSR. Started in Hack the Valley II, 2018. 项目地址: https://gitcode.com/gh_mirrors/vi/vi…

作者头像 李华