马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本篇网络编程modbus的详细表明,重点放在modbus TCP部门~
假如对你有资助,请点个免费的赞吧,谢谢汪。(点个关注也可以!)
假如以下内容必要补充和修改,请各人在评论区多多交换~。
最下面有总结的关于本篇相干标题(会包括口试题和考试题),假如各人有新标题接待一起交换呀
目录
1. Modbus
1.1. modbus劈头
1.1.1. Modbus RTU
1.1.2. Modbus ASCII
1.1.3. Modbus TCP
1.1.4. Modbus协议特点
1.1.5. 应用
1.2. 分类:
1.2.1.1. Modbus RTU
1.2.1.2. 数据格式
1.2.1.3. 串行通信
1.2.1.4. 波特率
1.2.1.5. CRC校验
1.2.1.6. 帧结构
1.2.1.7. 应用
1.2.1.8. 限定
1.2.1. Modbus ASCII协议概述:
1.2.2. 关键特点:
1. 网络层和传输层
2. Modbus TCP 帧
3. 通信过程
1.3. 优势:
1.4. 应用场景:
2. ModbusTCP的协议格式
2.1. Modbus TCP 的协议格式:
2.1.1. Modbus TCP 数据帧结构:
2.1.1.1. MBAP:Modbus Application Protocol (modbus报文头) - 固定7个字节
2.1.1.2. PDU:Protocol Data Unit(协议数据单元)
2.1.1.3. Modbus TCP/IP协议最大数据帧长度为260字节
2.1.1.4. 例子:
2.2. 报文头
2.3. 寄存器
2.3.1. 线圈寄存器(Coil Registers)
2.3.2. 离散输入寄存器(Discrete Input Registers)
2.3.3. 保持寄存器(Holding Registers)
2.3.4. 输入寄存器(Input Registers)
2.4. 功能码
2.5. Modbus Slave/Poll
2.5.1. Modbus Slave 功能
2.5.2. Modbus Master(Poller)功能
2.6. 在假造机写程序实现主机功能,编写客户端实现和Slave通信。
2.6.1. 怎样封装函数实现03,05功能码的作用。各人可以实行一下。
1. Modbus
1.1. modbus劈头
Modbus由Modicon公司于1979年开辟,是一种工业现场总线协议标准。
Modbus通信协议具有多个变种,此中有支持串口,以太网多个版本,此中最著名的是Modbus RTU、Modbus ASCII和Modbus TCP三种
此中Modbus TCP是在施耐德收购Modicon后1997年发布的。
1.1.1. Modbus RTU
采用串行通信方式,数据以二进制形式传输,实用于短距离、低速率的通信场景。
1.1.2. Modbus ASCII
同样采用串行通信方式,数据以ASCII码形式传输,便于调试和阅读,但传输效率低于Modbus RTU。
1.1.3. Modbus TCP
基于以太网通信,数据传输速率较高,实用于长距离、高速率的通信场景。Modbus TCP是在施耐德收购Modicon后1997年发布的。
1.1.4. Modbus协议特点
简单性:协议相对简单,易于实现和维护,降低了设备的通信本钱。
开放性:作为一种标准协议,Modbus是开放的,不同厂商的设备可以轻松实现互联互通。
广泛性:广泛应用于工业控制领域,如PLC、变频器、智能仪表等。
可靠性:具有较好的抗干扰能力,实用于各种工业环境。
1.1.5. 应用
Modbus协议广泛应用于以下场景:
工业自动化:PLC、变频器、伺服驱动器等设备之间的通信。
能源管理:智能电表、水表、气表等的数据采集。
环境监测:温湿度、压力、流量等传感器的数据传输。
楼宇自动化:照明、空调、安防等系统的集成控制。
1.2. 分类:
1)Modbus RTU
1.2.1.1. Modbus RTU
Modbus RTU(Remote Terminal Unit)是Modbus协议的一种变体,主要用于串行通信链路。以下是Modbus RTU的一些关键特点:
1.2.1.2. 数据格式
Modbus RTU使用二进制数据格式举行通信,与Modbus ASCII的文本格式相比,RTU格式更加紧凑,可以在雷同的波特率下传输更多的数据。
数据包由地点、功能码、数据和一个校验和(通常是循环冗余校验CRC)构成。
1.2.1.3. 串行通信
Modbus RTU通常通过RS-232、RS-485或RS-422串行接口举行通信。
RS-485是Modbus RTU中最常用的通信接口,由于它支持多点通信,可以在较长的距离上以较高的速率传输数据。
1.2.1.4. 波特率
Modbus RTU的通信速率(波特率)可以是9600、19200、38400、57600或115200等,具体取决于通信距离和现场环境。
1.2.1.5. CRC校验
Modbus RTU消息使用16位的CRC校验来确保数据的完整性。在发送和接收过程中,都会盘算CRC,以确保数据在传输过程中没有发生错误。
1.2.1.6. 帧结构
Modbus RTU的消息帧包括起始位、从站地点、功能码、数据、CRC校验和停止位。
消息帧之间必须有至少3.5个字符时间的隔断,以确保帧与帧之间可以或许精确区分。
1.2.1.7. 应用
Modbus RTU广泛应用于工业自动化领域,特别是在必要可靠和稳定的串行通信的场所,如PLC、变频器、传感器和仪表之间的通信。
1.2.1.8. 限定
Modbus RTU的一个主要限定是它不支持消息的在线编辑,一旦消息开始传输,就必须等候它完全发送完毕。
另一个限定是,由于串行通信的性子,RTU通常不支持高速或长距离的数据传输,尤其是在波特率较低时。
Modbus RTU由于其简单、稳定和广泛的支持,仍然是工业通信领域的重要协议之一。
2)Modbus ASCII
1.2.1. Modbus ASCII协议概述:
串口通信:与Modbus RTU一样,Modbus ASCII协议也是为串行通信接口设计的,如RS-232、RS-485或RS-422。
ASCII码传输:Modbus ASCII协议使用ASCII码举行数据传输。这意味着每个8位的字节都被转换成两个ASCII字符,通常是两个十六进制数字。
特别字符标志:Modbus ASCII消息帧的开始和竣事都有特别字符作为标志。帧的开始是冒号(:),而帧的竣事是回车(CR)和换行(LF)字符。这些特别字符资助接收设备识别消息的界限。
传输效率:由于每个字节都必要用两个ASCII字符来表现,Modbus ASCII的传输效率确实比Modbus RTU低。对于雷同的消息,ASCII格式的数据量是RTU格式的两倍。
实用场景:由于传输效率较低,Modbus ASCII通常用于通讯量较小的应用场景,大概当设备必要使用基于文本的协议时。
错误检测:Modbus ASCII使用纵向冗余校验(LRC)来检测传输错误,而不是Modbus RTU中的CRC校验。
怎样将十六进制字节转换为ASCII字符:
十六进制字节 0xAF(1010 1111)将被转换为ASCII字符 ‘A’(41)和 ‘F’(46)。
- #include <stdint.h> // 包含 uint8_t 和 uint16_t 的定义
- uint16_t combineUint8ToUint16(uint8_t highByte, uint8_t lowByte) {
- uint16_t combinedValue = 0;
- // 将 highByte 移动到高8位,lowByte 保持不变
- combinedValue = (uint16_t)highByte << 8; // 高8位
- combinedValue |= lowByte; // 低8位
- return combinedValue;
- }
- int main() {
- uint8_t highByte = 0x12; // 示例高位字节
- uint8_t lowByte = 0x34; // 示例低位字节
- // 将两个 uint8_t 值组合成一个 uint16_t 值
- uint16_t combinedValue = combineUint8ToUint16(highByte, lowByte);
- // 输出结果
- printf("组合后的 uint16_t 值为: 0x%04X\n", combinedValue);
- return 0;
- }
复制代码 由于Modbus ASCII协议的特点,它在以下情况下更为实用:
当设备的处置惩罚器能力有限,无法处置惩罚二进制数据格式时。
当必要通过更通用的媒介(如电子邮件或文本消息)传输Modbus消息时。
当使用Modbus协议的设备必要与使用ASCII码的其他系统举行互操纵时。
只管Modbus ASCII不如Modbus RTU高效,但它仍然在某些特定的应用场景中发挥着作用。
3)Modbus TCP
Modbus TCP 是 Modbus 协议的一种实现,专门用于以太网和 TCP/IP 网络环境。它是由施耐德电气(Schneider Electric)在 1996 年推出的,旨在将 Modbus 协议的优势扩展到基于 TCP/IP 的网络。
1.2.2. 关键特点:
1. 网络层和传输层
网络层:使用 IP 协议。
传输层:使用 TCP 协议,端标语默认为 502。
2. Modbus TCP 帧
Modbus TCP 帧 structure 与传统的 Modbus RTU 和 Modbus ASCII 不同,它包括以下部门:
事件标识符(Transaction Identifier):用于事件配对,标识 Modbus 哀求/相应的对应关系。
协议标识符(Protocol Identifier):对于 Modbus TCP,这个值始终为 0x0000。
长度字段:表现后续字段的字节数,包括单元标识符、功能码和数据字段。
单元标识符(Unit Identifier):在 Modbus TCP 中,这个字段通常用于标识特定的服务器或设备。
功能码(Function Code):与 Modbus RTU 和 Modbus ASCII 中的功能码雷同,用于指示哀求或相应的类型。
数据字段:包含哀求或相应的具体数据。
校验和:在 Modbus TCP 中,由于 TCP/IP 协议已经提供了错误检测机制,因此不必要额外的校验和。
3. 通信过程
建立连接:客户端通过 TCP/IP 网络与服务器建立连接。
发送哀求:客户端发送 Modbus TCP 哀求帧到服务器。
处置惩罚哀求:服务器接收哀求,处置惩罚哀求,并天生相应。
发送相应:服务器将 Modbus TCP 相应帧发送回客户端。
关闭连接:完成通信后,客户端和服务器可以关闭 TCP 连接,也可以保持连接状态以供后续通信使用。
1.3. 优势:
易于实现:基于成熟的 TCP/IP 协议栈,简化了网络通信的实现。
可靠性:利用 TCP 的错误检测和重传机制,提高了通信的可靠性。
兼容性:可以与现有的 Modbus 应用程序和设备兼容,只需举行得当的网关转换。
免费,简单,易于使用。
1.4. 应用场景:
Modbus TCP 广泛应用于工业自动化领域,特别是在必要通过以太网举行设备监控和控制的环境中。它被用于各种类型的设备,包括 PLCs、HMI、SCADA 系统、传感器和执行器等。
由于 Modbus TCP 依靠于稳定的网络环境,因此在网络条件精良的情况下,它是实现工业设备网络通信的抱负选择。
2. ModbusTCP的协议格式
Modbus TCP 是 Modbus 协议的以太网版本,它将 Modbus RTU 或 Modbus ASCII 协议的数据帧封装在 TCP/IP 协议中。
2.1. Modbus TCP 的协议格式:
具体协议分析可参考:
实例分享 | ModbusTCP报文详解
2.1.1. Modbus TCP 数据帧结构:
ModbusTcp协议包含三部门:报文头、功能码、数据。
2.1.1.1. MBAP:Modbus Application Protocol (modbus报文头) - 固定7个字节
事件标识符(Transaction Identifier) - 2 字节
这是一个唯一标识符,用于匹配哀求和相应。在哀求和相应中,这个字段的值是雷同的。
协议标识符(Protocol Identifier) - 2 字节
对于 Modbus TCP,这个字段的值始终是 0x0000。
长度字段(Length Field) - 2 字节
表现接下来的单元标识符、功能码和数据字段的字节数。不包括事件标识符、协议标识符和长度字段本身。
单元标识符(Unit Identifier) - 1 字节
也称为设备地点或从站地点。在 Modbus TCP 中,这个字段用于标识网络上的 Modbus 从设备。
2.1.1.2. PDU:Protocol Data Unit(协议数据单元)
功能码(Function Code) - 1 字节
表现哀求或相应的具体功能。比方,读保持寄存器是功能码 0x03,写单个寄存器是功能码 0x06。
数据字段(Data Field) - n 字节
这个字段包含了与功能码相干的具体数据。比方,假如功能码是读保持寄存器,那么这个字段将包含起始地点、寄存器数目等信息。
Modbus TCP 数据帧示例:
+----------------+-+-+-+-----------+-+-------------+-+----------+-+-+
| Transaction ID | 0 | 0 | Protocol | Unit ID | Function Code | Data |
| (2 bytes) | 0 | 0 | ID (2 | (1 byte) | (1 byte) | (n |
+----------------+-+-+-+-----------+-+-------------+-+----------+-+-+
| | T | L | bytes) | | | bytes)
+----------------+-+-+-+-----------+-+-------------+-+----------+-+-+
2.1.1.3. Modbus TCP/IP协议最大数据帧长度为260字节
2.1.1.4. 例子:
假设我们要读取从设备地点为 0x01 的保持寄存器,起始地点为 0x0002,读取 2 个寄存器。
数据帧如下:
Transaction ID: 0x0001
Protocol ID: 0x0000
Length: 0x0006 (6 bytes for Unit ID, Function Code, and Data)
Unit ID: 0x01
Function Code: 0x03 (Read Holding Registers)
Data: 0x0002 0x0002 (起始地点为 0x0002,读取 2 个寄存器)
实际的字节省(十六进制表现)可能是:
这个数据帧会被封装在 TCP/IP 数据包中,并通过以太网发送。接收方分析这个数据帧,并根据功能码和数据字段执行相应的操纵,然后返回一个包含雷同事件标识符的相应。
2.2. 报文头
7个字节
2.3. 寄存器
2.3.1. 线圈寄存器(Coil Registers)
类型:位寄存器(每个寄存器占 1 位,但在传输时通常以字节为单位)
用途:控制离散输出(如继电器、开关)
特性:可读可写
功能码:
读线圈:0x01
写单个线圈:0x05
写多个线圈:0x0F
2.3.2. 离散输入寄存器(Discrete Input Registers)
类型:位寄存器(每个寄存器占 1 位,但在传输时通常以字节为单位)
用途:读取离散输入(如按钮、传感器状态)
特性:只读
功能码:
读离散输入:0x02
2.3.3. 保持寄存器(Holding Registers)
类型:字寄存器(每个寄存器占 2 字节)
用途:存储可读写的数据,如配置参数、设备状态
特性:可读可写
功能码:
读保持寄存器:0x03
写单个保持寄存器:0x06
写多个保持寄存器:0x10
2.3.4. 输入寄存器(Input Registers)
类型:字寄存器(每个寄存器占 2 字节)
用途:读取设备输入的数据,如传感器读数、计数器值
特性:只读
功能码:
读输入寄存器:0x04
读操纵:通常一个功能码可以用于读取单个或多个寄存器。
写操纵:写单个和写多个寄存器通常有不同的功能码。
可读可写寄存器:具有三个功能码(读多个、读/写单个、写多个)。
只读寄存器:具有一个功能码(读多个)。
2.4. 功能码
功能码占一个字节
2.5. Modbus Slave/Poll
下载与安装,modbus Slave/Poll ,可以用于具体的查看modbus数据帧的结果。会以表格的方式出现出来,软件界面如下:
下载,安装以及使用我会在下一篇文档中详细阐明
本篇只必要通过代码实现数据帧的收发
在Modbus通信网络中,Modbus Slave(从设备)和Modbus Master(主设备)共同工作,以实现数据交换和控制命令的通报。以下是Modbus Slave和Master(Poller)的功能:
2.5.1. Modbus Slave 功能
相应哀求:从设备监听来自主设备的哀求,并根据哀求类型(功能码)提供相应的数据或执行指定的操纵。
数据存储:Slave设备通常具有四种类型的寄存器(线圈、离散输入、输入寄存器、保持寄存器),用于存储数据。
数据处置惩罚:Slave设备根据主设备的哀求处置惩罚数据,比方读取传感器数据、执行控制命令等。
错误检测:在处置惩罚哀求时,Slave设备会检测可能的错误,并在相应中包含错误码,以便主设备相识哀求的状态。
支持多种功能码:Slave设备必要支持多种功能码,以相应不同类型的哀求,如读/写线圈、读/写寄存器等。
串行或网络通信:Slave设备可以或许通过串行通信(如RS-485)或以太网举行数据交换。
2.5.2. Modbus Master(Poller)功能
发起哀求:主设备(Poller)负责发起通信,向从设备发送哀求以读取数据或写入命令。
轮询从设备:主设备定期轮询从设备,以获取状态更新或监控数据。
处置惩罚相应:主设备接收从设备的相应,并处置惩罚这些数据,比方更新人机界面(HMI)、记录数据或触发报警。
错误处置惩罚:主设备可以或许识别从设备相应中的错误,并采取相应的措施,如重试哀求、记录错误日志或通知操纵员。
支持多种功能码:主设备必要支持多种功能码,以执行不同的操纵,如读取输入寄存器、写入保持寄存器等。
通信管理:主设备负责管理通信网络,包括维护通信链路、处置惩罚网络故障和优化数据传输。
数据整合:主设备可能必要将从不同从设备收集的数据整合到一个统一的系统中,以便举行更高级的数据处置惩罚和分析。
时间同步:在某些应用中,主设备可能还必要负责网络中的时间同步,确保全部从设备使用雷同的时钟源。
2.6. 在假造机写程序实现主机功能,编写客户端实现和Slave通信。
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <arpa/inet.h>
- #include <sys/select.h>
- #include <pthread.h>
- #include <sqlite3.h>
- #include <errno.h>
- #include <netinet/tcp.h>
- int main(int argc, char const *argv[])
- {
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- {
- perror("sock err");
- return 0;
- }
- struct sockaddr_in addr, caddr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(502);
- addr.sin_addr.s_addr = inet_addr("192.168.0.116");
- int len = sizeof(caddr);
- printf("connect ok\n");
- connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
- // 写保持寄存器,让第6位为6
- uint8_t data[12] = {
- 0x00,
- 0x00, // 服务器
- 0x00, // 协议标示
- 0x00,
- 0x00,
- 0x06, // 字节数
- 0x01, // 单元标识
- 0x06, // 功能
- 0x00,
- 0x06, // 位置
- 0x00,
- 0x07 // 值
- };
- send(sockfd, data, sizeof(data), 0);
- uint8_t d[12];
- int res = recv(sockfd, d, 12, 0);
- for (int i = 0; i < 12; i++)
- {
- printf("%02x ", d[i]);
- }
- printf("\n");
- close(sockfd);
- return 0;
- }
复制代码 2.6.1. 怎样封装函数实现03,05功能码的作用。各人可以实行一下。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |