☰
Modbus地址规则详解:协议地址与PLC地址换算及工控应用
2026/10/8 18:14:41 网站建设 项目流程

1. 搞懂Modbus地址规则,先弄明白它到底在解决什么问题

刚入工控这行的时候,我最怕听到的一句话就是“地址对不上”。PLC那边数据明明有,上位机就是读不到;组态软件里填了个40001,结果读出来的是别的设备的寄存器。折腾半天,最后发现是Modbus地址规则没搞明白。这个问题在工控现场太常见了,尤其是刚接触Modbus协议的朋友,很容易在地址这一关卡住。

Modbus地址规则,说白了就是一套“门牌号”体系。你想想,一个小区里有几千户人家,快递员怎么准确把包裹送到你家?靠的就是楼栋号、单元号、门牌号这一整套编码规则。Modbus网络里也是一样,主站要跟几十个从站设备通信,每个从站里面又有成千上万个数据点,没有一套清晰的地址规则,数据根本没法准确读写。

这套规则涉及几个核心问题:Modbus有哪几种数据区、每种数据区的地址范围是多少、协议地址和PLC地址之间怎么换算、不同厂家的设备地址映射有什么差异。搞清楚了这些,你再看Modbus Poll、Modbus Slave这些调试工具里的地址栏,就不会一脸茫然了。这篇文章适合刚入行工控的朋友、需要对接Modbus设备的自动化工程师、以及做上位机开发的程序员参考。我会从实际项目经验出发,把Modbus地址规则讲透,包括那些手册上不会写的坑。

2. Modbus四种数据区与地址分配逻辑

2.1 为什么Modbus要分四种数据区

Modbus协议在设计之初,就把数据分成了四类,分别用不同的字母和数字范围来标识。这个设计思路其实很朴素:不同的数据有不同的用途,读写权限也不一样,分开管理更清晰。

打个比方,你去图书馆借书。图书馆里有借阅区(可以借走)、阅览区(只能现场看)、新书展示区(工作人员可以更新)、档案区(只读不借)。Modbus的四种数据区就类似这个逻辑:

  • 线圈(Coils):可读可写,对应开关量输出。比如控制继电器吸合、指示灯亮灭。地址范围是00001到09999。
  • 离散输入(Discrete Inputs):只读,对应开关量输入。比如按钮状态、限位开关信号。地址范围是10001到19999。
  • 输入寄存器(Input Registers):只读,对应模拟量输入。比如温度传感器读数、电压采样值。地址范围是30001到39999。
  • 保持寄存器(Holding Registers):可读可写,对应模拟量输出或参数存储。比如设定温度值、PID参数。地址范围是40001到49999。

这个分类不是随便定的,它直接决定了你在上位机或PLC里能用什么功能码去访问。比如你要读一个温度值,它存在输入寄存器里,你就得用功能码04;如果你要写一个设定值到保持寄存器,就得用功能码06或16。

2.2 地址编号的两种表示方式:协议地址与PLC地址

这里是最容易把人绕晕的地方。Modbus地址有两种表示方式,一种是协议地址(也叫逻辑地址、偏移地址),另一种是PLC地址(也叫物理地址、寄存器地址)。两者之间差了一个偏移量。

协议地址是从0开始编号的,比如保持寄存器的协议地址是0x0000到0xFFFF。而PLC地址是从40001开始编号的,对应协议地址0x0000。也就是说,PLC地址40001等于协议地址0,40002等于协议地址1,以此类推。

为什么会有这个差异?因为早期PLC厂商在实现Modbus协议时,为了方便工程师记忆和使用,把数据区类型和地址范围直接编码到了地址数字里。40001这个数字本身就告诉你:这是保持寄存器,第1个。而协议层面的报文里,实际传输的是0x0000。

