MODBUSTCP整理资料

49 /* ----------------------- MBAP Header --------------------------------------*/
 50 /*
 51  *
 52  * <------------------------ MODBUS TCP/IP ADU(1) ------------------------->
 53  *              <----------- MODBUS PDU (1') ---------------->
 54  *  +-----------+---------------+------------------------------------------+
 55  *  | TID | PID | Length | UID  |Code | Data                               |
 56  *  +-----------+---------------+------------------------------------------+
 57  *  |     |     |        |      |                                          
 58  * (2)   (3)   (4)      (5)    (6)                                         
 59  *
 60  * (2)  ... MB_TCP_TID          = 0 (Transaction Identifier - 2 Byte)
 61  * (3)  ... MB_TCP_PID          = 2 (Protocol Identifier - 2 Byte)
 62  * (4)  ... MB_TCP_LEN          = 4 (Number of bytes - 2 Byte)
 63  * (5)  ... MB_TCP_UID          = 6 (Unit Identifier - 1 Byte)
 64  * (6)  ... MB_TCP_FUNC         = 7 (Modbus Function Code)
 65  *
 66  * (1)  ... Modbus TCP/IP Application Data Unit
 67  * (1') ... Modbus Protocol Data Unit
 68  */
 69
 70 #define MB_TCP_TID          0
 71 #define MB_TCP_PID          2
 72 #define MB_TCP_LEN          4
 73 #define MB_TCP_UID          6
 74 #define MB_TCP_FUNC         7
 75
 76 #define MB_TCP_PROTOCOL_ID  0   /* 0 = Modbus Protocol */

表1 ModBus功能码
功能码         名称                    作用
01         读取线圈状态        取得一组逻辑线圈的当前状态(ON/OFF)
02         读取输入状态         取得一组开关输入的当前状态(ON/OFF) only read
功能码01、02读到的位满8个组合成一个字节,可以用功能04读取
03         读取保持寄存器         在一个或多个保持寄存器中取得当前的二进制值 保持寄存器,设置的各种参数3xxxx
04         读取输入寄存器         在一个或多个输入寄存器中取得当前的二进制值  输入寄存器,实时数据 4xxxx only read

05         强置单线圈         强置一个逻辑线圈的通断状态
06         预置单寄存器         把具体二进值装入一个保持寄存器

07         读取异常状态         取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态
08         回送诊断校验         把诊断校验报文送从机,以对通信处理进行评鉴
09         编程(只用于484)         使主机模拟编程器作用,修改PC从机逻辑
10         控询(只用于484)         可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送
11         读取事件计数         可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时
12         读取通信事件记录         可是主机检索每台从机的ModBus事务处理通信事件记录。如果某项事务处理完成,记录会给出有关错误
13         编程(184/384 484 584)         可使主机模拟编程器功能修改PC从机逻辑
14         探询(184/384 484 584)         可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送

15         强置多线圈         强置一串连续逻辑线圈的通断
16         预置多寄存器         把具体的二进制值装入一串连续的保持寄存器

17         报告从机标识         可使主机判断编址从机的类型及该从机运行指示灯的状态
18         (884和MICRO 84)         可使主机模拟编程功能,修改PC状态逻辑
19         重置通信链路         发生非可修改错误后,是从机复位于已知状态,可重置顺序字节
20         读取通用参数(584L)         显示扩展存储器文件中的数据信息
21         写入通用参数(584L)         把通用参数写入扩展存储文件,或修改之
22~64         保留作扩展功能备用       
65~72         保留以备用户功能所用         留作用户功能的扩展编码
73~119         非法功能       
120~127         保留         留作内部作用
128~255         保留         用于异常应答


表2 ModBus功能码与数据类型对应表
代码        功能        数据类型
01        读        位
02        读        位
03        读        word(16bit)
04        读        word(16bit)
05        写        位
06        写        整型、字符型、状态字、浮点型
08        N/A        重复“回路反馈”信息
15        写        位
16        写        整型、字符型、状态字、浮点型

 

    常用Modbus寄存器有:线圈(Coil)、输入(Input)、保持寄存器(Holding Registers)和输入寄存器(Input Registers)。

    从Modbus设备角度看,输入是上位机采集Modbus设备的信息,也就是这些寄存器是只读的,所以,Modbus协议没有写输入(Input)和输入寄存器(Input Registers)的命令。

    线圈(Coil)是状态量,对应Modbus设备的开关量输出(DO),保持寄存器(Holding Registers)是模拟量,对应Modbus设备模拟量输出(AO),这些寄存器需要Modbus设备的上位机进行设置,也就是为可以写的寄存器。

    在Modicon_Modbus协议 协议中,写线圈(Coil)和保持寄存器(Holding Registers)都有两种写命令:

        1)、写单个寄存器:
        置单线圈(Force Single Coil)功能码05(0x05)
        写单个寄存器(Preset Single Holding Register)功能码06(0x06)
        ------------------------------------------------------------------------------
        2)、写多个寄存器
        写多线圈(Force Multiple Coils)功能码15(0x0F)
        写多个寄存器(Preset Multiple Registers)功能码16(0x10)

MODbus数据帧格式:
modbus信息嵌入在LLC层数据帧,HDLC(数据链路控制层)进行CRC校验

MODBUS包含四种寄存器:
1.线圈
2.输入点
3.保持寄存器
4.输入寄存器
其中输入点和输入寄存器为只读

