日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Modbus通信协议 【 初识 Modbus】

發(fā)布時間:2025/3/15 编程问答 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Modbus通信协议 【 初识 Modbus】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

Modbus協(xié)議

 ? ? Modbus 協(xié)議是應用于電子控制器上的一種通用語言。通過此協(xié)議,控制器相互之間、控制器經(jīng)由網(wǎng)絡(例如以太網(wǎng))和其它設備之間可以通信。它已經(jīng)成為一通用工業(yè)標準。有了它,不同廠商生產(chǎn)的控制設備可以連成工業(yè)網(wǎng)絡,進行集中監(jiān)控。?

? ? ? ? 此協(xié)議定義了一個控制器能認識使用的消息結(jié)構(gòu),而不管它們是經(jīng)過何種網(wǎng)絡進行通信的。它描述了一控制器請求訪問其它設備的過程,如果回應來自其它設備的請求,以及怎樣偵測錯誤并記錄。它制定了消息域格局和內(nèi)容的公共格式。?

 ? ?Modbus 是一個請求/應答協(xié)議,當在一Modbus網(wǎng)絡上通信時,此協(xié)議決定了每個控制器須要知道它們的設備地址,識別按地址發(fā)來的消息,決定要產(chǎn)生何種行動。如果需要回應,控制器將生成反饋信息并用Modbus協(xié)議發(fā)出。在其它網(wǎng)絡上,包含了Modbus協(xié)議的消息轉(zhuǎn)換為在此網(wǎng)絡上使用的幀或包結(jié)構(gòu)。這種轉(zhuǎn)換也擴展了根據(jù)具體的網(wǎng)絡解決節(jié)地址、路由路徑及錯誤檢測的方法。

?Modbus熱圖
?

?

?

Modbus消息幀

?

了解了它,會使你對串口通信有一個清晰的認識!

通用消息幀

?

ASCII消息幀?(在消息中的每個8Bit 字節(jié)都作為兩個ASCII字符發(fā)送)

十六進制,ASCII字符0...9,A...F

消息中的每個ASCII字符都是一個十六進制字符組成

每個字節(jié)的位

1個起始位

n個數(shù)據(jù)位,最小的有效位先發(fā)送

1個奇偶校驗位,無校驗則無

1個停止位(有校驗時),2個Bit(無校驗時)

錯誤檢測域

LRC(縱向冗長檢測)

RTU消息幀

8位二進制,十六進制數(shù)0...9,A...F

消息中的每個8位域都是一個兩個十六進制字符組成

每個字節(jié)的位

1個起始位

8個數(shù)據(jù)位,最小的有效位先發(fā)送

1個奇偶校驗位,無校驗則無

1個停止位(有校驗時),2個Bit(無校驗時)

錯誤檢測域

CRC(循環(huán)冗長檢測)

CRC校驗 public static string CRCCheck(string val){val = val.TrimEnd(' ');string[] spva = val.Split(' ');byte[] bufData = new byte[spva.Length + 2];bufData = ToBytesCRC(val);ushort CRC = 0xffff;ushort POLYNOMIAL = 0xa001;for (int i = 0; i < bufData.Length - 2; i++){CRC ^= bufData[i];for (int j = 0; j < 8; j++){if ((CRC & 0x0001) != 0){CRC >>= 1;CRC ^= POLYNOMIAL;}else{CRC >>= 1;}}}return Maticsoft.DBUtility.HLConvert.ToHex(System.BitConverter.GetBytes(CRC));}/// <summary>/// 例如把如下字符串轉(zhuǎn)換成字節(jié)數(shù)組/// AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22 E5 F3 16 BB BB BB BB 轉(zhuǎn)換為字節(jié)數(shù)組/// </summary>/// <param name="hex">十六進制字符串</param>/// <returns></returns>public static byte[] ToBytesCRC(string hex){string[] temp = hex.Split(' ');byte[] b = new byte[temp.Length + 2];for (int i = 0; i < temp.Length; i++){b[i] = Convert.ToByte(temp[i], 16);}return b;}/// <summary>/// 將字節(jié)數(shù)據(jù)轉(zhuǎn)換為十六進制字符串,中間用 “ ”分割 如:AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22 E5 F3 16 BB BB BB BB/// </summary>/// <param name="vars">要轉(zhuǎn)換的字節(jié)數(shù)組</param>/// <returns></returns>public static String ToHex(byte[] vars){return BitConverter.ToString(vars).Replace('-', ' ').Trim();} CRC校驗

?

CS校驗(累加和)