我见过太多人在这上面栽跟头。比如在Modbus Poll里填地址,如果你填40001,软件可能会自动帮你转换成协议地址0;但如果你填0,它就直接按协议地址0去读。不同软件的处理方式还不一样,有的加偏移,有的不加。所以调试的时候一定要先确认软件用的是哪种地址体系。

2.3 四种数据区的地址范围与功能码对应关系

下面这张表把四种数据区的地址范围、功能码、读写权限整理清楚了,建议收藏:

数据区PLC地址范围协议地址范围常用功能码读写权限典型用途
线圈00001-099990x0000-0x270F01, 05, 15读写继电器输出、指示灯
离散输入10001-199990x0000-0x270F02只读按钮、限位开关
输入寄存器30001-399990x0000-0x270F04只读温度、电压采样
保持寄存器40001-499990x0000-0x270F03, 06, 16读写设定值、参数存储

注意看协议地址范围那一列,四种数据区的协议地址都是从0x0000开始的,最大到0x270F(即9999)。这意味着每种数据区最多支持10000个数据点。当然,实际设备可能只实现其中一部分,具体支持多少要看设备手册。

功能码这块也有讲究。读线圈用01,写单个线圈用05,写多个线圈用15;读离散输入用02;读输入寄存器用04;读保持寄存器用03,写单个保持寄存器用06,写多个保持寄存器用16。这些功能码在报文里是一个字节,比如01就是0x01,03就是0x03。

3. 地址换算与不同设备映射的实操细节

3.1 协议地址与PLC地址的换算方法

换算规则其实很简单,但必须记牢:

  • 线圈:PLC地址 = 协议地址 + 1,即00001对应协议地址0
  • 离散输入:PLC地址 = 协议地址 + 10001,即10001对应协议地址0
  • 输入寄存器:PLC地址 = 协议地址 + 30001,即30001对应协议地址0
  • 保持寄存器:PLC地址 = 协议地址 + 40001,即40001对应协议地址0

反过来,如果你知道PLC地址,想算协议地址:

  • 线圈:协议地址 = PLC地址 - 1
  • 离散输入:协议地址 = PLC地址 - 10001
  • 输入寄存器:协议地址 = PLC地址 - 30001
  • 保持寄存器:协议地址 = PLC地址 - 40001

举个例子,你在设备手册上看到“保持寄存器40021”,那它的协议地址就是40021 - 40001 = 20,也就是0x0014。在Modbus报文里,你会看到地址字段是0x0014。

再比如,手册上写“线圈00005”,协议地址就是5 - 1 = 4,即0x0004。报文里地址字段就是0x0004。

这个换算在调试的时候一定要动手算一遍,别偷懒。我见过有人直接把40001填到报文里,结果读出来的是完全不相干的数据,就是因为没做换算。

3.2 不同品牌PLC的Modbus地址映射差异

虽然Modbus协议是标准的,但不同厂家在实现的时候,地址映射方式会有差异。这个差异主要体现在两个方面:一是数据区到内部存储区的映射关系,二是地址编号的起始规则。

以西门子S7-200 SMART为例,它的Modbus地址映射是这样的:保持寄存器40001对应V存储区的VW0,40002对应VW2,以此类推。也就是说,每个保持寄存器占2个字节,对应一个VW(字)。如果你要读VW100,那对应的Modbus地址就是40001 + (100/2) = 40051。

三菱FX系列PLC的映射又不一样。FX5U做Modbus TCP主站时,保持寄存器40001对应D0,40002对应D1,每个寄存器对应一个16位数据寄存器。如果你要读D100,Modbus地址就是40101。

国产DCS和国产PLC在这方面也有自己的规则。有的把保持寄存器直接映射到内部寄存器区,有的做了偏移。所以拿到一个新设备,第一件事就是翻手册找Modbus地址映射表,别凭经验猜。

3.3 地址规划中的常见陷阱与规避方法

在实际项目中,地址规划有几个坑特别容易踩:

