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校验(/view/1664507.htm) 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;}}}returnMaticsoft.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 22E5 F3 16 BB BB BB BB/// </summary>/// <param name="vars">要转换的字节数组</param>/// <returns></returns>public static String ToHex(byte[] vars){returnBitConverter.ToString(vars).Replace('-', ' ').Trim();}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);}LRC校验(LRC错误校验用于ASCII模式)/// <summary>/// 取模FF(255)/// 取反+1/// </summary>/// <paramname="writeUncheck"></param>/// <returns></returns>public static string LRCheck(string writeUncheck){char[] hexArray = newchar[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;}。