Modbus_RTU

news/2024/11/17 1:28:09/文章来源:https://www.cnblogs.com/zeussbook/p/18351579

本文主要记录串口通信,主要记录 modbus 的默认通信协议 modbus_RTU,当然modbus还包含 modbus_TCP(网口)和 modbus_ASCII(串口)。

一、基础知识

串口和网口
 串口:串口是一种物理接口,通常用于连接计算机和外部设备,如打印机、鼠标等。它使用一根线缆进行数据传输,常见的接口有RS-232、RS-485等。串口通信是异步的,可以在一根线上同时发送和接收数据。串口通信适用于需要简单、低成本通信的场景,如打印机、外部存储设备等。它也适用于需要长距离通信的应用,如工业控制系统中的远程监控。网口:网口主要用于计算机网络连接,如以太网接口(Ethernet Port),通常通过RJ45接口连接,使用双绞线或光纤进行数据传输。网口通信支持网络协议,如TCP/IP,用于在局域网或广域网中进行数据传输。
 
基本名词

 

传输TX:TXD(Transmit Data)发送数据,用于数据的双向传输。
接收RX:RXD(Received Data)接收数据
地线GND:GND(Ground)代表地线或0线,公共端的意思,这个地并不是真正意义上的地,是出于应用而假设的地,对于电源来说,它就是一个电源的负极。用于建立电平参考,保证信号的稳定传输。位:0或1,就是二进制里面的每一个数
字节:8个二进制组成一个字节
字符:一个汉字2个字节,一个英文字母1个字节数据位:表示每次发送的数据长度,取值5~8
报文格式:起始位+报文(数据位)+停止位,其中0表示起始位,1和2表示结束位
大端序:大位在前,小位在后
波特率:1秒内能传输多少个高低电平,双方必须设置成一致
低电平:0~0.4V 
高电平:2.4~5V

 

 

 

RS232
RS232标准:转换高低电平的作用,减少感染,增加传输距离。把高电平位拉高到12V传输,把高电平转换成5V解析。传输距离最大15米,波特率2M,全双工通信(只能1对1)

 

 
RS485

 

RS485标准:通过转换芯片,把外部干扰的高低电平同时升高,大大增加了抗干扰的能力,增加传输距离。传输距离最大1200米,波特率50M,半双工通信(1主多从)

 

modbus

存储区

 

存储的数据类型分为 :布尔量 和 16位寄存器布尔量:位操作。16位寄存器: 字节操作,长度16位。2个字节,2的16次方。10进制最大值65536,因此值范围0~65535

 

 

区号

名称

读写

值类型

定义范围

实际范围

0区

输出线圈 Coil Status

可读写布尔量

布尔

00001~09999

00001~65535

1区

输入状态Input Status

只读布尔量

布尔

10001~19999

100001~165535

3区

输入寄存器Input Register

只读寄存器

2字节无符号

30001~39999

300001~365535

4区

保持(输出)寄存器 Holding Register

可读寄存器

2字节无符号

40001~49999

400001~465535

 
功能码
功能码 寄存器类型 读写状态 PLC地址 modbus地址 操作数据类型 操作数量
01H 读取线圈状态 可读可写 00001~09999 0000H~FFFFH 位操作 单个或多个
02H 读取输入状态 只读 10001~19999 0000H~FFFFH 位操作 单个或多个
03H 读取保持寄存器 可读可写 40001~49999 0000H~FFFFH 字节操作 单个或多个
04H 读取输入寄存器 只读 30001~39999 0000H~FFFFH 字节操作 单个或多个
05H 写入单线圈 可读可写 00001~09999 0000H~FFFFH 位操作   单个
06H 写入单寄存器 可读可写 40001~49999 0000H~FFFFH 字节操作 单个
0FH 写入多线圈 可读可写 00001~09999 0000H~FFFFH 位操作 单个
10H 写入多寄存器 可读可写 40001~49999 0000H~FFFFH 字节操作 多个

这里可以总结,输入都是只读,输出可读可写。

CRC

CRC全称循环冗余校验(Cyclic Redundancy Check, CRC),是通信领域数据传输技术中常用的检错方法,用于保证数据传输的可靠性。

CRC16算法过程

