Modbus通信协议介绍

关于Modbus协议

Modbus协议是MODICON(莫迪康)(现施耐德品牌)在1979年开发的,是全球第一个真正用于现场的总线协议;

Modbus协议是应用于电子控制器上的一种通用语言。通过此协议,可以实现控制器相互之间、控制器经由网络和其实设备之间的通信。

Modbus特点

  • 标准开放、公开发表、无版税要求、无许可证费(没有费用)

  • 支持多种电气接口(RS232、RS422、RS485、RJ45);各种介质传输(双绞线、网线)

  • 格式简单、紧凑、通俗易懂,容易上手(好用)

Modbus总线通信环境

  • 基本通信结构

  • 从机编码

Modbus通信方式与分类

1. Modbus RTU (Remote Terminal Unit)
  • 描述:Modbus RTU是一种在串行链路上使用二进制编码的消息传输模式。它通常用于点对点或一点对多点(星型拓扑)网络。

  • 特点

    • 使用RS-232、RS-485等物理接口。

    • 消息帧包含起始位、地址、功能码、数据域、校验和/循环冗余校验(CRC)以及停止位。

    • 支持较长距离和较高的抗干扰能力。

    • 适用于需要稳定性和可靠性的工业环境。

2. Modbus ASCII
  • 描述:Modbus ASCII采用ASCII字符编码来表示消息帧中的每个字节,适合于不稳定的通信链路。

  • 特点

    • 消息以冒号(:)开头,以回车换行符(CR/LF)结尾。

    • 数据以十六进制形式发送,并且每两个字符代表一个字节。

    • 校验方法为纵向冗余检查(LRC)。

    • 速度较慢但易于调试和观察通信内容。

3. Modbus TCP/IP (Transmission Control Protocol/Internet Protocol)
  • 描述:Modbus TCP/IP是基于以太网技术的标准Modbus协议扩展,它将Modbus请求封装到TCP/IP包中。

  • 特点

    • 不需要定义物理地址,因为IP地址已经确定了目标设备。

    • 在TCP/IP五层模型的应用层之上运行。

    • 可以通过局域网、广域网甚至互联网实现远程监控和控制。

    • 提供了更好的灵活性和可扩展性,适应现代工业自动化的需求。

Modbus协议下的数据存储

  • 数据存储中的位bit (bool)、字节byte(8个位)、字Word(2个字节,16位)、双字DWord(2个字,4个字节,32位),C#中的数据显示:数据类型、显示格式

存储区对象类型访问类型(针对程序)存储区标识说明
线圈状态 Q单个bit读写0XXXX通过应用程序改变这种类型数据
输入线圈 I单个bit只读1XXXXI/O系统提供这种类型数据
输入寄存器 16-位 字只读3XXXXI/O系统提供这种类型数据
保持寄存器16-位 字 2个字节读写4XXXX通过应用程序改变这种类型数据

操作存储器的命令

常用功能码:01、02、03、04、05、06、15、16

功能码 16进制名称功能
01读线圈状态读位(读N个bit)---读从机线圈寄存器,位操作
02读输入离散量读位(读N个bit)---读离散输入寄存器,位操作
03读多个保持型寄存器读整型、字符型、状态字、浮点型(读N个words)---读保持寄存器,字节操作
04读多个输入寄存器读整型、状态字、浮点型(读N个words)---读输入寄存器,字节操作
05写单个线圈写位(写一个bit)---写线圈寄存器,位操作
06写单个保持寄存器写整型、字符型、状态字、浮点型(写一个word)---写保持寄存器,字节操作
07读取异常状态取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态
08回送诊断校验把诊断校验报文送从机,以对通信处理进行评鉴
09编程(只用于484)使主机模拟编程器作用,修改PC从机逻辑
0A控询(只用于484)可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送
0B读取事件计数可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时
0C读取通讯事件记录可是主机检索每台从机的ModBus事务处理通信事件记录。如果某项事务处理完成,记录会给出有关错误
0D编程(184/384/484/584)可使主机模拟编程器功能修改PC从机逻辑
0E探询(184/384/484/584)可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送
0F写多个线圈可以写多个线圈---强置一串连续逻辑线圈的通断
10写多个保持寄存器写多个保持寄存器---把具体的二进制值装入一串连续的保持寄存器
11报告从机标识可使主机判断编址从机的类型及该从机运行指示灯的状态
12(884和MICRO84)可使主机模拟编程功能,修改PC状态逻辑
13重置通信链路发生非可修改错误后,是从机复位于已知状态,可重置顺序字节
14读取通用参数(584L)显示扩展存储文件中的数据信息
15写入通用参数(584L)把通用参数写入扩展存储文件
16~40保留做扩展功能备用<font style="color:#595959;"></font>
41~48保留以备用户功能所用留作用户功能的扩展编码
49~77非法功能<font style="color:#595959;"></font>
78~7F保留留作内部作用
80~FF保留用于异常应答

