- modbus通讯
1.1 modbus通讯数据格式
地址码(1个字节)+功能码(1个字节)+数据区(N个字节)+校验码(16位crc)
1.2功能码
功能码->描述->说明->modbus地址
01 -> 读输出线圈寄存器->位操作->00001-09999
02 -> 读离散输入寄存器 -> 位操作->10001-19999
03 -> 读保持(输出)寄存器 ->字操作->40001-49999
04 -> 读输入寄存器 ->资操作 ->30001-39999
05 -> 写单线圈寄存器 ->位操作 ->00001-09999
06 -> 写单线圈保持寄存器 ->字操作 ->40001-49999
15 -> 写多线圈寄存器 -> 位操作 ->00001-09999
16 ->写多个保持寄存器 -> 字操作 ->40001-49999
其余自行了解吧。
1.3数据格式
数据格式不固定,需要查看从机设备的通讯资料
开始编号/寄存器地址 | 数据个数 | 数据1 | …… | 数据n |
2个字节 | 2个字节 | 2个字节 | 2个字节 | 2个字节 |
寄存器地址
通常Modbus地址由5位数字组成,包括起始的数据类型代号,以及后面的偏移地址。Modbus Master协议库把标准的Modbus地址映射为所谓Modbus功能号,读写从站的数据。
Modbus Master协议库支持如下地址:
编号范围 | 含义 |
00001~09999 | 数字量输出(线圈) |
10001~19999 | 数字量输入(触点) |
30001~39999 | 输入数据寄存器(通常为模拟量输入) |
40001~49999 | 数据保持寄存器 |
1.4CRC校验
(1)设置crc变量存储器并初始化 0xFFFF
(2) 把第一个参与校验的数据和crc变量的低八位进行异或运算,结果存到crc存储器中
(3)把crc右移一位,最高位补0
(4)检查刚移出的最低位b0,如果b0=1,则CRC变量和0xA001进行异或运算,结果仍存在CRC 变量存储器中,然后执行下一步。如果b0=0,则直接执行下一步
(5)重复3、4两步,只到右移8次。这样第一个数据处理就完成了,结果仍存在CRC变量存储器中
(6)重复2~5步,处理下一个数据,只到参与校验的数据均处理完毕。
最后获得的16位校验值,要在传输时,低在前,高在后。
1.5 C语言
#include <stdio.h>
//需要生成crc校验的数据个数
#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++) //位移8次
{temp = crc16 & 0x0001;
crc16 = crc16>>1;
if(temp){
crc16 = 0xa001^crc16;
}
printf("CRC校验为:%x\n",crc16);
}
printf("---------------------------------\n");
}
printf("CRC校验为:%x\n",crc16);
}
1.6 S7-1200 MODBUS通讯指令介绍
MB_COMM_LOAD指令:用于设置Modbus(RTU)端口。
参数 | 说明 |
EN | 使能 |
REQ | 上升沿启动该指令 |
PORT | 扩展模块的硬件标识符 |
BAUD | 波特率 |
PARITY | 0:无校验;1:奇校验;2:偶校验 |
RESP_TO | 每个从站的读取延时时间 |
MB_DB | MB_MASTER / MB_SLAVE 指令的背景数据块 |
MB_MASTER指令
参数说明
EN使能
REQ上升沿发送有一个读/写请求
MB_ADDR从站地址
MODE读写控制位;0:读;1:写;
PARITY0:无校验;1:奇校验;2:偶校验
DATA_ADDR将要读/写的从机寄存器地址
DATA_LEN访问寄存器的连续数量
DNE完成标志位,可以用来激活下一个指令
BUSY繁忙标志位
ERROR错误标志位
STAUS错误代码
1.7 C#
待更。。。。。