Modbus 是Modicon 家的东东,所有的规矩都要它说了算。


先看一下modscan32对上文的设备的测试结果

01.


监视到串口的数据如下:

发出:01 01 00 00 00 03 7C 0B                  //01站地址,01功能号,00 00 起始地址,00 03要读的数据个数

接收:01 01 01 03 11 89                            //01站地址,01功能号,01返回的字节数,02即0000 0011 对应1个字节(后3位有效)


02.


监视到串口的数据如下:

发出:01 02 00 00 00 03 38 0B                 //01站地址,02功能号,00 00 起始地址,00 03要读的数据个数

接收:01 02 01 03 E1 89                           //01站地址,02功能号,01返回的字节数,03即0000 0011 对应1个字节(后3位有效)


03.


监视到串口的数据如下:

发出:01 03 00 00 00 03 05 CB                  //01站地址,03功能号,00 00 起始地址,00 03要读的数据个数

接收:01 03 06 00 00 00 01 00 02 F1 74    //01站地址,03功能号,06返回的字节数,00 00 00 01 00 02 对应6个字节3个数


04.


监视到串口的数据如下:

发出:01 04 00 00 00 03 B0 0B                  //01站地址,04功能号,00 00 起始地址,00 03要读的数据个数

接收:01 04 06 00 00 00 01 00 02 B0 92    //01站地址,04功能号,06返回的字节数,00 00 00 01 00 02 对应6个字节3个数


可以看到,modscan32

读modbus地址00001时,使用的是01功能号,并且发出的起始地址是0

读modbus地址10001时,使用的是02功能号,并且发出的起始地址是0

读modbus地址30001时,使用的是04功能号,并且发出的起始地址是0

读modbus地址40001时,使用的是03功能号,并且发出的起始地址是0

恩,这是modicon modbus 地址的规范。40001属于应用层,功能号部分应该属于"数据链路层"

最终交付给客户的地址都应该是如40001等形式的modbus地址,比如你如果定义40001为冰机蒸发器出水温度,对于一般的软件如modscan32,ModbusSerialDAServer都是采用modbus标准协议来写的,所以他们读取40001时,会发03功能号和地址0,所以在设备的响应程序里应该在接到03功能号和地址0的时候将这个温度值发出。

即对应关系是:modbu地址--->功能号,地址--->设备内部定义的变量


另外对modbus功能码:

01读取线圈状态,线圈为可读可写,比如plc中的DO可读可写,也可以是plc或单片机的某个内部位变量。

02读取输入状态,输入为只读,比如plc中DI的状态

03读取保持寄存器,保持寄存器为可读可写,比如plc中的AO通道,也可以是plc或单片机的某个内部变量

04读取输入寄存器,输入寄存器为只读,比如plc中的AI通道

05强制单个线圈

06强制单个保持寄存器


对modbus的功能码后的地址:

对于单片机可以是实际的某个寄存器,也可以是某个内部变量,按需选择。


refer to

Modicon Modbus Protocol Reference Guide

http://bbs.cechina.cn/thread-81236.html

**********************************************************************************************************************************************************************************

modscan32没有写功能,就试着对照着它也写了一个基于view/document的modbus读写小工具,取名叫modscan36。