微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Modbus协议完全资料与程序解析

Modbus协议完全资料与程序解析

时间:12-01 来源:互联网 点击:
1简述,modbus是一种工业用的多设备之间的主从通信协议。只要两台设备之间,是采用modbus协议的主从关系,并连接到相同网络,即可互相通信。因为Modbus只是协议,而且只规定了数据帧,底层连接,可以是232,485或者以太网。设备一般采用232和485进行通信,因为成本低。当然要是考虑远距离传输和多卖钱的话,也会采用以太网,不过应该就会相应复杂一些了。

2模式,modbus有两种模式,一种叫RTU模式,另一种叫acsii模式,RTU模式是纯二进制的,而acsii模式,一个信息中的每8位字节作为2个ascii字符传输的,这种模式的主要优点时允许字符之间的时间间隔长达1秒,也不会出现错误。而较acsii模式,RTU模式的优点是用最少的字节,表达更多的内容。但同时也要求设备必须连续传输。

3通讯,modbus属于主从通讯,可以是一主一从或者一主多从。通讯的方式为主机向从机发送命令(或者叫请求)从机向主机发送响应。主机不发送,从机不返回,一发,一收,不发不收。而且一个时间,只有一个机器发送请求或者响应,否则的话,则会出错。

4信息帧,由于项目上没有涉及到acsii模式,所以本文只讨论RTU模式,不讨论acsii模式,以后如果要是用的上,肯定会继续讨论。用不上,就不讨论了。RTU帧,开始时,必须要有3.5个静止的时间,也就是时间间隔,用来区分上一帧和下一帧,如果没有时间间隔的话,则会分辨不出哪里是帧开始,哪里是帧结束了。3.5个时间间隔依据波特率不同而不同。同样,结束时也需要时间。除了时间以外,还有地址,功能码,数据,crc校验四个部分,每个部分的字节数不同,地址功能码各1个字节,crc是2个字节其完整表达如下:

开始

地址

功能

数据

校验

结束

3.5t

1字节 8b

1字节 8b

n字节 n*8b

2字节16b

3.5t

4.1、地址:主要用于区分从机,在下位机程序中,的宏定义中设置不同的从机地址。

#define Modbus_addr 0x01

设备响应时,第一位也是本机地址。地址的范围是从0-247,地址0为广播地址,所有机器均可以识别。

4.2、功能码:表示主机要命令这个设备的什么功能,执行什么程序。我看了一下正规的modbus的功能码多达24个,不同厂家生产的不同型号的设备,可能会支持不同的功能码,所以买之前需要注意一下。具体功能如下:

01 读线圈状态 02 读输入状态 03 读保持寄存器 04 读输入寄存器 05 强制单个线圈

06 预置单个寄存器 07 读不正常状态 08 诊断 09 程序484 10 查询484

11 通讯事件控制 12 通讯事件记录 13 程序控制器 14 查询控制器 15 强制多个寄存器

16 预置多个寄存器 17 报告从机id 18 程序884/M84 19 通讯链路复位 20 读通用参考值

21 写通用参考值 22 Mask Write 4X Register 23 Read/Write 4X Registers 24 Read FIFO 队列

虽然看着功能很多,但实际上有用的,只有01 02 03 04 05 06 15 和16功能码。

4.3、数据区,根据功能码的不同数据的长度是不同的。

4.4、crc校验 包含两个字节,发送端发送时,一帧的所有数据统一计算出一个crc校验码,然后加在一帧的最后两位中,然后等到发送到接收端时接收端重新计算一次除最后两位的一帧所有数据,然后根据两个数据的对比,来判断接收到的数据是否正确。

5、程序,以下位机为程序对象,主要使用c语言编写,首先,先从变量入手,既然modbus接受以帧为单位,所以就要设置两个缓冲区,用来接收数据,我们这里使用数组来存储接收来的数据Modbus_send_buf[Modbus_max_send_buf];//数据发送缓冲 和 Modbus_recevie_buf[Modbus_max_recevie_buf];//数据接收缓冲 ,其中Modbus_max_send_buf,和Modbus_max_recevie_buf ,为宏定义,这样可以方便的修改一帧最大的存储数据。有了发送接收缓冲,就可以写中断函数了,进入中断后,首先做一些必要的工作,清ES ,判断IR,清IR,做完后,就可以开始接收数据了,但有个问题?如果设备处于空闲状态,那么接收数据后按命令执行,但如果当设备正在执行指令的时候,则不应该再继续的接收指令,那样的话,会让程序进入混乱状态。所以要在基础工作做完后,增加一个判断,来确定设备的忙闲。if((Modbus_cmd_flag == 0) && (Modbus_exe_flag == 0)),判断完以后就可以继续下面的工作了。如果通讯中包含奇偶校验的话,那么则判断奇偶校验。下面就是接收数据。Modbus_recevie_buf[Modbus_recevie_count] = SBUF; ,将接收来的数据存入数组并记录存入的数据个数Modbus_recevie_count,由

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top