1 初始化一个16位的寄存器地址 用作初始值
2 遍历数据字节,从最高位到最低位, 
3 将数据字节与寄存器异或
4 对寄存器进行8次迭代,每一次迭代将寄存器右移一位
5 如果最低位位1,将寄存器与生成多项式0x8005异或,否则只进行右移操作
6 重复上述步骤直到遍历完所有的字节
7 最终寄存器的值就是crc16校验码
8 crc计算之后高低位进行互换

CRC16算法

    public static class CRC16{/// <summary>/// CRC校验,参数data为byte数组/// </summary>/// <param name="data">校验数据,字节数组</param>/// <returns>字节0是高8位,字节1是低8位</returns>public static byte[] CRCCalc(byte[] data){//crc计算赋初始值int crc = 0xffff;for (int i = 0; i < data.Length; i++){crc = crc ^ data[i];for (int j = 0; j < 8; j++){int temp;temp = crc & 1;crc = crc >> 1;crc = crc & 0x7fff;if (temp == 1){crc = crc ^ 0xa001;}crc = crc & 0xffff;}}//CRC寄存器的高低位进行互换byte[] crc16 = new byte[2];//CRC寄存器的高8位变成低8位,crc16[1] = (byte)((crc >> 8) & 0xff);//CRC寄存器的低8位变成高8位crc16[0] = (byte)(crc & 0xff);return crc16;}/// <summary>/// CRC校验,参数为空格或逗号间隔的字符串/// </summary>/// <param name="data">校验数据,逗号或空格间隔的16进制字符串(带有0x或0X也可以),逗号与空格不能混用</param>/// <returns>字节0是高8位,字节1是低8位</returns>public static byte[] CRCCalc(string data){//分隔符是空格还是逗号进行分类,并去除输入字符串中的多余空格IEnumerable<string> datac = data.Contains(",") ? data.Replace(" ", "").Replace("0x", "").Replace("0X", "").Trim().Split(',') : data.Replace("0x", "").Replace("0X", "").Split(' ').ToList().Where(u => u != "");List<byte> bytedata = new List<byte>();foreach (string str in datac){bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier));}byte[] crcbuf = bytedata.ToArray();//crc计算赋初始值return CRCCalc(crcbuf);}/// <summary>///  CRC校验,截取data中的一段进行CRC16校验/// </summary>/// <param name="data">校验数据,字节数组</param>/// <param name="offset">从头开始偏移几个byte</param>/// <param name="length">偏移后取几个字节byte</param>/// <returns>字节0是高8位,字节1是低8位</returns>public static byte[] CRCCalc(byte[] data, int offset, int length){byte[] Tdata = data.Skip(offset).Take(length).ToArray();return CRCCalc(Tdata);}
}

 

 

modbus_RTU协议

01H 读取线圈状态(多个)

格式:

发送报文:从站地址+功能码+开始线圈地址+线圈数量+CRC返回报文:从站地址+功能码+字节计数+数据+CRC

 

02H 读输入状态

格式:

 

发送报文:从站地址+功能码+起始地址+输入长度+CRC返回报文:从站地址+功能码+数据长度+数据+CRC

 

03H读取保持寄存器

格式:

发送报文:从站地址+功能码+开始寄存器地址+寄存器数量+CRC返回报文:从站地址+功能码+字节计数+数据+CRC

 

04H读取输入寄存器

格式:

发送报文:从站地址+功能码+开始寄存器地址+寄存器数量+CRC返回报文:从站地址+功能码+字节计数+数据+CRC

 

05H写入单线圈

格式:

发送报文:从站地址+功能码+线圈地址+线圈值+CRC返回报文:从站地址+功能码+线圈地址+线圈值+CRC

 

 

06H写入单寄存器

格式:

发送报文:从站地址+功能码+寄存器地址+寄存器值+CRC返回报文:从站地址+功能码+寄存器地址+寄存器值+CRC

 

0FH写入多线圈

格式:

发送报文:从站地址+功能码+起始线圈地址+数量+字节技术+数据+CRC返回报文:从站地址+功能码+起始线圈地址+数量+CRC

 

10H写入多寄存器

格式:

发送报文:从站地址+功能码+起始寄存器地址+数量+字节计数+数据+CRC返回报文:从站地址+功能码+起始寄存器地址+数量+CRC

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/780513.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

异步FIFO设计

Asynchronous FIFO Design总结来自Clifford E. Cummings论文 《Simulation and Synthesis Techniques for Asynchronous FIFO Design》一、设计难点使用格雷码计数时空和满的判断。 同步FIFO读写时钟相同,而异步FIFO读写来自不同两个读写时钟,需要考虑跨时钟域设计。二、设计…