第一个坑:地址重叠。有些设备把输入寄存器和保持寄存器的协议地址都从0开始编,如果你不区分功能码,光看地址数字,很容易搞混。比如协议地址0x0000,用功能码04读的是输入寄存器,用功能码03读的是保持寄存器,完全是两个不同的数据。所以地址规划时一定要把数据区类型和地址一起记,不能只记数字。

第二个坑:字节序问题。Modbus协议规定寄存器是16位的,但一个32位浮点数需要两个寄存器来存。这两个寄存器的顺序,不同厂家可能不一样。有的高字在前,有的低字在前。如果你读出来一个浮点数,发现数值完全不对,大概率是字节序或字序搞反了。这时候需要调整寄存器的组合顺序,或者在上位机里设置字节序参数。

第三个坑:地址偏移量不统一。有的设备手册写的是协议地址,有的写的是PLC地址,有的甚至写的是“从0开始的第几个寄存器”。这三种表述方式混在一起,很容易让人算错。我的习惯是,拿到手册先确认它用的是什么地址体系,然后统一换算成协议地址,再填到调试工具里。

第四个坑:保留地址和系统地址。有些设备的Modbus地址空间里,前面一段是系统保留的,不能随便读写。比如前100个保持寄存器可能被系统占用了,你只能从40101开始用。这个信息通常在手册的地址映射表里有标注,不看的话可能会写到系统参数区,导致设备异常。

4. 用调试工具验证地址规则的实际操作

4.1 Modbus Poll与Modbus Slave的地址设置要点

Modbus Poll和Modbus Slave是调试Modbus最常用的两个工具,一个做主机模拟,一个做从机模拟。这两个工具在地址设置上有一个关键选项:Address显示格式。

在Modbus Poll里,打开Setup菜单,有一个“Address”选项,可以选“Protocol Address”或“PLC Address”。如果你选Protocol Address,那地址栏里填的就是协议地址,比如0、1、2;如果你选PLC Address,那地址栏里填的就是40001、40002这种。

我个人的习惯是统一用Protocol Address,因为报文里传的就是协议地址,这样对起来最直接。但如果你要跟别人沟通,对方习惯说40001,那你就得换算一下。

Modbus Slave这边也一样,它模拟从站的时候,你需要设置每个数据区的起始地址和数量。比如你要模拟100个保持寄存器,起始地址设为0,数量设为100,那对应到PLC地址就是40001到40100。

这里有个细节要注意:Modbus Slave的地址设置里,如果你填的是0,它默认就是协议地址0。但有些版本的软件会有一个“PLC Address”的勾选项,勾上之后填40001才会对应协议地址0。所以每次用新版本软件,先确认一下这个设置。

4.2 用报文抓包验证地址换算是否正确

光看软件界面还不够,最靠谱的验证方法是抓报文。你可以用Wireshark抓Modbus TCP的包,或者用串口助手抓Modbus RTU的包,看实际传输的地址字段是多少。

比如你在Modbus Poll里设置读保持寄存器,起始地址填0,数量填10。抓到的报文里,功能码是03,起始地址字段是0x0000,数量字段是0x000A。这就验证了协议地址0对应的是第一个保持寄存器。

如果你在Modbus Poll里填的是40001,抓到的报文起始地址字段还是0x0000,那就说明软件自动做了换算。如果抓到的起始地址字段是0x9C41(40001的十六进制),那就说明软件没做换算,直接把PLC地址当协议地址发出去了,这肯定读不到数据。

这个验证方法我强烈推荐,尤其是第一次对接某个新设备的时候。花十分钟抓个包,比瞎试半天强得多。

4.3 常见错误码与地址问题的关联分析

Modbus协议里有一些错误码,跟地址问题直接相关。比如错误码9003,这个在有些调试工具里会出现,通常表示“非法数据地址”。意思是你请求的地址超出了从站支持的范围。

