/// <summary> /// 创建数据包 /// </summary> /// <param name="addr"></param> /// <param name="funCode"></param> /// <param name="registAddress"></param> /// <param name="registLength"></param> /// <returns></returns> public static byte[] CreatePackage(byte addr, byte funCode, UInt16 registAddress, UInt16 registLength) { List <byte> bytes = new List <byte>(); bytes.Add(addr); bytes.Add(funCode); bytes.Add((byte)(registAddress >> 8)); bytes.Add((byte)registAddress); bytes.Add((byte)(registLength >> 8)); bytes.Add((byte)registLength); //必须为CRC校验 ushort tempCrc = CRC16.CRC16Code(bytes.ToArray()); bytes.Add((byte)(tempCrc >> 8)); bytes.Add((byte)tempCrc); return(bytes.ToArray()); }
/// <summary> /// 解析modbus数据包 /// 全部验证 /// </summary> void ParseModBusPackage() { while (!isExit) { lock (parseLock) { if (receBytesCache.Count < 5) { Monitor.Wait(parseLock); } else { if (modBusRtuMessage == null) { receBytesCache.Clear(); } else { if (receBytesCache[0] == modBusRtuMessage.Address) { //这里暂时不考虑程序报错 if (receBytesCache[1] == modBusRtuMessage.FunctionCode) { //读 if (modBusRtuMessage.FunctionCode != 0x06) { //整个数据包的长度 int length = receBytesCache[2] + 5; if (receBytesCache.Count >= length) { //验证CRC16 ushort crcValue = CRC16.CRC16Code(receBytesCache.ToArray(), 0, length - 2); if ((crcValue >> 8) == receBytesCache[length - 2] && (byte)crcValue == receBytesCache[length - 1]) { cmdResponseBytes = receBytesCache.GetRange(0, length).ToArray(); receBytesCache.RemoveRange(0, length); response.Set(); } else { receBytesCache.RemoveAt(0); } } else { Monitor.Wait(parseLock); } } else { //写的话 数据是一模一样的 if (modBusRtuMessage.PackageBytes.Length <= receBytesCache.Count) { bool isEquals = true; for (int i = 0; i < modBusRtuMessage.PackageBytes.Length; i++) { if (modBusRtuMessage.PackageBytes[i] != receBytesCache[i]) { isEquals = false; receBytesCache.RemoveAt(0); break; } } if (isEquals) { cmdResponseBytes = receBytesCache.GetRange(0, modBusRtuMessage.PackageBytes.Length).ToArray(); receBytesCache.RemoveRange(0, modBusRtuMessage.PackageBytes.Length); response.Set(); } } else { Monitor.Wait(parseLock); } } } else { if (receBytesCache[1] == modBusRtuMessage.FunctionCode + 0x80) { int length = 5; ushort crcValue = CRC16.CRC16Code(receBytesCache.ToArray(), 0, length - 2); if ((crcValue >> 8) == receBytesCache[length - 2] && (byte)crcValue == receBytesCache[length - 1]) { Console.WriteLine("modbus查询返回异常"); cmdResponseBytes = receBytesCache.GetRange(0, length).ToArray(); receBytesCache.RemoveRange(0, length); response.Set(); } else { receBytesCache.RemoveAt(0); } } else { receBytesCache.RemoveAt(0); } } } else { receBytesCache.RemoveAt(0); } } } } } }