常量的基础认知和相互转化

常量:在java程序运行过程中,其值不能够发送改变的量 分类:字面值常量:字符串常量:被双引号括起来的字符序列 "java"字符常量:被单引号括起来的单个字符 a整数常量:所有的整数 100 200 -100小数常量:所有的小数 1.23 3.14 -1.23布尔常量:true false空常…

.NET 窗口/屏幕录制

窗口/屏幕截图适用于截图、批注等工具场景,时时获取窗口/屏幕图像数据流呢,下面讲下视频会议共享桌面、远程桌面这些场景是如何实现画面录制的。 常见的屏幕画面时时采集方案,主要有GDI、WGC、DXGI。 GDI GDI(Graphics Device Interface)就是使用user32下WindowsAPI来实现…

.NET 屏幕录制

窗口/屏幕截图适用于截图、批注等工具场景,时时获取窗口/屏幕图像数据流呢,下面讲下视频会议共享桌面、远程桌面这些场景是如何实现画面录制的。 常见的屏幕画面时时采集方案,主要有GDI、WGC、DXGI。 GDI GDI(Graphics Device Interface)就是使用user32下WindowsAPI来实现…

Kubernetes-POD的QoS

目录背景问题分析进一步排查问题原因Pod的QoS服务质量等级结论 背景 今天开发团队反馈,测试环境中部分业务功能无法正常使用。经过初步排查,发现某个业务Pod在一天内重启了10次,因此需要进一步调查原因。 问题分析 首先,我查看了Pod的日志,发现JVM并未抛出任何错误,服务却…

2024.8.9 鲜花

几张图?推歌:早安大森林 ![](https://baike.baidu.com/pic/%E6%97%A9%E5%AE%89%E5%A4%A7%E6%A3%AE%E6%9E%97/64160919/1/b17eca8065380cd791236bebf51cba345982b2b72b26?fr=lemma&fromModule=lemma_content-image#aid=1&pic=b17eca8065380cd791236bebf51cba345982b2…

赋值运算符和+号的用法(两个练习)

string strName = "kakaxi";string strVillage = "huoyingcun";int iAge = 20;string strEmail = "1287195315@qq.com";decimal deSalary = 2000m;Console.WriteLine("大家好,我叫{0},我今年{1}岁了, 我住在{2},我的邮箱是{3}, 我的工资有足…

中国四大软件外包公司

今天我们来聊聊国内的四大软件外包公司。这些公司不仅在国内市场中占据重要地位,还对全球软件外包行业产生了影响。部分数据来源网络排名,按照职位量、增长速度排名,排名仅供参考,去某家公司一定要多方位参考,比如企查查、脉脉等。要说软件外包这块大蛋糕,谁不想来一口呢…

六、决策树

决策1:如何选择在每个节点上分割什么特征?最大限度地提高纯度(或最小限度地减少不纯)。决策2:什么时候停止拆分?当一个节点是一个单一类时 当拆分一个节点会导致树超过最大的深度 当纯度分数的改进低于一个阈值(获得的信息增益很小小于阈值) 当一个节点中的例子数量低于…

性能测试面试题大曝光,让你如何迅速拿下 offer!

性能测试面试题精选1、 以前做过性能测试么?请结合例子具体说明性能测试的流程 面试考察点:性能测试的流程首选做性能测试的需求分析,明确性能测试的目标、范围、场景和性能指标(如响应时间、吞吐量、并发用户数等)。测试性能测试环境搭建:搭建与生产环境尽可能一致的测试…

[Java并发]ThreadLocal补充

ThreadLocal缺点及解决方案 每个Thread上都有一个threadLocals属性,它是一个ThreadLocalMap,里面存放着一个Entry数组,key是ThreadLocal类型的弱引用,value是对用的值。所有的操作都是基于这个ThreadLocalMap操作的。 但是它有一个局限性,就是不能在父子线程之间传递。 即…

NuminaMath 是如何荣膺首届 AIMO 进步奖的?

今年,Numina 和 Hugging Face 合作角逐 AI 数学奥林匹克 (AI Math Olympiad,AIMO) 的首届进步奖。此次比赛旨在对开放 LLM 进行微调,以使其能解决高中难度的国际数学奥林匹克训练题。我们很高兴向大家报告: 我们的模型 - NuminaMath 7B TIR - 在比赛中脱颖而出,成功解决了私…