遇到9003,先检查三件事:第一,你请求的地址是不是超出了设备手册标明的范围;第二,你用的功能码跟数据区类型是不是匹配,比如用03去读输入寄存器,有些设备会返回错误;第三,地址换算是不是做对了,有没有把PLC地址直接当协议地址发出去。

还有一个常见错误是“非法功能码”,这个跟地址关系不大,但有时候是因为设备不支持某个功能码。比如有些简易从站只支持03和06,不支持16,你发16就会报错。

另外,如果你读多个寄存器,起始地址加上数量超过了设备支持的最大地址,也会报非法数据地址。比如设备只支持100个保持寄存器,协议地址0到99,你从地址95开始读10个,就会读到地址104,超出范围了。

5. 地址规则在典型工控场景中的应用

5.1 PLC与变频器通信的地址映射实例

变频器是工控现场最常见的Modbus从站设备之一。以某品牌变频器为例,它的Modbus地址映射表通常包含这几类数据:

  • 运行状态字:输入寄存器,协议地址0x0000,对应PLC地址30001
  • 输出频率:输入寄存器,协议地址0x0001,对应PLC地址30002
  • 设定频率:保持寄存器,协议地址0x0000,对应PLC地址40001
  • 加速时间:保持寄存器,协议地址0x0001,对应PLC地址40002
  • 控制命令字:保持寄存器,协议地址0x0002,对应PLC地址40003

PLC作为主站,要读变频器的输出频率,就用功能码04读输入寄存器协议地址0x0001;要写设定频率,就用功能码06写保持寄存器协议地址0x0000。

这里有个细节:不同品牌的变频器,地址映射表差别很大。有的把运行状态放在保持寄存器里,有的放在输入寄存器里。所以每次对接新变频器,第一件事就是找它的Modbus通信手册,把地址映射表抄下来,做成一个对照表贴在工位上。

5.2 上位机与多从站通信的地址规划策略

当一个上位机要跟多个从站通信时,地址规划就变得更重要了。因为每个从站都有自己的地址空间,上位机需要区分“跟哪个站通信”和“读哪个地址”。

Modbus的从站地址是一个字节,范围1到247。0是广播地址,248到255保留。所以一个Modbus网络最多可以有247个从站。

上位机在规划地址时,通常会建立一个二维表:从站地址 + 寄存器地址。比如1号从站的保持寄存器40001,2号从站的保持寄存器40001,这是两个不同的数据点。

在组态软件里,通常会有一个“设备地址”和“寄存器地址”两个字段。设备地址填从站号,寄存器地址填Modbus地址。有的软件还支持“站号.地址”的写法,比如1.40001表示1号从站的40001寄存器。

我做过一个项目,上位机要跟20台变频器通信,每台变频器有10个参数要读写。如果地址规划不清晰,后期维护会非常痛苦。我的做法是做一个Excel表格,列出每台变频器的站号、参数名称、Modbus地址、数据类型、读写权限,然后导入到组态软件里。这样后期查问题的时候,直接看表格就行,不用去翻程序。

5.3 国产DCS与Modbus设备的集成要点

国产DCS这几年发展很快,很多项目里DCS需要跟Modbus设备集成。DCS这边通常作为Modbus主站,去读现场设备的Modbus从站数据。

集成的关键点在于地址映射。DCS内部有自己的数据库和地址体系,需要把Modbus地址映射到DCS的内部地址上。这个映射关系通常在DCS的组态软件里配置。

配置的时候要注意几个问题:第一,DCS的Modbus驱动支持哪些功能码,有的只支持03和04,不支持01和02;第二,DCS的扫描周期跟Modbus通信超时时间要匹配,如果扫描周期太短,Modbus响应还没回来,就会报通信故障;第三,DCS的地址映射表要跟现场设备的手册对齐,不能凭经验填。

我参与过一个国产DCS项目,现场有几十台Modbus仪表。调试的时候发现有几台仪表的数据一直读不上来,后来查了半天,发现是DCS的Modbus驱动默认用协议地址,而仪表手册写的是PLC地址,组态的时候没做换算。把地址减掉40001之后,数据就正常了。

