2. 标准功能码回顾:01-06功能码详解、15-16功能码详解、功能码分类与适用场景

各位同学,咱们今天聊点实在的。

在深入扩展功能码之前,我强烈建议先把标准功能码吃透。为什么?因为扩展功能码本质上是在标准功能码基础上的「魔改」。你连01-06都没玩明白,后面那些花里胡哨的扩展码,你肯定用不顺手。

我自己带团队时,有个不成文的规矩:新来的工程师,先给我把01、03、06这三个码背下来,再谈别的。这不是刁难,是血的教训换来的经验。

2.1 位操作功能码:01、02、05、15

先说位操作。说白了,就是针对单个「开关量」的读写。

01功能码:读线圈状态

这个最常用。读取PLC或远程IO模块的DO(数字量输出)状态。

我记得有一次在现场调试,一个老工程师跟我说:「01码读的是线圈,不是输入。」我当时还纳闷,后来才明白——线圈对应的是输出,不是输入。这个区分很重要。

请求格式:

从站地址 + 0x01 + 起始地址(2字节) + 数量(2字节) + CRC

响应格式:

从站地址 + 0x01 + 字节数 + 数据(N字节) + CRC

注意一点:起始地址是从0开始的。比如你要读第1个线圈,地址写0x0000。很多新手在这里栽跟头,我见过有人把地址写成1,结果读回来的数据全是乱的。

02功能码:读离散输入

这个读的是DI(数字量输入),也就是传感器、按钮这些外部信号。

02和01的区别,说白了就是一个读输入,一个读输出。但实际项目中,02码用得比01少。为什么?因为很多设备把DI映射到了保持寄存器里,大家更习惯用03码去读。

05功能码:写单个线圈

控制单个DO点。比如启动电机、打开阀门。

个人经验:05码写数据时,0xFF00代表ON,0x0000代表OFF。其他值?别乱试。我曾经见过一个设备,收到0xFF01后直接死机了。嗯,从那以后我再也不敢写非标值了。

15功能码:写多个线圈

这个就厉害了。一次可以控制多个DO点,效率比05码高得多。

避坑指南:我曾经在一条生产线上,用15码同时控制16个气缸。结果发现,如果连续发送15码请求,有些从站会丢包。后来查了手册才知道——某些从站的15码处理缓冲区只有128字节。超过这个数,你就得拆包发送。

2.2 字操作功能码:03、04、06、16

字操作,处理的是16位的数据。模拟量、计数器、设定值,全在这里。

03功能码:读保持寄存器

这是Modbus里最常用的功能码,没有之一。

我统计过,在我经手的项目中,03码的使用频率占了总通讯量的60%以上。为什么?因为保持寄存器既能读又能写,而且可以存各种数据——整数、浮点数、字符串,全都能塞进去。

请求格式:

从站地址 + 0x03 + 起始地址(2字节) + 寄存器数量(2字节) + CRC

响应格式:

从站地址 + 0x03 + 字节数 + 数据(N字节) + CRC

注意:一次最多读125个寄存器。这是Modbus协议规定的上限。你非要读126个?从站会给你回一个异常码0x03(非法数据值)。

04功能码:读输入寄存器

这个读的是只读数据,比如温度、压力、流量。

04码和03码的区别,你想想看——04码的数据是「只读」的,你只能看,不能改。这在安全要求高的场合特别有用。比如核电站的辐射监测数据,谁敢让你随便写?

06功能码:写单个寄存器

写一个16位的数据。比如设定一个PID参数、修改一个报警值。

我的习惯:在调试阶段,我更喜欢用06码而不是16码。为什么?因为06码一次只写一个寄存器,出错了容易排查。16码一次写一堆,万一哪个地址写错了,找起来很麻烦。

16功能码:写多个寄存器

批量写寄存器,效率高。比如下载一组配方参数、更新一批设定值。

注意:我曾经在项目里用16码一次写了100个寄存器,结果从站处理了将近2秒才回复。那2秒里,主站一直在等,整个系统都卡住了。后来我学乖了——批量写的时候,一次别超过20个寄存器,分几次写,系统反而更流畅。

2.3 功能码分类与适用场景

好了,咱们把常用的功能码捋一遍。我习惯把它们分成三类:

类别 功能码 操作对象 典型场景
位操作(读) 01、02 线圈、离散输入 读取按钮状态、传感器信号
位操作(写) 05、15 线圈 控制继电器、指示灯、电机启停
字操作(读) 03、04 保持寄存器、输入寄存器 读取温度、压力、速度、累计量
字操作(写) 06、16 保持寄存器 设定PID参数、修改报警阈值

怎么选?我给你几个原则:

  • 读开关量:用01或02。别用03去读,那是杀鸡用牛刀。
  • 写单个点:用05或06。简单、可靠、好排查。
  • 批量操作:用15或16。但注意数量限制,别贪多。
  • 只读数据:用04。安全第一。
  • 读写数据:用03和06/16组合。这是最通用的方案。

总结一下:

标准功能码是Modbus的基石。你把这些码用熟了,后面学扩展功能码就会轻松很多。我见过太多人一上来就研究自定义功能码,结果连03码的地址偏移都没搞明白——那真是本末倒置了。

下一章,咱们开始聊扩展功能码。但在此之前,我建议你把今天的内容亲手敲一遍代码。纸上得来终觉浅,绝知此事要躬行。