Modbus协议把交互数据分成四个区域,可以把它理解成四张抽屉,先弄清哪张抽屉能放什么、能取什么,后面选功能码才不会乱。线圈是可读可写的位,对应PLC的Q输出和M中间继电器;离散输入是只读的位,对应I输入点,外部按钮和接近开关的信号都在这里;保持寄存器是可读可写的16位字,仪表参数、设定值、变频器频率多放在这一区;输入寄存器是只读的16位字,一般存放电压、电流、温度等实时测量值。
四个区各对应一读一写两类操作,现场常用的功能码只有八个:01读线圈、02读离散输入、03读保持寄存器、04读输入寄存器、05写单个线圈、06写单个寄存器、0F写多个线圈、10写多个寄存器。吃透这八个,就能应付绝大部分Modbus应用。
这是现场容易踩的坑。Modbus协议地址从0开始,而设备手册里写的往往是40001这类显示地址,两者之间差1。保持寄存器的显示地址40001对应协议地址0,40002对应协议地址1,依此类推。手册写“地址40003读取量程上限”,填进PLC指令的起始地址应该是2。把手册里的显示地址直接当协议地址填,读回来的数据会整体错位。养成一个习惯:涉及Modbus地址先问一句“这是协议地址还是显示地址”,没有说明就按相差1处理。
比地址偏移更隐蔽的是字节序。Modbus单个寄存器16位,内部高字节在前。一旦涉及32位浮点数,两个寄存器谁前谁后、每个寄存器内部高低字节是否交换,不同厂商的处理方式不一样。以压力值234.56为例,它的单精度浮点十六进制是0x436AD1EC,现场可能出现正序、字序反、字节序反等多种存储组合,PLC不做对应处理,读出来的就是天文数字。
判断流程可以直接照用:先用调试软件读回目标寄存器的原始十六进制值,再用浮点转换工具按不同排列组合试算,得到合理量程内数值的那一种就是正确顺序;然后在PLC程序里用字交换或字节交换指令调整,或者在通讯库的字节序选项里选对模式。
以读取一台RS485压力变送器为例。接线环节坑较多:A、B两根差分线不能接反,通讯失败先对调再试;用屏蔽双绞线,屏蔽层单端接地;线缆超过50米时在末端并接120欧终端电阻,能有效减少信号反射带来的偶发错误。正式写程序前,先用电脑加USB转485转换器连上变送器,用调试软件发一条03读请求验证参数,确认从站地址、功能码、起始地址、数量、字序模式,再把这些参数一对一填进PLC主站指令,成功率会高很多。读回的浮点值做量程转换时,建议放到触摸屏侧处理,减少PLC的浮点运算开销。
还有两个工程习惯值得养成:每次项目把设备寄存器表整理成点表存档,标注协议地址、显示地址、数据格式和缩放系数;在PLC程序里留通讯状态位和错误码寄存器,并把通讯故障做到报警画面里,现场人员能直接告诉你“通讯断了”,而不是让你漫无目的地查程序。