博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ModBus协议简介及移植到STM32单片机
阅读量:4080 次
发布时间:2019-05-25

本文共 2294 字,大约阅读时间需要 7 分钟。

一、基本概念 

Modbus协议是全球最早用于工业现场的总线规约,许多工业设备,包括PLC,DCS,智能仪表等都在使用此协议作为他们之间的通信标准。

Modbus 协议是一个请求/应答协议,发起请求的为Master(client),响应请求的为slave(server)。

此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一个控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。

 

二、消息格式

这里大致说明Modbus协议的消息中包含有哪些域(ADU:应用数据单元,PDU:协议数据单元),并且说明各个域的作用。但是需要注意,modbus tcp无地址码和校验码,modbus ascii和modbus rtu也有差别,具体请看下节详述。

 

地址码:每个从机都必须有唯一的地址码(从1到247,0是广播地址),并且只有符合地址码的从机才能响应回送。当从机回送信息时,相应的地址码表明该信息来自于何处。

功能码:主机发送的功能码告诉从机执行什么任务。ModBus通讯规约定义功能号为1到127。表2-1列出部分常用功能码,以备查询。

数据区:数据区包含需要从机执行什么动作或由从机采集的返送信息。应答包中,数据包括了数据字节长度+数据值,请求包中数据只包含数据值。

校验码:主机或从机可用校验码进行判别接收信息是否出错。

表2-1

代码

中文名称

为操作/字节操作

操作数量

01

读线圈状态

位操作

单个或多个

02

读离散状态

位操作

单个或多个

03

读保持寄存器

字节操作

单个或多个

04

读输入寄存器

字节操作

单个或多个

05

写单个线圈

位操作

单个

06

写单个保持寄存器

字节操作

单个

15

写多个线圈

位操作

多个

16

写多个保持寄存器

字节操作

多个

 

三、通讯方式

3.1 异步串行传输

各种介质如有线RS-232/422/485/;光纤、无线等,对应的通信模式是MODBUS RTU或MODBUS ASCII。

3.1.1 ASCII帧

起始位

设备地址

功能代码

数据

LRC校验

结束符

2个字符

2个字符

n个字符

2个字符

2个字符

  

使用ASCII模式,消息以冒号(:)字符(ASCII码 3AH)开始,以回车换行符结束(ASCII码 0DH,0AH)。

其它域可以使用的传输字符是十六进制的0...9,A...F。网络上的设备不断侦测“:”字符,当有一个冒号接收到时,每个设备都解码下个域(地址域)来判断是否发给自己的。消息中字符间发送的时间间隔最长不能超过1秒,否则接收的设备将认为传输错误。

3.1.2 RTU帧

起始位

设备地址

功能代码

数据

CRC校验

结束符

T1-T2-T3-T4

8bit

8bit

n个8bit

16bit

T1-T2-T3-T4

使用RTU模式,消息发送至少要以3.5个字符时间的停顿间隔开始(如上图的T1-T2-T3-T4所示)。传输的第一个域是设备地址。可以使用的传输字符是十六进制的0...9,A...F。网络设备不断侦测网络总线,包括停顿间隔时间内。当第一个域(地址域)接收到,每个设备都进行解码以判断是否发往自己的。在最后一个传输字符之后,一个至少3.5个字符时间的停顿标定了消息的结束。一个新的消息可在此停顿后开始。

整个消息帧必须作为一连续的流转输。如果在帧完成之前有超过1.5个字符时间的停顿时间则为非法帧,如果一个新消息在小于3.5个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续,这将导致一个错误,因为在最后的CRC域的值不可能是正确的。即帧之间的间隔必须大于3.5T,帧内字符的间隔必须小于1.5T。实际应用中1.5T一般不处理,只处理3.5T(FreeModBus开源代码就是这样)。

3.2 以太网

在以太网上进行通讯,对应的通讯模式是MODBUS TCP,其帧结构如下图。

与MODBUS RTU相比,少了校验域和地址码,其中地址码被放到MBAP报文头里面了,没有校验域是因为TCP本身就有校验所以省略了。

3.3 高速令牌传递网络

对应的通信模式是Modbus PLUS。

 

四、调试工具

如果你做的是modbus master,可以使用modbus slave工具模拟从设备来调试,该工具下载地址:

如果你做的是modbus slave,可以使用modbus poll工具模拟主设备来调试,该工具下载地址:

以上两个工具的使用方法,可以参考此博客:

 

五、移植到STM32单片机

5.1 FreeModBus Master工程

5.1.1 开发环境

STM32L475 + STM32CubeMX + KEIL5

5.1.2 工程说明

使用STM32L475单片机的uart1作为调试串口,uart2外接RS485芯片作为modbus通讯串口,PC3引脚用来控制RS485芯片的方向。下载本工程后,只需根据你的硬件,改变上述接口,即可正常工作!

本工程实现了MODBUS MASTER RTU的功能,MODBUS SLAVE RTU、MODBUS ASCII和MODBUS TCP均未测试!

5.1.3 下载地址

本人使用modbus slave工具进行测试,读取线圈、离散、输入、保持四种寄存器都正常,如下图所示

 

5.2 FreeModBus Slave工程

5.2.1 开发环境

STM32L071 + STM32Cube + KEIL5

5.2.2 下载地址

 

 

转载地址:http://ztsni.baihongyu.com/

你可能感兴趣的文章
无名的飞控默认是用的PID,没用ADRC,可以改变宏定义切换。而且只在角速度环用ADRC。
查看>>
我发现《四轴飞行器DIY-基于STM32微控制器》,还有crazypony,还有无名,匿名这类没有用操作系统的都是靠定时器中断来弄的。
查看>>
弄清楚这里所说的解耦是什么意思。
查看>>
我准备把ACfly和T265接上
查看>>
T265源码下载及案例实验(这个人运行成功了realsense里的pose例程,获得位置数据!)
查看>>
网上搜到的树莓派使用串口(uart或者USB)都是Python来用的,我感觉我得换成x86系统来弄或许好些。
查看>>
Mavlink协议是在串口通讯基础上的一种更高层的开源通讯协议,似乎校验更多比串口更可靠?
查看>>
移植mavlink到stm32详细教程,后面附快速移植方法
查看>>
感觉mavlink对于目前的我而言还是麻烦了点,干脆用串口吧(现在回看这可能是错误的想法)
查看>>
树莓派利用串口进行通信(这个是用c写的树莓派的串口)
查看>>
树莓派3 B+ 的串口(USART)使用问题 (也是用C写的)
查看>>
ROS下树莓派USB串口通信(具体为接收到某个ROS的topic数据后,向串口下发数据。)
查看>>
ROS系统的串口数据读取和解析
查看>>
ROS串口编程学习笔记
查看>>
ROS环境下串口通信
查看>>
ros中使用serial包实现串口通信
查看>>
做机械臂导航时遇到的问题5:如何使用ROS内嵌serial功能包实现串口通信
查看>>
ROS为上位机与STM32为下位机串口通讯(一)
查看>>
github上搜了下有ROS uart方面的
查看>>
STM32和ROS的串口通信(这篇是公众号文章写得比较正规详细)
查看>>