Modbus RTU 协议报文格式

读寄存器消息帧格式
功能码: 0x03、0x04
请求:
从站地址功能码起始地址读取长度(2byte->16bit)CRC
010300(Hi)00(Lo)00(Hi)0A(Lo)C5
响应:
从站地址功能码字节数寄存器值(1)寄存器值(2)寄存器值(...)寄存器值(20)CRC
01031400(Hi)00(Lo)00(Hi)00(Lo)…………00(Hi)00(Lo)
写单寄存器消息帧格式
功能码:0x06
请求、响应:
从站地址功能码写入地址写入值(2)CRC
010600(Hi)00(Lo)00(Hi)00(Lo)XX
写多寄存器消息帧格式
功能码:0x10
请求:
从站地址功能码写入地址写入数量字节数写入值CRC
011000(Hi)00(Lo)00(Hi)0A(Lo)040AAB
响应:
从站地址功能码写入地址写入数量CRC
010F00(Hi)00(Lo)00(Hi)0A(Lo)XX
读线圈消息帧格式
功能码:0x01、0x02
请求:
从站地址功能码起始地址读取长度CRC
010100(Hi)00(Lo)00(Hi)0A(Lo)XX
响应:
从站地址功能码字节数输出状态 7-0输出状态 15-8CRC
0101020000XXXX
写单线圈消息帧格式
功能码:0x05
请求、响应:
从站地址功能码写入地址写入值CRC
010500(Hi)00(Lo)FF(Hi)/00(Hi)0A(Lo)XX
写单线圈消息帧格式
功能码:0x0F
请求:
从站地址功能码写入地址写入数量字节数写入值CRC
010F00(Hi)00(Lo)00(Hi)0A(Lo)020A(Lo)AB(Lo)
响应:
从站地址功能码写入地址写入数量CRC
010F00(Hi)00(Lo)00(Hi)0A(Lo)XX
CRC校验码计算:
void CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
    if (value == null || !value.Any())
        throw new ArgumentException("");

    //运算
    ushort crc = crcInit;
    for (int i = 0; i < value.Count; i++)
    {
        crc = (ushort)(crc ^ (value[i]));
        for (int j = 0; j < 8; j++)
        {
            crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
        }
    }
    byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
    byte lo = (byte)(crc & 0x00FF);         //低位置

    List<byte> buffer = new List<byte>();
    value.Add(lo);
    value.Add(hi);
}
 

Modbus Ascii 协议处理

格式变化
  • 将RTU基础报文(除CRC校验部分,PDU)可用字符转对应ASCII编码

  • 利用转换后的ASCII编码数组进行LRC校验码计算

  • 添加起始(: 3A)结束字符(换行回车 0D 0A)

传输示例

要读取地址 0x20c1的两个寄存器需要发送以下 ASCII 消息:

        010420C1000218<CRLF>

请求:

  • : -消息开始-0x3A

  • 01-从站地址-0x01

  • 04-功能码 (读取输入寄存器)-0x04

  • 20C1-要读取的寄存器地址-0x20C1

  • 0002 -要读取的寄存器长度(必须是 2)-0x0002

  • 18-LRC 校验码

  • <CRLF>-消息结束,回车换行-0x0D0A

LRC校验码:
public void LRC(List<byte> value)
{
    if (value == null) return;

    int sum = 0;
    for (int i = 0; i < value.Count; i++)
    {
        sum += value[i];
    }

    sum = sum % 256;
    sum = 256 - sum;

    value.Add((byte)sum);// 16进制一个字节
}

Modbus TCP 协议处理

MBAP:Modbus Application Protocol (modbus报文头) - **固定7个字节**
  • 事务标识符(Transaction Identifier) - 2 字节

这是一个唯一标识符,用于匹配请求和响应。在请求和响应中,这个字段的值是相同的。

  • 协议标识符(Protocol Identifier) - 2 字节

对于 Modbus TCP,这个字段的值始终是 0x0000。

  • 长度字段(Length Field) - 2 字节

表示接下来的单元标识符、功能码和数据字段的字节数。不包括事务标识符、协议标识符和长度字段本身。

  • 单元标识符(Unit Identifier) - 1 字节

也称为设备地址或从站地址。在 Modbus TCP 中,这个字段用于标识网络上的 Modbus 从设备。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值