MODBUS 总结
- 格式:doc
- 大小:2.05 MB
- 文档页数:14
MODBUS协议整理协议名称:MODBUS协议整理一、引言MODBUS协议是一种用于工业控制系统的通信协议,广泛应用于自动化领域。
本协议旨在整理MODBUS协议的基本原理、通信方式、数据帧格式以及相关功能码的使用方法,以便于开发人员在设计和实施MODBUS通信时能够准确理解和应用该协议。
二、协议原理1. MODBUS协议采用主从结构,主设备负责发起通信请求,从设备负责响应请求。
2. 通信基于串行通信或以太网通信,通过物理层的传输介质进行数据传输。
3. MODBUS协议使用简单、高效的数据帧格式,在通信过程中通过功能码来定义通信类型和数据操作。
三、通信方式1. 串行通信方式a. MODBUS RTU:采用二进制编码,数据帧包括起始位、设备地址、功能码、数据、CRC校验等字段。
b. MODBUS ASCII:采用ASCII编码,数据帧包括起始符、设备地址、功能码、数据、LRC校验等字段。
2. 以太网通信方式a. MODBUS TCP/IP:基于TCP/IP协议,数据帧采用以太网帧格式,包括设备地址、功能码、数据等字段。
四、数据帧格式1. MODBUS RTU数据帧格式起始位 | 设备地址 | 功能码 | 数据 | CRC校验-------|---------|-------|------|--------1字节 | 1字节 | 1字节 | n字节 | 2字节2. MODBUS ASCII数据帧格式起始符 | 设备地址 | 功能码 | 数据 | LRC校验 | 结束符-------|---------|-------|------|--------|-------1字节 | 2字节 | 2字节 | n字节 | 1字节 | 2字节3. MODBUS TCP/IP数据帧格式以太网帧格式五、功能码1. 读取操作a. 读取线圈状态:功能码01,用于读取从设备的线圈状态。
b. 读取输入状态:功能码02,用于读取从设备的输入状态。
modbus通讯协议与4851. 介绍本文将介绍modbus通讯协议与485总线的相关知识。
modbus通讯协议是一种常用于工业领域的通讯协议,而485总线是一种可靠的工业通讯标准。
我们将探讨它们的基本原理、工作方式以及一些常见应用。
2. modbus通讯协议modbus通讯协议是一种基于串行通信的协议,广泛应用于工业自动化领域。
它可以通过RS-485、RS-232等物理层接口进行通讯。
modbus通讯协议被设计用于在主机和从机之间传输数据,其中主机负责发起通讯请求,而从机负责响应请求并提供相应的数据。
2.1 modbus协议的工作方式modbus通讯协议采用了主从结构,主机作为通讯的发起者,从机作为通讯的接收者。
通讯的数据传输基于请求-响应模式,主机发送一个请求,从机收到请求后发送响应。
请求和响应的内容包括功能码、数据地址以及数据内容等。
2.2 modbus协议的功能码modbus协议定义了一系列功能码,用于标识通讯的目的和操作类型。
其中常用的功能码包括读取线圈状态、读取输入状态、读取保持寄存器以及写入单个寄存器等。
3. 485总线485总线是一种常用的工业通讯标准,它可以支持多个设备共享同一条通讯线路。
485总线采用差分信号传输方式,能够有效抵抗干扰从而提高通讯的可靠性和稳定性。
3.1 485总线的工作原理485总线采用全双工通讯方式,可以同时进行发送和接收数据。
它通过差分信号来传输数据,其中正线和负线分别承载两个相反的信号。
这种差分传输方式使得485总线能够有效地抵抗电磁干扰和噪声的影响。
3.2 485总线的优势485总线具有以下几个优势: - 长距离传输:485总线可以支持较长的通讯距离,最高可达1200米。
- 多设备共享:多个设备可以通过485总线连接在一起,共享同一条通讯线路。
- 抗干扰能力强:485总线采用差分传输方式,能够有效地抵抗电磁干扰和噪声。
4. modbus通讯协议与485总线的应用modbus通讯协议与485总线的结合被广泛应用于工业自动化领域。
MODBUS协议整理协议名称:MODBUS协议整理协议背景:MODBUS协议是一种用于工业自动化领域的通信协议,广泛应用于工业控制系统中。
为了更好地理解和应用MODBUS协议,现整理该协议的相关内容。
一、协议概述MODBUS协议是一种基于主从架构的串行通信协议,用于实现设备之间的数据交换。
该协议定义了数据传输的格式、通信方式和错误处理等规范,使得不同厂商的设备能够互联互通。
二、协议特点1. 简单易懂:MODBUS协议采用简单的二进制格式进行数据传输,易于理解和实现。
2. 灵活可扩展:该协议支持多种通信方式,如串口、以太网等,并且可以根据具体需求进行扩展。
3. 高效可靠:MODBUS协议具有较高的传输效率和可靠性,适用于实时性要求较高的工业控制系统。
三、协议结构MODBUS协议由多个功能码组成,每个功能码对应一种操作。
以下为常用的功能码及其对应的操作:1. 读取线圈状态(功能码01):用于读取远程设备的线圈状态,返回线圈的开关状态。
2. 读取输入状态(功能码02):用于读取远程设备的输入状态,返回输入的开关状态。
3. 读取保持寄存器(功能码03):用于读取远程设备的保持寄存器的值,返回寄存器的内容。
4. 读取输入寄存器(功能码04):用于读取远程设备的输入寄存器的值,返回寄存器的内容。
5. 写单个线圈(功能码05):用于控制远程设备的单个线圈,将线圈置为开启或关闭状态。
6. 写单个保持寄存器(功能码06):用于设置远程设备的单个保持寄存器的值。
7. 写多个线圈(功能码15):用于控制远程设备的多个线圈,将多个线圈置为开启或关闭状态。
8. 写多个保持寄存器(功能码16):用于设置远程设备的多个保持寄存器的值。
四、协议通信方式MODBUS协议支持多种通信方式,包括串口通信和以太网通信。
以下为常用的通信方式:1. 串口通信:MODBUS协议支持RS-232、RS-485等串口通信方式,适用于小规模的设备互联。
MODBUS协议整理协议名称:MODBUS协议整理一、引言MODBUS协议是一种通信协议,用于在工业自动化系统中进行数据传输和设备控制。
本协议整理旨在详细介绍MODBUS协议的基本原理、数据帧格式以及常见的功能码和寄存器类型。
通过本协议的整理,读者将能够全面了解MODBUS协议的结构和应用。
二、协议概述1. 协议定义MODBUS协议是一种基于主从架构的通信协议,用于在工业自动化系统中实现设备之间的数据交换和控制。
该协议支持串行通信和以太网通信,并提供了多种功能码和寄存器类型以满足不同应用场景的需求。
2. 协议特点MODBUS协议具有以下特点:- 简单易学:协议结构简单,易于理解和实现。
- 灵活可扩展:支持不同的物理介质和传输方式,并提供了多种功能码和寄存器类型以适应不同的应用需求。
- 高效可靠:采用CRC校验和错误检测机制,确保数据传输的可靠性和完整性。
三、协议结构1. 物理层MODBUS协议可以通过串口、以太网等物理介质进行通信。
串口通信一般使用RS-232、RS-485等标准,以太网通信则使用标准的TCP/IP协议栈。
2. 数据帧格式MODBUS协议的数据帧格式如下:- 起始符:用于标识数据帧的起始位置,一般为一个字节。
- 地址字段:用于标识设备的地址,一般为一个字节。
- 功能码:用于指示数据帧的操作类型,一般为一个字节。
- 数据字段:用于存储传输的数据,长度可变。
- CRC校验:用于校验数据帧的完整性,一般为两个字节。
四、功能码和寄存器类型1. 功能码MODBUS协议定义了多种功能码,用于指示数据帧的操作类型。
常见的功能码包括:- 读取线圈状态(0x01):用于读取设备的开关量输入状态。
- 读取输入状态(0x02):用于读取设备的开关量输出状态。
- 读取保持寄存器(0x03):用于读取设备的模拟量输入状态。
- 读取输入寄存器(0x04):用于读取设备的模拟量输出状态。
- 写单个线圈(0x05):用于控制设备的开关量输出状态。
modbus高位低位换算十进制1. 什么是modbus?Modbus是一种通信协议,用于在自动化系统中传输数据。
它是由Modicon公司于1979年开发的,用于连接可编程逻辑控制器(PLC)和其他外部设备。
Modbus已成为工业领域中最常用的通信协议之一,广泛应用于监控和控制系统。
2. modbus通信中的数据表示在modbus通信中,数据被表示为16位的二进制数。
这16位数据可以分为两个8位的字节,即高位字节和低位字节。
高位字节包含数值的高8位,低位字节包含数值的低8位。
3. 高位低位换算在modbus通信中,高位字节和低位字节的顺序是固定的。
高位字节在前,低位字节在后。
因此,在进行高位低位换算时,我们需要将高位字节和低位字节的位置互换。
3.1 高位低位换算的原理高位低位换算的原理是通过位运算实现的。
我们可以使用以下公式将高位字节和低位字节的位置互换:result = (high_byte << 8) | low_byte其中,<<是左移操作符,将高位字节向左移动8位,|是位或操作符,将低位字节与左移后的高位字节进行位或运算。
3.2 高位低位换算的示例假设我们有一个16位的数据,高位字节为0x12,低位字节为0x34。
我们可以使用上述公式进行高位低位换算:result = (0x12 << 8) | 0x34运算结果为:result = 0x1234因此,经过高位低位换算后,原始的16位数据0x1234被转换为十进制的4660。
4. modbus高位低位换算的应用modbus高位低位换算在实际应用中非常常见。
例如,在PLC与其他设备进行数据通信时,常常需要进行高位低位换算。
以下是一些常见的应用场景:4.1 传感器数据读取在某些自动化系统中,传感器的数据通常以modbus格式进行传输。
当从传感器读取数据时,我们需要对接收到的数据进行高位低位换算,以获得正确的数值。
modbus 协议详解(一)Modbus 协议详解什么是 Modbus 协议?•Modbus 协议是一种通信协议,用于在不同设备之间实现数据传输和通信。
•Modbus 协议最初由 Modicon 公司于 1979 年开发,用于在可编程逻辑控制器 (PLC) 和外部设备之间进行通信。
•Modbus 协议被广泛应用于工业自动化领域,包括监控系统、仪器仪表、传感器和执行器等设备之间的通信。
Modbus 协议的特点•简单:Modbus 协议采用了简单而有效的通信方式,易于实施和理解。
•开放:Modbus 协议是开放的标准,可以由不同厂商的设备实现和集成。
•灵活:Modbus 协议支持多种物理介质,包括串口、以太网和无线网络等。
•可靠:Modbus 协议具有重试机制和错误校验,确保数据的可靠传输。
Modbus 协议的工作原理Modbus 协议基于主从结构,在系统中通常包括一个主站和多个从站。
1.主站(Master):主站负责发起通信请求并控制从站的操作。
2.从站(Slave):从站被动地响应主站的请求,并提供所需的数据或执行相应的操作。
通信过程如下:1.主站向从站发送读取或写入请求。
2.从站接收到请求后,根据请求进行相应的数据读取或写入操作。
3.从站将读取的数据或写入的确认信息返回给主站。
4.主站接收到从站的响应后,根据需要进行后续的操作或请求。
Modbus 协议的数据格式Modbus 协议定义了数据的格式和通信规范。
帧格式Modbus 协议使用字节为单位进行传输,通常采用以下帧格式:•起始符:1 字节,表示帧的起始。
•地址:1 字节,指定主站或从站的地址。
•功能码:1 字节,指定所需的功能,如读取、写入等。
•数据:N 字节,包含读取或写入的数据。
•校验:2 字节,用于校验帧的完整性和准确性。
•结束符:1 字节,表示帧的结束。
功能码Modbus 协议定义了多个功能码,用于不同类型的操作和通信需求:•读取操作:–03H:读取保持寄存器的值。
MODBUS协议详细讲解MODBUS协议是一个常用的工业领域通信协议,用于在不同设备之间进行数据传输和通信。
它具有简单、易于实现和可靠的特点,被广泛应用于现代工业自动化系统中。
一、MODBUS协议的基本原理MODBUS协议使用主从结构进行通信,其中主机通常是一个上位机(如计算机),而从机则是各种设备(如传感器、控制器等)。
主机通过发送请求命令来获取或修改从机中的数据,而从机则通过相应命令来响应主机的请求。
这种简单的请求-响应机制使得MODBUS协议非常易于理解和实现。
二、MODBUS协议的消息格式1. MODBUS RTU格式:MODBUS RTU格式是MODBUS协议中最常用的一种格式。
它使用二进制编码,每个字节之间不使用分隔符。
一个MODBUS RTU消息包括以下几个部分:- 从机地址:指定要操作的从机设备- 功能码:表示执行的操作类型(读取数据、写入数据等)- 数据域:包含具体的数据信息- CRC校验:用于检测数据的完整性2. MODBUS ASCII格式:MODBUS ASCII格式使用ASCII码来表示消息,相比RTU格式更容易诊断和调试。
它与RTU格式相比,消息包含的信息量更大,但传输效率较低。
三、MODBUS协议的功能码在MODBUS协议中,功能码用于指示主机要执行的操作类型,常用的功能码包括:- 读取线圈状态(功能码01)- 读取离散输入状态(功能码02)- 读取保持寄存器(功能码03)- 读取输入寄存器(功能码04)- 写单个线圈(功能码05)- 写单个寄存器(功能码06)- 写多个寄存器(功能码16)四、MODBUS协议的应用领域MODBUS协议被广泛应用于工业自动化系统中,包括以下几个方面:1. 监控和控制:MODBUS协议可以用于监控和控制设备的状态和操作。
2. 数据传输:MODBUS协议支持在不同设备之间传输数据,实现数据的共享和交换。
3. 设备管理:MODBUS协议可用于管理和配置各种设备,例如设备的参数设置和固件更新等。
MODBUS协议整理协议名称:MODBUS协议整理协议简介:MODBUS协议是一种通信协议,用于在工业自动化系统中传输数据。
该协议采用主从结构,允许主设备(通常是控制器或计算机)与从设备(通常是传感器、执行器或其他外设)进行通信。
MODBUS协议被广泛应用于工业领域,以实现设备之间的数据交换和控制。
协议内容:1. MODBUS协议类型:- MODBUS RTU:采用二进制编码,在串行通信中使用。
- MODBUS ASCII:采用ASCII编码,在串行通信中使用。
- MODBUS TCP:采用TCP/IP协议,在以太网通信中使用。
2. MODBUS协议帧格式:- MODBUS RTU帧格式:- 起始符:1字节,值为0xFF。
- 设备地址:1字节,用于标识主从设备。
- 功能码:1字节,用于指定操作类型。
- 数据域:可变长度,包含读取或写入的数据。
- CRC校验:2字节,用于数据完整性验证。
- MODBUS ASCII帧格式:- 起始符:1字节,值为':'- 设备地址:2字节,用于标识主从设备。
- 功能码:2字节,用于指定操作类型。
- 数据域:可变长度,包含读取或写入的数据。
- LRC校验:2字节,用于数据完整性验证。
- MODBUS TCP帧格式:- 事务标识符:2字节,用于标识请求和响应的对应关系。
- 协议标识符:2字节,值为0x0000。
- 长度字段:2字节,指示后续数据长度。
- 设备地址:1字节,用于标识主从设备。
- 功能码:1字节,用于指定操作类型。
- 数据域:可变长度,包含读取或写入的数据。
3. MODBUS协议功能码:- 读取线圈状态(功能码0x01):用于读取从设备的开关量输入。
- 读取离散输入状态(功能码0x02):用于读取从设备的离散量输入。
- 读取保持寄存器(功能码0x03):用于读取从设备的模拟量输入。
- 读取输入寄存器(功能码0x04):用于读取从设备的模拟量输入。
MODBUS协议整理协议名称:MODBUS协议整理协议介绍:MODBUS协议是一种串行通信协议,广泛应用于工业自动化领域。
它定义了一种主从结构的通信方式,主要用于实现数据在不同设备间的传输和共享。
本协议整理旨在对MODBUS协议的相关内容进行详细介绍和解释,包括协议的基本原理、通信方式、数据格式、功能码等。
1. 协议基本原理:MODBUS协议采用主从结构,主设备负责发起通信请求,从设备负责响应请求。
主设备通过发送请求报文来读取或写入从设备的数据。
通信基于物理层的串行通信,如RS-232、RS-485等。
2. 通信方式:MODBUS协议支持两种主要的通信方式:ASCII(American Standard Code for Information Interchange)和RTU(Remote Terminal Unit)。
ASCII方式使用ASCII字符作为通信数据的表示形式,每个字符占用一个字节;RTU方式使用二进制编码,每个字节包含8个比特。
3. 数据格式:MODBUS协议定义了不同类型的数据帧,包括请求帧和响应帧。
请求帧包含了主设备的请求信息,响应帧包含了从设备的响应信息。
数据帧的基本结构如下:- 起始符:表示帧的开始,通常为一个字节。
- 地址字段:指定从设备的地址,通常为一个字节。
- 功能码:指定请求的功能,通常为一个字节。
- 数据字段:包含请求或响应的数据,字节长度可变。
- CRC校验:用于校验数据的完整性,通常为两个字节。
4. 功能码:MODBUS协议定义了一系列功能码,用于指定不同的操作类型。
常用的功能码包括:- 读取线圈状态(功能码01):用于读取从设备的输出线圈状态。
- 读取输入状态(功能码02):用于读取从设备的输入状态。
- 读取保持寄存器(功能码03):用于读取从设备的保持寄存器。
- 读取输入寄存器(功能码04):用于读取从设备的输入寄存器。
- 写单个线圈(功能码05):用于写入从设备的单个线圈状态。
modbus协议详解Modbus是一种通信协议,用于在自动化系统中传输数据。
它是一种简单、可靠、广泛应用的协议,被广泛用于工业控制领域。
Modbus协议基于主-从架构,其中主机负责发送请求,并接收和处理从机的响应。
主机可以是一台计算机,而从机可以是传感器、执行器或其他设备。
该协议使用不同功能代码来定义不同的操作,如读取和写入寄存器、读取和写入线圈等。
Modbus协议使用串行通信(RS-232或RS-485)或以太网通信,具有简单的数据传输格式。
它使用16位CRC校验码来确保数据的完整性。
Modbus协议包括以下几个重要组成部分:1. 功能码:用于定义不同的操作类型,如读取和写入寄存器、读取和写入线圈等。
每个功能码都有其特定的操作方式和数据格式。
2. 从站地址:用于标识从机设备,主机通过该地址与指定的从机通信。
3. 数据地址:用于标识从机设备中的数据寄存器或线圈的地址。
主机通过读写操作来访问这些数据。
4. 数据长度:用于指定要读取或写入的数据的长度。
长度可以是字节,两个字节或更多。
5. CRC校验:用于检测数据传输中是否发生错误。
主机在发送数据之前计算CRC校验码,并在接收端进行验证。
Modbus协议使用不同的功能码来执行不同的操作。
例如,功能码03用于读取保持寄存器的值,功能码06用于写入一个寄存器的值。
在Modbus协议中,主机发送请求消息给从机,并等待从机的响应消息。
从机首先解析请求消息,执行请求的操作,然后将响应结果发送回主机。
Modbus协议的优点是简单、可扩展和可靠。
它的数据传输速度相对较慢,因为它使用串行通信。
但是,由于其简单性和广泛应用,Modbus仍然是工业控制系统中最常用的通信协议之一。
尽管Modbus协议在很多方面已经过时,但仍然有很多现代控制系统和设备支持该协议。
此外,有许多现代化的Modbus协议的变种,如Modbus TCP,它使用以太网通信,提供更高的数据传输速度和更大的灵活性。
MODBUS总结 这几天终于可以暂时的放松一下,说实话做技术有时真的很累,而有事也很清闲,当项目下来的时候也就是忙碌的开始,当项目验收成功后那种久违的满足兴奋感着实让人舒服、向往。其实做技术也挺有趣我喜欢那种“过关斩将”的感觉。但是技术真的需要不断的充电,因为更新实在太快了干本赶不上当今潮流。做技术一定要抓住技术的实质,这样才能灵活运用,正所谓万变不离其宗。 做MODBUS通讯协议已经有一段时间了,回头看看这段漫长的路其中充满了一次一次的失望又一次有一次的喜悦,感觉很开心。 想当初第一次接触MODBUS时,感觉没有什么难得不就是一个串口通信么?但是自己太过清高了,其实任何一项技术如果要真真正正的掌握不下一番功夫,不经过一次次失败是不可能。 关于MODBUS TCP协议我不做讲解,这个我没有做。至于MODBUS RTU 与MODBUS ASCII协议的格式我也不再多说,这些网上太多了,我只想把我自己遇到的问题以及很多容易忽略的细节做一下阐述(下文主要是从从机的角度考虑): 1 通信速率 如果我们用单片机做MODUS通讯,一定要注意单片机的晶振。很多人不要不在意,这是最为关键的硬件部分,如果晶振不正常或者选型不匹配,那么一切都是扯淡。不怕大家笑话,我在用51单片机做MODUBS RTU通讯实验时,为了查看单片机发送的命令字节,我用八个LED灯作为每个字节的显示,可是我发现单片机只能正确的接收若干个字节的数据,而其他的都是错误的,起初我总怀疑是自己的软件设计有问题,可是改了很多遍也没有解决,很是郁闷啊 。可是我相信做技术的都有这样的经历,当你快要放弃的时候突然来了灵感,问题被很干脆的解决。我暂时放系软件去做别的事情,因为高技术最忌钻牛角尖,当遇到困难时要跳出来再跳进去。呵呵,引用我们领到的一句话,感觉说的很对很好。接下来的日子里,偶尔的一天我在焊接硬件电路时,突然眼睛定格在晶振上,一下子我全明白了,原来自己的晶振用错了(原本是11.0592M,自己用成了12M),随即换上问题不复存在。可是你们知道么就这样一个个小小的疏忽将近花费了经耗费了我一个星期的时间。 当然晶振没有问题时并不能保障你能够正确的接收信息,如果你的主从机波特率设置不同那出错也是在所难免的。
2 A B端接反 这也是很多人在不经意的时候犯下的小错误,一般很容易发现,但是不排除马大哈。 3 MODBUS协议属于典型的主从问答式协议,只有在主机发送命令后,从机正确接收后才能响应主机命令,决不能主动上传。 4 编写程序时必须严格的按照MODBUSRTU/ASCII通讯协议的格式发送数据特别要注意CRC/LRC校验码高位在先,低位在后。 5 CRC校验码的的获得常见的有两种方式一是通过查表法,二是计算法。查表法速度更快,但是占用较大内存;计算法速度稍慢但是程序代码简洁。 6 如果我们物理层上走的是232电路,数据的方向无需控制额外控制,但是如果我么采用485电路,那么这时候由于多了一个数据方向控制端口,请务必留意控制信号要和当前的数据流向一致,避免数据冲突。(这也是初学者容易犯错的地方)。 7 还有一个奇怪的现象,比如主机发送功能码03 ,当需要读取的字节很少时,从机很正常的回复,但是当数据超过一定数量后我们会发现出现了通讯超时的现象。后经分析发现是定义的发送缓冲区太小了。在C语言中经常建议我们在定义数组时确定数组的大小,即使不确定数组大小(多维除外)系统也能识别。有些时候我们忽略了数组的大小而去引用数组边界的数组元素(这样说不太恰当) 举个例子: int table[10]={0}; //定义了一个含有10个元素的整型数组 int a1; //定义了一个整型变量a1
a1=table[10]; //对a1赋值 其中对a1赋值这一语句在编译器中是不会报错的,尽管有些时候我们没有发现程序有错误,但是在默写情况下会引起某些不必要变量值的改变,从而引起系统崩溃。 在程序中引用越界数组元素是一个很大的漏洞,会给程序稳定性留下很大 的隐患,而且一般这类问题不易察觉。 8要善于总结规律,细心发现。 比如:在MODBUS RTU协议中主机发送功能码01 02 03 04 05 06时,其发送一帧数据的长度是固定的 (8个),即使功能码15 16我们也可以找到规律。这为我们编写程序提供了某些方便。我们可以根据从机接收的字节个数来判断主机命令帧是否结束,因此在网上我们会发现有相当一部分程序中从机是通过该方法判断主机命令帧结束的。但是我建议大家不要这样用,如果应用不好会带来很多麻烦很多问题,接下来我将重点讨论这点。 9 如何判断一帧数据是否接收完毕? 在说明之前我先叙述一下我的经历:原本我是拿着自己编写的程序加载的实验板上和某公司生产的采集模块的MODBUS RTU通讯比较试验效果,我采用的正是依据个数来判断一帧数据结束,我惊奇的发现我的通信灯闪烁的频率远比它的快(通过通信灯可以查看通信速率),这下我高兴坏了,感觉他们编写的程序也不过如此,现在想起来真是好笑,自己太肤浅了。首先人家模块里不单单只是MODBUS通讯一个任务,还有SPI通讯,继电器状态判断等多个任务,而我的程序只有一个任务,根本没有可比性嘛。再者人家是一个成型的产品,性能不好能占领那么大的市场么,哎太大言不惭了,羞愧难当啊! 我在做实验时,主机只连接一个从机模块,效果相当好,正当我满怀信心的向领导汇报时问题来了,来的真打击人。当主机只连接一个模块确实相当给力,没有出现任何错误,领导也确实很满意,但是紧接着领导说,你多给几个模块通讯,看看是不是正常毕竟MOBUS是一主机多从机的通讯模式。 当时的我当然不怕了,很快的连接上两个模块正准备看到那可爱的小精灵闪烁时,等了好久也没有见到,等来的却是触摸屏上显示的”Timeout error”.通讯根本不正常,一点都通不上,当时真是失望到了极点,我苦苦努力地几个月就这样流产了吗,我不甘心。于是开始查找问题,首先从硬件入手,我怀疑是我的485芯片的问题,因为我用一个自己的模块和人家公司生产的模块同主机通讯时,尽管也出现了通讯超时,但是至少偶尔也能成功,于是我把人家的485芯片拆下来换到我的模块上实验,结果又一次让我失望,非常失望,还是一点都通讯不上。 当我排出了硬件上可能存在的问题发现效果如初。看来问题不在硬件上,还是软件的问题,可是问题究竟出在哪个地方呢?由于第一次做MODBUS通讯,自己 经验不足,接下来我就在网上寻求高人指点,可是人家根本不鸟你啊,更有甚者说别做了把你的要求给我,我给你写,一个功能码50,你看如何。我哪受得了这般,当时就憋着一股劲,一定要把MODBUS解决. 我一点一点的分析程序,任何一个串口通讯无外乎接收与发送两部分,发送由于是CPU主动控制不应该有太大的问题,很有可能是接收数据出现了问题,所以我重点分析接收中断中的数据处理部分。 在这里插入一段小话题,有很多资料上说我们有时为了提高CPU的处理能力,当我们判断第一个字节不是本机地址时(假设主机发送的数据帧正确),那么该帧数据就不要接收了,直接丢掉;另一种说法是所有的从机全部接收主机发送的命令帧,当数据接受完毕时再对数据进行处理,如果是发给自己的再进行数据正确性判断。事实证明,这两种方法如果能够正确运用都是对的,但是关键就在于如何正确的运用。 第一种:如果接收到的第一个字节不是本机地址,直接丢掉,怎么丢掉?我相信很多人摇摇头,可能有人会说,禁止中断不就行了么,不错的确可以避免接收该帧数据,但是我问一下,你下次中断在什么时候打开?你是如何判断该帧数据接收完毕的? 先说一下我的思路:当从机接收到第一个数据时首先判断是否与本机地址相符,如果不符合,那么接收缓冲区地址不偏移,直到道接收到某一个字节和本机地址匹配时才开始接收该帧数据,然后根据功能码计算出该帧数据的有效长度去判断该帧数据是否接收完毕。当初毕竟经验少,现在想想真是漏洞百出啊。 假设某一时刻主机发送功能码如下(读取从机1寄存器起始地址为2的两个字节数据): 01H 03H 00H 02H 00H 01H CRCH CRCL 地址码 功能码 地址高低字节 数量高低字节 校验高地字节
漏洞1:按照自己的思想当主机发送第二个字节(功能码03H)时,从机3就会错误的认为该字节数据于本机地址相符,就会启动接收,不做太多讨论,结果必定错误。 漏洞2:从机将无法正确的计算该帧数据的长度。按常理说03H功能码的数据长度为8个字节,但是如果我们在程序中通过功能码计算数据帧长度时,问题 将不期而至,试问从机03想当然的以为其后00H是功能码进而去计算长度,请问你见过功能码00 H 么?再说了你需要的是功能码03H啊。 漏洞3:现在我们假设功能码03 H后面是03H,即从机3可以识别“有效功能码”并计算出该帧数据的长度8,但是问题又来了,主机从03H功能码到CRC校验码共计7个字节的数据,从机3之多接收这七个数据,而当从机1响应(假设接收正确)或主机重发(接收失败,响应超时),那么这时候从机3只需再接收一个字节便认为该帧数据结束,从而置位接收玩标志,进而在主程序中做数据处理。我写着就笑了,这错误太低级了。 漏洞4:有可能造成一连串的通讯超时。 假设主机发送 02H 03H 10H 02H 00H 01H CRCH CRCL 地址码 功能码 地址高低字节 数量高低字节 校验高地字节 当从机3正确的识别所谓的地址码03H与功能码10H后,开始计算出该命令帧的长度,我们知道对于主机发送的功能码10H,对应该帧数据长度为 Length=rx_buf[6]*2+9; 这里从机3缓冲区中的rx_buf[6]= CRCL;如CRCL较小那么Length也较小,假设Length=16;那么会出现漏洞3所说的那种错误,但是这种错误在较短的时间不会影响系统,当从机3再接收到10个字节就可认为该帧数据接收完毕,假设从机2正确的响应主机,而且响应数据帧长度大于10个,那么当从机3接受到10个后置位接收完标志,在主程序中判断该帧数据不是发给自己的,于是清除缓冲区,准备接收下一帧数据,如果从机3足够幸运,在主机发送命令之前完成准备工作,那么它将能正确接受到主机发给自己的命令帧;但是当CRCL较大时,情况就变得更为复杂,可能主机发送N=重试次数,从机3还认为没有接收完毕,那么这是主机就认为从机3出现了故障,放弃了对它的询问。 洛里啰嗦输了这么多,当中引用了大量的假设,这意味着程序中充满了太多的不确定性,自然出错的概率不言而喻。 分析:造成上述错误的原因是从机不能有效的分辨出同本机地址相符的究竟是地址帧还是数据帧。 为此我提出了两种解决问题的方法: 方法1:无论从机收到的第一个字节数据与本机地址相符与否都放到缓冲区