6. 地址规则相关的常见问题与排查技巧

6.1 地址对不上时的系统排查流程

地址对不上是Modbus调试中最常见的问题。我总结了一个排查流程,按这个顺序走,基本能定位到问题:

第一步,确认物理连接和通信参数。串口的话,波特率、数据位、停止位、校验位要跟设备一致;网口的话,IP地址、端口号、单元标识符要正确。这一步没问题了,再往下查。

第二步,确认功能码和数据区类型匹配。你要读的是线圈还是寄存器,是输入寄存器还是保持寄存器,功能码用对了没有。

第三步,确认地址换算。设备手册写的是PLC地址还是协议地址,你填到调试工具里的是哪种地址,有没有做换算。

第四步,确认地址范围。你请求的地址是不是在设备支持的范围内,起始地址加数量有没有超出上限。

第五步,抓包看报文。看实际发出的地址字段是多少,跟预期是否一致。

这个流程走下来,大部分地址问题都能解决。

6.2 地址规则速查表与避坑清单

下面这张表把常见的地址问题和解决方法整理了一下,方便快速查阅:

问题现象可能原因排查方法解决方法
读不到数据,超时从站地址错误确认从站号设置修改从站地址
返回非法数据地址地址超出范围查设备手册地址范围调整起始地址或数量
读到的数据不对地址换算错误抓包看地址字段做PLC地址到协议地址的换算
写不进去功能码不支持查设备支持的功能码换用支持的功能码
浮点数数值异常字节序或字序错误检查寄存器组合顺序调整字节序设置
部分数据读不到地址被系统保留查手册保留地址说明避开保留地址段

避坑清单:

  • 拿到新设备,先找Modbus通信手册,确认地址映射表
  • 确认手册用的是PLC地址还是协议地址,统一换算成协议地址
  • 调试工具里确认地址显示格式设置
  • 第一次通信成功之后,抓包保存报文,作为后续对照
  • 多从站项目,做地址规划表,别靠脑子记
  • 浮点数读写,先确认字节序和字序
  • 地址规划留余量,别把地址用满

6.3 从实际项目踩坑中总结的经验

说几个我实际踩过的坑。

有一次调试一个称重仪表,手册上写“重量值:输入寄存器30001”。我在Modbus Poll里填了30001,结果读出来是0。后来抓包发现,报文里的地址字段是0x7531(30001的十六进制),而仪表期望的是0x0000。原来Modbus Poll默认把填进去的数字当协议地址,我填30001,它就发0x7531。改成填0之后,数据就正常了。

还有一次,一个项目里PLC要读变频器的频率。手册上写“输出频率:保持寄存器40001”。我在PLC程序里填了40001,读出来是0。查了半天,发现PLC的Modbus库函数里,地址参数用的是协议地址,不是PLC地址。改成0之后,数据就对了。

最坑的一次是浮点数。一个流量计的输出是32位浮点数,存在两个保持寄存器里。我按高字在前的顺序读出来,数值完全不对。后来试了低字在前,还是不对。最后发现是字节序的问题,需要把每个寄存器的两个字节也交换一下。调整之后,数值才正确。

这些坑说到底,都是地址规则没吃透。Modbus协议本身不复杂,但地址这块的细节特别多,不同厂家还有不同的实现方式。所以我的建议是,每次对接新设备,先把地址规则搞清楚,别急着写程序。花半个小时看手册、做换算、抓包验证,能省下后面几天的调试时间。

地址规则这个东西,说难不难,说简单也不简单。关键是要有耐心,一步一步来,别凭经验猜。手册上写的每一个地址,都要自己动手算一遍,验证一遍。时间长了,你看到40001就知道协议地址是0,看到30001就知道是输入寄存器,看到00001就知道是线圈。这种直觉,是靠一个个项目积累出来的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询