1 modbus通讯
1.1 modbus 通讯数据格式
| 地址码 |
功能码 |
数据区 |
校验码 |
| 1个字节 |
1个字节 |
N个字节 |
16位CRC |
1.2 功能码
| 功能码 |
描述 |
说明 |
MOUBUS地址 |
| 01 |
读输出线圈寄存器 |
位操作 |
00001 ~ 09999 |
| 02 |
读离散输入寄存器 |
位操作 |
10001 ~ 19999 |
| 03 |
读保持(输出)寄存器 |
字操作 |
40001 ~ 49999 |
| 04 |
读输入寄存器 |
字操作 |
30001 ~ 39999 |
| 05 |
写单线圈寄存器 |
位操作 |
00001 ~ 09999 |
| 07 |
读取异常状态 |
获得8个内部线圈的逻辑状态 |
|
| 06 |
写单线圈保持寄存器 |
字操作 |
40001 ~ 49999 |
| 10 |
写多路寄存器 |
字操作 |
|
| 15 |
写多线圈寄存器 |
位操作 |
00001 ~ 09999 |
| 16 |
写多个保持寄存器 |
字操作 |
40001 ~ 49999 |
| 17 |
报告从机标识 |
可使主机判断从机标识的类型及其该从机运行指示灯的状态 |
|
1.3 数据区
1.3.1 格式
数据区格式不固定,一般需要查看从机设备的通讯手册
数据区格式示例:
| 开始编号/寄存器地址 |
数据个数 |
数据1 |
…… |
数据n |
| 2个字节 |
2个字节 |
2个字节 |
2个字节 |
2个字节 |
1.3.2 寄存器地址
通常Modbus地址由5位数字组成,包括起始的数据类型代号,以及后面的偏移地址。Modbus Master协议库把标准的Modbus地址映射为所谓Modbus功能号,读写从站的数据。
Modbus Master协议库支持如下地址:
| 编号范围 |
含义 |
| 00001~09999 |
数字量输出(线圈) |
| 10001~19999 |
数字量输入(触点) |
| 30001~39999 |
输入数据寄存器(通常为模拟量输入) |
| 40001~49999 |
数据保持寄存器 |
由上表可知,Modbus通讯的地址是从1开始的,如果遇到从机设备的寄存器编号从0开始,那么就需要考虑给通讯地址加1处理。
即:
| Modbus地址 |
数据地址 (参数地址) |
| 1 |
0 |
| 2 |
1 |
| … |
… |
| n |
n-1 |
1.4 CRC校验
1.4.1 CRC校验算法步骤
- 第一步:设置CRC变量存储器初始值位0xFFFF;
- 第二步:把第一个参与校验的数据和CRC变量的低八位进行异或运算,结果仍存到CRC存储器中;
- 第三步:把CRC右移一位,最高位补0;
- 第四步:检查刚移出的最低位b0,如果b0=1,则CRC变量和0xA001进行异或运算,结果仍存在CRC变量存储器中,然后执行下一步。如果b0=0,则直接执行下一步;
- 第五步:重复3、4两步,只到右移8次。这样第一个数据处理就完成了,结果仍存在CRC变量存储器中。
- 第六步:重复2~5步,处理下一个数据,只到参与校验的数据均处理完毕。
- 注:最后获得的16位CRC校验值,在传输时,低八位在前,高八位在后;
1.4.2 CRC校验算法C语言程序
#include <stdio.h>
#define num 6
int main()
{
unsigned char buf[num]={0x01,0x04,0x00,0x0a,0x00,0x0a};
int i,n;
unsigned int crc16;
unsigned int temp;
crc16=0xffff;
i=0;n=0;
for(n=0;n<num;n++)
{
crc16 = buf[n]^crc16;
for(i=0;i<8;i++)
{
temp = crc16 & 0x0001;
crc16 = crc16 >> 1;
if(temp)
{
crc16 = 0xa001^crc16;
}
printf("CRC校验为:%x\n",crc16);
}
printf("---------------------------------\n");
}
printf("CRC校验为:%x\n",crc16);
}
1.5 MODBUS主问从答
1.5.1 读输出线圈
| 从机地址 |
功能码 |
寄存器起始地址 |
寄存器个数 |
CRC校验 |
| 01 |
01 |
00 02 |
00 01 |
5C 0A |
| 从机地址 |
功能码 |
字节个数 |
数据1 |
… |
CRC校验 |
| 01 |
01 |
01 |
01 |
- |
- |
1.5.2 读输入线圈
| 从机地址 |
功能码 |
寄存器起始地址 |
寄存器个数 |
CRC校验 |
| 01 |
02 |
00 01 |
00 01 |
E8 0A |
| 从机地址 |
功能码 |
字节个数 |
数据1 |
… |
CRC校验 |
| 01 |
02 |
01 |
FF |
- |
E1 C8 |
1.5.3 读输出寄存器
| 从机地址 |
功能码 |
寄存器起始地址 |
寄存器个数 |
CRC校验 |
| 01 |
03 |
00 01 |
00 01 |
D5 CA |
| 从机地址 |
功能码 |
字节个数 |
数据1 |
数据2 |
… |
CRC校验 |
| 01 |
03 |
02 |
02 |
05 |
- |
79 27 |
1.5.4 读输入寄存器
| 从机地址 |
功能码 |
寄存器起始地址 |
寄存器个数 |
CRC校验 |
| 01 |
04 |
00 04 |
00 01 |
70 0B |
| 从机地址 |
功能码 |
字节个数 |
数据1 |
数据2 |
… |
CRC校验 |
| 01 |
04 |
02 |
55 |
99 |
- |
16 0A |
1.5.5 主机写当个线圈寄存器
| 从机地址 |
功能码 |
寄存器起始地址 |
寄存器个数 |
CRC校验 |
| 01 |
05 |
00 03 |
FF 00 |
7C 3A |
- 从机应答格式
无应答
该节与1.5.1 读输出线圈互为读写
2 西门子PLC Modbus通讯
2.1 S7-200SMART地址转换MODBUS地址
| Modbus地址 |
S7-200数据区 |
| 00001~00128 |
Q0.0~Q15.7 |
| 10001~10128 |
I0.0~I15.7 |
| 30001~30032 |
AIW0~AIW62 |
| 40001~4xxxx |
如下 |
Modbus地址映射中:40001表示保持性寄存器,是一个字(两个字节),若对应是VW0。这 40001的高位字节存在VB0中,低位字节存在VB1中,而一个字节里位的权重是一样的,也就是一一对应。因此40001的第0位对应VB1的第0位,40001的第15位对应VB0的第7位。简言之,近似下面的表达:
40001.0 = V1.0
40001.1 = V1.1
40001.2 = V1.2
40001.3 = V1.3
40001.4 = V1.4
40001.5 = V1.5
40001.6 = V1.6
40001.7 = V1.7
40001.8 = V0.0
40001.9 = V0.1
40001.10 = V0.2
40001.11 = V0.3
40001.12 = V0.4
40001.13 = V0.5
40001.14 = V0.6
40001.15 = V0.7
2.2 CM1241模块
- CM1241指示灯
- DIAG指示灯:
- 亮红色:模块没有被PLC识别;
- 亮绿色闪烁:模块已经被PLC识别,但是软件没有进行配置;
- 亮绿色常亮:模块已经被PLC识别,而且软件中配置正确;
cm1241最多带12个485从机设备
2.3 S7-1200 MODBUS通讯指令介绍
MB_COMM_LOAD指令:用于设置Modbus(RTU)端口。

| 参数 |
说明 |
| EN |
使能 |
| REQ |
上升沿启动该指令 |
| PORT |
扩展模块的硬件标识符 |
| BAUD |
波特率 |
| PARITY |
0:无校验;1:奇校验;2:偶校验 |
| RESP_TO |
每个从站的读取延时时间 |
| MB_DB |
MB_MASTER / MB_SLAVE 指令的背景数据块 |
一个端口只能执行一次这个指令,可以选择放置到OB100中。
MB_MASTER指令

| 参数 |
说明 |
| EN |
使能 |
| REQ |
上升沿发送有一个读/写请求 |
| MB_ADDR |
从站地址 |
| MODE |
读写控制位;0:读;1:写; |
| PARITY |
0:无校验;1:奇校验;2:偶校验 |
| DATA_ADDR |
将要读/写的从机寄存器地址 |
| DATA_LEN |
访问寄存器的连续数量 |
| DNE |
完成标志位,可以用来激活下一个指令 |
| BUSY |
繁忙标志位 |
| ERROR |
错误标志位 |
| STAUS |
错误代码 |
所有评论(0)