MODBUS常用功能码:
===========================================================================
---------------------------------------------------------------------------
0X线圈操作:01 05 15
01 读线圈状态
读从机离散量输出口的开关状态。
例:读从设备线圈地址为00020(modbus地址0x0013)的37个线圈,即00020-00056
查询:查询时需要指定起始线圈和线圈量,以最地位开始绕线圈,最高位不足补零。
[0 - 1][2 - 3][4 - 5] [6] [7] [8 - 9]    [10 - 11]
  TID     PID   长度   ID func start_addr data
[00][04][00][00][00][06][FF][01][00][13][00][25]
注意:modbus协议和PLC之间,modbus线圈地址从0开始,设备地址从1开始,其他寄存器也是这种关系。
响应:
<00><04><00><00><00><08><FF><01><05><CD><6B><B2><0E><1B>
那么线圈00020-00056的状态为:
coils:
27-20: 1100 1101
35-28: 0110 1011
43-36: 1011 0010
51-44: 0000 1110
56-52: 0001 1011 (高位补零)
数据长度<05>= (线圈数 + 7)/8=5
在libmodbus测试代码中unit-test.h,定义了如下的地址信息:
 31 const uint16_t UT_BITS_ADDRESS = 0x13;
 32 const uint16_t UT_BITS_NB_POINTS = 0x25;
 33 const uint8_t UT_BITS_TAB[] = { 0xCD, 0x6B, 0xB2, 0x0E, 0x1B };
在分析libmodbus时,看到这几个测试地址和值想不明白为什么是这几个数,看了modicon关于MODBUS协议的定义,原来这几个地址和值,是它协议(设备M84984...)上面的例子。
--------------------------------------------------------------------------
05强制单个线圈
强制单个线圈的状态的状态,可以广播地址,使所有从机同一线圈同为1或0
以请求数据的数据区规定请求线圈的开关状态
0xFF00 ON
0x0000 OFF
例:强制从机设备(广播)中00020(0x0013)线圈为ON
请求:
[00][01][00][00][00][06][FF][05][00][13][FF][00]
查询:
<00><01><00><00><00><06><FF><05><00><13><FF><00>
-------------------------------------------------------------------------
15强制多个线圈
按线圈的顺序把各线圈强制成ON/OFF,支持广播
例:强制将设备起始线圈位00020的37个线圈强制,数据中1位代表一个线圈状态,1为ON
查询:
[00][03][00][00][00][0C][FF][0F][00][13][00][25][05][CD][6B][B2][0E][1B]
响应:
<00><03><00><00><00><06><FF><0F><00><13><00><25>

以上是3种线圈操作,包括读单/多组线圈(1),强制单个线圈(5),强制多个线圈(15)
---------------------------------------------------------------------------
===========================================================================

===========================================================================
---------------------------------------------------------------------------
4X保持寄存器功能码:03 06 16
03 读保持寄存器:
保持寄存器一般做内存存储和模拟量输出,不支持广播,查询信息包含了寄存器起始地址和数量
例:读寄存器起始地址是40108(0x006B)的一个寄存器,40108寄存器对应MODBUS协议中0x006B地址
查询:
[00][07][00][00][00][06][FF][03][00][6B][00][01]
响应:
<00><07><00><00><00><05><FF><03><02><12><34>
以上表示寄存器40108的数据为0x1234两个byte。一个寄存器是16位(2B)。
-----------------------------------------------------------------------
06 置单个保持寄存器
把一个值预置到一个4X类型保持寄存器中,支持广播
查询:
查询信息包含寄存器起始地址。
例:请求把从机寄存器40108(0x406B)预置为0x1234
[00][06][00][00][00][06][FF][06][00][6B][12][34]
响应:寄存器内容被预置后返回正常响应,
<00><06><00><00><00><06><FF><06><00><6B><12><34>
----------------------------------------------------------------------
16 预置多个寄存器
把数据按顺序预制到4X类型保持寄存器,支持广播
例:请求预置40108(0x006B)寄存器为起始地址的3个寄存器依次置为0x0602,0x0b,0x0064.
查询:40108-40109-40110(每个寄存器2B)
[00][08][00][00][00][0D][FF][10][00][6B][00][03][06][02][2B][00][00][00][64]
字段说明:
FF  --广播地址
10  --功能码
006B -- 寄存器地址
0003 -- 寄存器数量
06   -- 数据字节数
后面6个自己为数据
响应:
<00><08><00><00><00><06><FF><10><00><6B><00><03>
正常响应从机地址功能码,预置寄存器起始地址和数量
------------------------------------------------------------------------
========================================================================
=========================================================================
-------------------------------------------------------------------------
1X输入位状态操作 02 只读
02读输入状态
读从机离散量输入状态,不支持广播
例:请求读从机设备地址为10197(0x00C4)开始的22(0x16)个输入状态
请求:
[00][05][00][00][00][06][FF][02][00][C4][00][16]
响应:
<00><05><00><00><00><06><FF><02><03><AC><DB><35>
<03>  -- 字节数=(输入量 + 7)/8 =29/8
响应数据位每位表示一个输入状态,从最低位开始,最高位填零

这个寄存器通常作为,开关量的输入寄存器,只可读不可写,输入对于主站而言。
-------------------------------------------------------------------------
=========================================================================

=========================================================================
-------------------------------------------------------------------------
3X输入寄存器操作 04 只读
04读输入寄存器,读取从机3X类型输入寄存器的而数据,不支持广播
例:请求读从机的30009寄存器
查询:查询信息规定了要读的寄存器起始地址和数量
[00][0D][00][00][00][06][FF][04][00][08][00][01]
响应:
<00><0D><00><00><00><05><FF><04><02><00><0A>
========================================================================
以上是MODBUS TCP中最最常用的功能码操作

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值