详解Modbus通信协议---清晰易懂

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    本文旨在让您对Modbus有一个很直观的了解总结关于Modbus相关的知识非常适合初学的同学同时如有错误欢迎修改意见和建议将在第一时间修改

    什么是协议

    在了解什么是Modbus之前我们先来看下什么是协议

    协议是一个汉语词汇读音为xié yì意思是共同计议协商经过谈判、协商而制定的共同承认、共同遵守的文件。

    简单地说在我们的单片机之间互相通信以及单片机和上位机通信中规定了不同的内容规范这个规范是通信的双方都需要遵守的这样就可以实现两者的通信

    而这个协议规范可以有很多种来适应不同的设备以及通信要求等我们常见的就有IIC SPI UART串口通信协议等等。而Modbus也是一个串行通信协议。

    在这里插入图片描述

    什么是RS-485 RS-232

    我们在看Modbus的时候经常会看到485串口232串口这些是什么呢

    RS232RS485是一种电平标准

    数据在通信双方之间传输本质是传输物理的电平 比方说传输5V的电压 -1V的电压信号这些物理信号在传输过程中会受到很多干扰比方说你传输一个5V的电压到了接收端可能就变成了4.8V并且通信的双方高低电平的参考电压可能不同。

    那么这个时候就需要一个电平标准来判断多少V的电压是高电平 1多少V的电压是低电平 0 这就诞生了 RS-485 RS-232

    RS232是电子工业协会(Electronic Industries AssociationEIA) 制定的异步传输标准接口同时对应着电平标准和通信协议时序其电平标准+3V~+15V对应0-3V~-15V对应1。

    • 全双工
    • 逻辑1-15V–5V
    • 逻辑0+3V–+15V
      在这里插入图片描述

    RS485RS485是一种串口接口标准为了长距离传输采用差分方式传输传输的是差分信号抗干扰能力比RS232强很多。两线压差为-2~-6V表示0两线压差为+2~+6V表示1

    • 半双工
    • 逻辑1+2V~+6V
    • 逻辑0 -2V~ -6V
    • 注意485的电平指的是485-A和485-B两根传输线两线间的电压差。而不是传输线上的电压

    在这里插入图片描述

    如果还想继续了解可以看博主的这个博文

    USB转串口 TTL RS-232 RS-485 COM口 UART区别

    也就是RS-485电平标准确定传输过来的数据是0还是1在此基础上这些字节数据根据modbus通信协议来进行数据的交互传输。

    硬件层协议解决0和1的可靠传输常有RS232、RS485、CAN、IIC、SPI …
    软件层协议解决传输目的,常有Modbus、TCP/IP、CANopen …

    在这里插入图片描述

    Modbus协议说明

    Modbus诞生于1979年 莫迪康公司 后来被施耐德电气公司收购。Modbus提供通用语言用于彼此通信的设备和设备。
    Modbus已经成为工业领域通信协议的业界标准并且现在是工业电子设备之间常用的连接方式。Modbus作为目前工业领域应用最广泛的协议

    最简单的说Modbus就是一个总线通信协议像IIC SPI这种但是他不依赖于硬件总线

    Modbus之所以使用广泛是有他的优点的

    • Modbus协议标准开放、公开发表且无版权要求
    • Modbus协议支持多种电气接口包括RS232、RS485、TCP/IP等还可以在各种介质上传输如双绞线、光纤、红外、无线等
    • Modbus协议消息帧格式简单、紧凑、通俗易懂。用户理解和使用简单厂商容易开发和集成方便形成工业控制网络

    举一个简单的例子我们常用的IIC通信协议需要在物理上连接iic总线然后加上拉电阻规定好物理层的高低电平。
    在这里插入图片描述
    而 Modbus协议是一种应用层报文传输协议协议本身并没有定义物理层定义了控制器能够认识和使用的消息结构不管它们是经过何种网络进行通信的。 所以能够适应多种电气接口因此使用非常广泛。

    Modebus通信过程

    注意Modbus是一主多从的通信协议

    Modbus通信中只有一个设备可以发送请求。其他从设备接收主机发送的数据来进行响应从机是任何外围设备如I/O传感器阀门网络驱动器或其他测量类型的设备。从站处理信息和使用Modbus将其数据发送给主站。

    也就是说,不能Modbus同步进行通信,主机在同一时间内只能向一个从机发送请求总线上每次只有一个数据进行传输,即主机发送,从机应答,主机不发送,总线上就没有数据通信。

    从机不会自己发送消息给主站只能回复从主机发送的消息请求。

    在这里插入图片描述
    并且Modbus并没有忙机制判断比方说主机给从机发送命令 从机没有收到或者正在处理其他东西这时候就不能响应主机因为modbus的总线只是传输数据没有其他仲裁机制所以需要通过软件的方式来判断是否正常接收。

    举例

    现在我们来探讨Modbus数据传输的方式可以简单地理解成打电话。并且是单向通信的打电话

    主机发送数据首先需要从机的电话号码(区分每个从机每个地址必须唯一)告诉从机打电话要干什么事情然后是需要发送的内容最后再问问从机我说的话你都听清楚了没有呀没有听错吧

    然后从机这里得到了主机打过来的电话从机回复主机需要的内容主机得到从机数据这样就是一个主机到从机的通信过程

    就好比老师和你打电话老师拨通了你的电话号然后老师跟你说小王呀我这里需要你给我发东西发的内容是上周的一周总结你说好的然后打开你电脑的文件夹把你的周报发给老师这就是一个通信过程。

    Modbus存储区

    既然从机存储数据那么肯定要有一个存储区那就需要文件操作我们都知道这文件可以分为只读(-r)和读写(-wr)两种类型

    并且存储的数据类型可以分为 布尔量 和 16位寄存器

    • 布尔量比如IO口的电平高低灯的开关状态等。
    • 16位寄存器比如 传感器的温度数据存储的密码等。

    Modbus协议规定了4个存储区 分别是0 1 3 4区 其中1区和4区是可读可写1区和3区是只读。

    区号名称读写地址范围
    0区输出线圈可读可写布尔量00001-09999
    1区输入线圈只读布尔量10001-19999
    3区输入寄存器只读寄存器30001-39999
    4区保持寄存器可读可写寄存器40001-49999

    并且Modbus还给每个区都划分了地址范围 主机向从机获取数据时只需要告诉从机数据的起始地址还有获取多少字节的数据从机就可以发送数据给主机

    Modbus数据模型规定了具体的地址范围每一个从机都有实际的物理存储跟modbus的存储区相对应主机读写从机的存储区实际上就是对从机设备对应的实际存储空间进行读写。
    在这里插入图片描述

    Modbus协议类型

    在上面我们已经说明了Modbus可以在各种介质上传输那么他的传输模式也分为三种。包括ASCII、RTU(远程终端控制系统)、TCP三种报文类型

    串行端口存在多个版本的Modbus协议而最常见的是下面四种

    • Modbus-Rtu
    • Modbus-Ascii
    • Modbus-Tcp
    • ModbusPlus

    Modbus RTU是一种紧凑的十六进制表示数据的方式Modbus ASCII是一种采用Ascii码表示数据并且每个8Bit 字节都作为两个ASCII字符发送的表示方式。
    RTU格式后续的命令/数据带有循环冗余校验的校验和而ASCII格式采用纵向冗余校验的校验和。

    Modbus协议使用串口传输时可以选择RTU或ASCII模式并规定了消息、数据结构、命令和应答方式并需要对数据进行校验。ASCII 模式采用LRC校验RTU模式采用16 位CRC校验。通过以太网传输时使用TCP这种模式不使用校验因为TCP协议是一个面向连接的可靠协议。

    在这里插入图片描述

    当然常用的就是RTU模式ASCII一般很少

    举一个简单的例子如果我们需要发送一个数字10 那么RTU模式下只需要发送 0x0A 总线上传输数据形式为 0000 1010

    而ASCII码模式则将数据1和0转为’1’和’0’,需要发送0x31(1) 0x30(0)两个字节数据。总线上传输数据形式为 0011 0001 0011 0000

    详细的我们等下再阐述

    Modbus-RTU协议

    Modbus报文帧结构

    一个报文就是一帧数据一个数据帧就一个报文 指的是一串完整的指令数据本质就是一串数据。

    Modbus报文是指主机发送给从机的一帧数据其中包含着从机的地址主机想执行的操作校验码等内容

    Modbus协议在串行链路上的报文格式如下所示

    在这里插入图片描述

    从站地址功能码数据CRC/LRC
    1 byte1 byteN bytes2 bytes
    • 帧结构 = 从机地址 + 功能吗 + 数据 + 校验
    • 从机地址: 每个从机都有唯一地址占用一个字节,范围0-255,其中有效范围是1-247,其中255是广播地址(广播就是对所有从机发送应答)

    • 功能码: 占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改从机的数据,所以不同功能码对应不同功能.

    • 数据: 根据功能码不同,有不同功能比方说功能码是查询从机的数据这里就是查询数据的地址和查询字节数等。

    • 校验: 在数据传输过程中可能数据会发生错误CRC检验检测接收的数据是否正确

    Modbus功能码

    Modbus规定了多个功能那么为了方便的使用这些功能我们给每个功能都设定一个功能码也就是指代码。

    Modbus协议同时规定了二十几种功能码但是常用的只有8种用于对存储区的读写如下表所示

    功能码功能说明
    01H读取输出线圈
    02H读取输入线圈
    03H读取保持寄存器
    04H读取输入寄存器
    05H写入单线圈
    06H写入单寄存器
    0FH写入多线圈
    10H写入多寄存器

    当然我们用的最多的就是03和06 一个是读取数据一个是修改数据。

    CRC校验

    错误校验CRC域占用两个字节包含了一个16位的二进制值。CRC值由传输设备计算出来然后附加到数据帧上接收设备在接收数据时重新计算CRC值然后与接收到的CRC域中的值进行比较如果这两个值不相等就发生了错误。
    比如主机发出01 06 00 01 00 17 98 04 98 04 两个字节是校验位那么从机接收到后要根据01 06 00 01 00 17 再计算CRC校验值从机判断自己计算出来的CRC校验是否与接收的CRC校验98 04主机计算的相等如果不相等那么说明数据传输有错误这些数据就不能要。

    CRC校验流程

    1、预置一个16位寄存器为0FFFFH全1称之为CRC寄存器。

    2 、把数据帧中的第一个字节的8位与CRC寄存器中的低字节进行异或运算结果存回CRC寄存器。

    3、将CRC寄存器向右移一位最高位填以0最低位移出并检测。

    4 、如果最低位为0重复第三步下一次移位如果最低位为1将CRC寄存器与一个预设的固定值0A001H进行异或运算。

    5、重复第三步和第四步直到8次移位。这样处理完了一个完整的八位。

    6 、重复第2步到第5步来处理下一个八位直到所有的字节处理结束。

    7、最终CRC寄存器的值就是CRC的值。

    此外还有一种利用预设的表格计算CRC的方法它的主要特点是计算速度快但是表格需要较大的存储空间该方法此处不在阐述

    在这里插入图片描述

    下面我们来看详细的发送和接收数据

    1、主机对从机读数据操作

    主机发送报文格式如下

    从站地址功能码起始高起始低数量高数量低校验
    0x010x030x000x010x000x010xD5 0xCA

    含义

    0x01从机的地址
    0x03查询功能读取从机寄存器的数据
    0x00 0x01 代表读取的起始寄存器地址.说明从0x0001开始读取.
    0x00 0x01 查询的寄存器数量为0x0001个 Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据; 寄存器地址对应着从机实际的存储地址
    0xD5 0xCA 循环冗余校验 CRC

    从机回复报文格式如下
    | 从站地址 | 功能码 | 字节计数 | 字节1 |字节2 | 校验 |
    |–|–|-|-|-|-|-|
    | 0x01 | 0x03| 0x02| 0x01 | 0x00| 0x17| 0xF8 0x4A |

    含义

    0x01从机的地址
    0x03查询功能读取从机寄存器的数据
    0x02 返回字节数为2个 一个寄存器2个字节
    0x00 0x17寄存器的值是0017
    0xF8 0x4A 循环冗余校验 CRC

    2、主机对从机写数据操作

    主机发送报文格式如下

    从站地址功能码数据地址高数据地址低数据高数据低校验
    0x010x060x000x010x000x170x98 0x04

    含义

    0x01从机的地址
    0x06修改功能修改从机寄存器的数据
    0x00 0x01 代表修改的起始寄存器地址.说明修改0x0000-0x0001的存储内容
    0x00 0x17 要修改的数据值为0017
    0x98 0x04 循环冗余校验 CRC

    从机回复报文格式如下

    从站地址功能码数据地址高数据地址低数据高数据低校验
    0x010x060x000x010x000x170x98 0x04

    含义

    0x01从机的地址
    0x06修改功能修改从机寄存器的数据
    0x00 0x01 代表修改的起始寄存器地址.说明是0x0000
    0x00 0x17修改的值为0017
    0x98 0x04 循环冗余校验 CRC

    从机的回复和主机的发送是一样的如果不一样说明出现了错误

    Modbus-ACSII协议

    在消息中的每个字节都作为两个ASCII字符发送

    十六进制的0-F 分别对应ASCII字符的0…9A…F

    也就是0x30~0x3A 0x41~0x46
    在这里插入图片描述

    下方是ascii的报文帧

    • 1个字节起始位

    • 2个字节地址位

    • 2个字节功能位

    • n个数据位最小的有效位先发送

    • LRC(纵向冗长检测) 注意校验方式不同

    • 结束符 \r \n
      在这里插入图片描述

    可以看到数据部分更加繁琐正常我们使用都是用RTU格式ASCII码格式有了解即可。

    在这里插入图片描述
    总结
    ModbusASCII有开始字符(和结束字符(CR LF)可以作为一帧数据开始和结束的标志而ModbusRTU没有这样的标志需要用时间间隔来判断一帧报文的开始和结束协议规定的时间为3.5个字符周期就是说一帧报文开始前必须有大于3.5个字符周期的空闲时间一帧报文结束后也必须要有3.5个字符周期的空闲时间否则就会出现粘包的情况。

    注意针对3.5个字符周期其实是一个具体时间但是这个时间跟波特率相关。
    在串口通信中1个字符包括1位起始位、8位数据位一般情况、1位校验位或者没有、1位停止位一般情况下因此1个字符包括11个位那么3.5个字符就是38.5个位波特率表示的含义是每秒传输的二进制位的个位因此如果是9600波特率3.5个字符周期=/960038.5=0.00401s1000=4.01ms

    Modbus-TCP协议

    我们首先看下Modbus-TCP和Modbus-ACSII的区别

    Modbus-TCP并不需要从从机地址而是需要MBAP报文头

    并且不需要差错校验因为TCP本身就具有校验差错的能力
    在这里插入图片描述

    MBAP报文头格式如下
    在这里插入图片描述

    其中事务处理表示符合协议标识符我们正常使用设置为0即可 长度为6个字节 0x0006

    简单来说也就是Modbus-TCP是在Modbus-ACSII的基础上去掉校验然后加上五个字节的0和一个06

    最后附上 Modbus标准协议手册链接
    Modbus标准协议手册

    请添加图片描述
    请添加图片描述

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6