public RTUFrame(byte addr, byte funcode, byte[] sendData, byte datalen) { //addrss(1) funcode(1) + bytecount(1) sendData(datalen) CRC(2) int len = 1 + 1 + 1 + datalen + 2; frame = new byte[len]; this.dataLen = datalen; this.address = addr; this.function = (byte)funcode; this.framedata = new byte[datalen]; for (int i = 0; i < datalen; i++) { this.framedata[i] = sendData[i]; frame[i + 3] = sendData[i]; } frame[0] = addr; frame[1] = (byte)funcode; frame[2] = (byte)datalen; ushort crc = GenCRC.CRC16(frame, (ushort)(len - 2)); //ushort crc = (ushort)len; frame[len - 2] = (byte)(crc & 0xFF); //低8位 frame[len - 1] = (byte)((crc & 0xFF00) >> 8); //高8位 completeFlag = false; saveFlag = false; }
/// <summary> /// 对于租数据进行判读 /// </summary> /// <param name="frame"></param> /// <param name="rtuf"></param> /// <returns></returns> public static ErrorCodeEnum JudgeFrame(byte[] frame, out RTUFrame rtuf, byte reciveAddress) { //数据长度不符合最小长度 rtuf = new RTUFrame(reciveAddress, 0); if (frame.Length < 5) { return(ErrorCodeEnum.ErrorLength); } if (!(frame[0] == reciveAddress)) { return(ErrorCodeEnum.ErrorAddress); } var fun = frame[1]; //长度数 int len = frame[2]; //获取数据字节数 if (frame.Length < len + 5) { return(ErrorCodeEnum.ErrorLength); } ushort crc = GenCRC.CRC16(frame, (ushort)(len + 3)); byte crcl = (byte)(crc & 0x00FF); byte crch = (byte)(crc & 0xFF00 >> 8); var low = (byte)(crc & 0xFF); //低8位 var getbyte = frame[len + 3]; if (crcl != getbyte) { return(ErrorCodeEnum.ErrorCRCL); } var hig = (byte)(crc & 0xFF00 >> 8);//高8位 getbyte = frame[len + 4]; if (crch != getbyte) { return(ErrorCodeEnum.ErrorCRCH); } List <byte> tmp = new List <byte>(); tmp.AddRange(frame); tmp.RemoveRange(0, 3); //去除头 rtuf = new RTUFrame(frame[0], frame[1], tmp.ToArray(), (byte)len, low, hig); rtuf.Time = DateTime.Now; return(ErrorCodeEnum.Correct); }
/// <summary> /// 从字节流中判断是否为相应帧 /// </summary> /// <param name="reciveData">接收的字节流</param> /// <param name="sendFrame">发送的帧数据</param> /// <returns></returns> public bool JudgeResponseFrame(List <byte> reciveData, RTUFrame sendFrame, RTUFrame reciveFrame) { //首先判断这一帧是否已经完成响应 //if (!sendFrame.CompleteFlag) { //测试注销 //判断 查询地址 与 发送地址 是否一致 if (reciveData[0] != sendFrame.Address) { return(false); } if (reciveData[1] != sendFrame.Function) { return(false); } int len = reciveData[2]; //获取数据字节数 //再紧接着进行CRC校验 ushort crc = GenCRC.CRC16(reciveData.ToArray(), (ushort)(len + 3)); var low = (byte)(crc & 0xFF); //低8位 if (low != reciveData[2 + len - 1]) { return(false); } var hig = (byte)(crc & 0xFF00 >> 8);//高8位 if (low != reciveData[2 + len]) { return(false); } List <byte> tmp = new List <byte>(); tmp.AddRange(reciveData); tmp.RemoveRange(0, 3); //去除头 tmp.RemoveRange(len, 2); //去除尾巴 reciveFrame = new RTUFrame(reciveData[0], reciveData[1], tmp.ToArray(), (byte)len); sendFrame.CompleteFlag = true; //防止重复响应 ReciveFrame.Time = DateTime.Now; return(true); } //else //{ // return false; //} }
/// <summary> /// 判断数据是否满足一帧要求 /// </summary> /// <param name="sendFrame">需要存储的数据帧</param> /// <param name="quneRecive">出队参数</param> /// <returns>true-符合帧要求,false--不符合</returns> private bool judgeDataPart(RTUFrame sendFrame, Queue <byte> quneRecive) { //队列数据长度大于已知数据长度 if (quneRecive.Count >= sendFrame.DataLen + 2) { sendFrame.Frame = new byte[sendFrame.DataLen + 5]; sendFrame.FrameData = new byte[sendFrame.DataLen]; sendFrame.Frame[0] = sendFrame.Address; sendFrame.Frame[1] = sendFrame.Function; sendFrame.Frame[2] = sendFrame.DataLen; //获取数据 for (int i = 0; i < sendFrame.DataLen; i++) { sendFrame.Frame[i + 3] = quneRecive.Dequeue(); sendFrame.FrameData[i] = sendFrame.Frame[i + 3]; } //可先校验 var cl = quneRecive.Dequeue(); //获取校验位低8bit var ch = quneRecive.Dequeue(); //获取校验位高8bit sendFrame.Frame[sendFrame.DataLen + 3] = cl; sendFrame.Frame[sendFrame.DataLen + 4] = ch; ushort crc = GenCRC.CRC16(sendFrame.Frame, (ushort)(sendFrame.DataLen + 3)); byte crcl = (byte)(crc & 0x00FF); byte crch = (byte)((crc & 0xFF00) >> 8); if (crcl != cl) { return(false); } if (crch != ch) { return(false); } sendFrame.SaveFlag = true; sendFrame.ErrorFlag = ErrorCodeEnum.Correct; return(true); } else { return(false); } }
//private DateTime recivedTime; /// <summary> /// 获取字节数据,并进帧平判断 /// </summary> /// <param name="sendFrame">帧</param> /// <returns>true--完整的一帧, false--不是完整一帧</returns> public bool JudgeGetByte(RTUFrame sendFrame) { //首先判断这一帧是否已经完成响应 // if (!sendFrame.CompleteFlag) { //判断 查询地址 与 发送地址 是否一致 // if (GetByte() != sendFrame.Address) // return false; //放宽范围 byte addr = GetByte(); if (!(addr == JudgeAddress)) { return(false); } reciveFlagTuple = new Tuple <bool, DateTime>(true, DateTime.Now); //if (GetByte() != sendFrame.Function) // return false; var fun = GetByte(); int len = GetByte(); //获取数据字节数 byte[] array = new byte[len + 3]; //array[0] = sendFrame.Address; array[0] = addr; //array[1] = sendFrame.Function; array[1] = fun; array[2] = (byte)len; for (int i = 0; i < len; i++) { array[i + 3] = GetByte(); } ushort crc = GenCRC.CRC16(array, (ushort)(len + 3)); //ushort crc = (ushort)(len + 5); byte crcl = (byte)(crc & 0x00FF); byte crch = (byte)(crc & 0xFF00 >> 8); var low = (byte)(crc & 0xFF); //低8位 var getbyte = GetByte(); if (crcl != getbyte) { return(false); } var hig = (byte)(crc & 0xFF00 >> 8);//高8位 getbyte = GetByte(); if (crch != getbyte) { return(false); } List <byte> tmp = new List <byte>(); tmp.AddRange(array); tmp.RemoveRange(0, 3); //去除头 ReciveFrame = new RTUFrame(array[0], array[1], tmp.ToArray(), (byte)len, low, hig); reciveFlagTuple = new Tuple <bool, DateTime>(false, DateTime.Now); sendFrame.CompleteFlag = true; //防止重复响应 ReciveFrame.Time = DateTime.Now; return(true); } // else // { // return false; // } }