Modbus通信协议 【 初识 Modbus】
?
Modbus協議
? ? Modbus 協議是應用于電子控制器上的一種通用語言。通過此協議,控制器相互之間、控制器經由網絡(例如以太網)和其它設備之間可以通信。它已經成為一通用工業標準。有了它,不同廠商生產的控制設備可以連成工業網絡,進行集中監控。?
? ? ? ? 此協議定義了一個控制器能認識使用的消息結構,而不管它們是經過何種網絡進行通信的。它描述了一控制器請求訪問其它設備的過程,如果回應來自其它設備的請求,以及怎樣偵測錯誤并記錄。它制定了消息域格局和內容的公共格式。?
? ?Modbus 是一個請求/應答協議,當在一Modbus網絡上通信時,此協議決定了每個控制器須要知道它們的設備地址,識別按地址發來的消息,決定要產生何種行動。如果需要回應,控制器將生成反饋信息并用Modbus協議發出。在其它網絡上,包含了Modbus協議的消息轉換為在此網絡上使用的幀或包結構。這種轉換也擴展了根據具體的網絡解決節地址、路由路徑及錯誤檢測的方法。
?Modbus熱圖
?
?
?Modbus消息幀
?
了解了它,會使你對串口通信有一個清晰的認識!
通用消息幀
?
ASCII消息幀?(在消息中的每個8Bit 字節都作為兩個ASCII字符發送)
十六進制,ASCII字符0...9,A...F
消息中的每個ASCII字符都是一個十六進制字符組成
每個字節的位
1個起始位
n個數據位,最小的有效位先發送
1個奇偶校驗位,無校驗則無
1個停止位(有校驗時),2個Bit(無校驗時)
錯誤檢測域
LRC(縱向冗長檢測)
RTU消息幀
8位二進制,十六進制數0...9,A...F
消息中的每個8位域都是一個兩個十六進制字符組成
每個字節的位
1個起始位
8個數據位,最小的有效位先發送
1個奇偶校驗位,無校驗則無
1個停止位(有校驗時),2個Bit(無校驗時)
錯誤檢測域
CRC(循環冗長檢測)
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>/// 例如把如下字符串轉換成字節數組/// 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="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>/// 將字節數據轉換為十六進制字符串,中間用 “ ”分割 如: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">要轉換的字節數組</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 轉換為字節數組/// </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>/// 轉換為符合本程序的十六進制格式/// </summary>/// <param name="var">1 2 3 等。</param>/// <returns>返回十六進制字符串,如果是1-9的話,前面帶零</returns>/// <example>例如: 5 ="05" 12 ="0C" 無論何時,都是兩位數。 </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數據表
?
自定義Modbus數據表例子:
設備相關讀取信息:
命令報文信息解析:
自定義Modbus數據表定義注意
?
串口調試工具
?
串口調試工具的使用.
?
串口調試工具 + RS485? 就可以讀取硬件上的數據,和向硬件請求了,如何使用請看“調試篇”會有詳細的說明。
?
網絡調試助手:
?????? 調試助手主要還是TCP協議通訊的一個調試工具
?
?
https://www.cnblogs.com/luomingui/archive/2013/06/14/Modbus.html#top
?
轉載于:https://www.cnblogs.com/Tanghongchang/p/9370004.html
總結
以上是生活随笔為你收集整理的Modbus通信协议 【 初识 Modbus】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rinetd 进行转发
- 下一篇: JDK源码分析(三)——HashMap