public static string CSCheck(string str){if (str.Length == 0) return "";else str = str.Trim();byte[] sss = ToBytes(str);int n = 0;for (int i = 0; i < sss.Length; i++){n += sss[i];}return ToHex(n);}/// <summary>/// AB CD 12 3B 轉(zhuǎn)換為字節(jié)數(shù)組/// </summary>/// <param name="hex">十六進制字符串</param>/// <returns></returns>public static byte[] ToBytes(string hex){string[] temp = hex.Split(' ');byte[] b = new byte[temp.Length];for (int i = 0; i < temp.Length; i++){if (temp[i].Length > 0)b[i] = Convert.ToByte(temp[i], 16);}return b;}/// <summary>/// 轉(zhuǎn)換為符合本程序的十六進制格式/// </summary>/// <param name="var">1 2 3 等。</param>/// <returns>返回十六進制字符串,如果是1-9的話,前面帶零</returns>/// <example>例如: 5 ="05" 12 ="0C" 無論何時,都是兩位數(shù)。 </example>public static string ToHex(int var){int cs = var;string tmp = "";if (cs == 0) { tmp = "00"; }while (cs > 0){int ys;cs = Math.DivRem(cs, 256, out ys);tmp = tmp.Insert(0, string.Format(" {0}", Right("00" + Convert.ToString(ys, 16), 2).ToUpper()));}return tmp.Trim();}public static string Right(string str, int Length){if ((Length <= 0) || (str == null)){return "";}int length = str.Length;if (Length >= length){return str;}return str.Substring(length - Length, Length);} CS校驗(累加和)

?

LRC校驗(LRC錯誤校驗用于ASCII模式)

/// <summary>/// 取模FF(255)/// 取反+1/// </summary>/// <param name="writeUncheck"></param>/// <returns></returns>public static string LRCheck(string writeUncheck){char[] hexArray = new char[writeUncheck.Length];hexArray = writeUncheck.ToCharArray();int decNum = 0, decNumMSB = 0, decNumLSB = 0;int decByte, decByteTotal = 0;bool msb = true;for (int t = 0; t <= hexArray.GetUpperBound(0); t++){if ((hexArray[t] >= 48) && (hexArray[t] <= 57))decNum = (hexArray[t] - 48);else if ((hexArray[t] >= 65) & (hexArray[t] <= 70))decNum = 10 + (hexArray[t] - 65);if (msb){decNumMSB = decNum * 16;msb = false;}else{decNumLSB = decNum;msb = true;}if (msb){decByte = decNumMSB + decNumLSB;decByteTotal += decByte;}}decByteTotal = (255 - decByteTotal) + 1;decByteTotal = decByteTotal & 255;int a, b = 0;string hexByte = "", hexTotal = "";double i;for (i = 0; decByteTotal > 0; i++){b = Convert.ToInt32(System.Math.Pow(16.0, i));a = decByteTotal % 16;decByteTotal /= 16;if (a <= 9)hexByte = a.ToString();else{switch (a){case 10:hexByte = "A";break;case 11:hexByte = "B";break;case 12:hexByte = "C";break;case 13:hexByte = "D";break;case 14:hexByte = "E";break;case 15:hexByte = "F";break;}}hexTotal = String.Concat(hexByte, hexTotal);}return hexTotal;}public void LRCheck(byte[] code){int sum = 0;foreach (byte b in code){sum += b;}sum = sum % 255;//取模FF(255)sum = ~sum + 1;//取反+1string lrc = Convert.ToString(sum, 16);return lrc;} LRC校驗(LRC錯誤校驗用于ASCII模式)

?

?

?

自定義Modbus數(shù)據(jù)表

?

自定義Modbus數(shù)據(jù)表例子:

設備相關讀取信息:

命令報文信息解析:

自定義Modbus數(shù)據(jù)表定義注意

?

串口調(diào)試工具

?

串口調(diào)試工具的使用.

?

串口調(diào)試工具 + RS485? 就可以讀取硬件上的數(shù)據(jù),和向硬件請求了,如何使用請看“調(diào)試篇”會有詳細的說明。

?

網(wǎng)絡調(diào)試助手:

?????? 調(diào)試助手主要還是TCP協(xié)議通訊的一個調(diào)試工具

?

?

https://www.cnblogs.com/luomingui/archive/2013/06/14/Modbus.html#top

?

轉(zhuǎn)載于:https://www.cnblogs.com/Tanghongchang/p/9370004.html

總結(jié)

以上是生活随笔為你收集整理的Modbus通信协议 【 初识 Modbus】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。