我正在从.bin文件中读取字节数据并将整个字节数据拆分成16-16字节的帧,所以我希望逐个16字节的帧并等到第一帧完成它的循环.
SerialPort类的回调方法:
private void port_DataReceived(object sender,SerialDataReceivedEventArgs e) { // Read data from serial port: byte[] buffer = new byte[serialPort.BytesToRead]; serialPort.Read(buffer,buffer.Length); StringBuilder sb = new StringBuilder(); List<string> response = new List<string>(); for (int i = 0; i < buffer.Length; i++) { string currentByte = string.Format("{0:X2}",buffer[i]); response.Add(currentByte); sb.AppendFormat("{0:X2}",buffer[i]); } string responesCode = response[1].ToString(); if (responesCode == "44") { // Wait until the first response is not received foreach (var packet in packetList.Skip(1)) { // This method which sending the the data this.ReadByteDataFromFile(packet); } } }
FdbrowseFile_Click按钮单击:
private void FdbrowseFile_Click(object sender,RoutedEventArgs e) { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); Nullable<bool> result = dlg.ShowDialog(); if (result == true) { byte[] fileBytes = File.ReadAllBytes(filename); foreach (byte[] copySlice in fileBytes.Slices(16)) { var splitedByteArray = copySlice; if (splitedByteArray.Length != 16) { byte[] padd = new byte[16]; var startAt = 0; Array.copy(splitedByteArray,padd,startAt,splitedByteArray.Length); packetList.Add(padd); } else { packetList.Add(splitedByteArray); } } ReadByteDataFromFile(packetList[0]); } }
ReadByteDataFromFile方法:
public void ReadByteDataFromFile(byte[] packet) { try { byte[] mBuffer = new byte[24]; byte[] payload = new byte[16]; int i = 0; foreach(var bytes in packet) { payload[i++] = bytes; } CheckSumHelper checkSumHelper = new CheckSumHelper(); var ckSum = checkSumHelper.GetCheckSum(payload); mBuffer[0] = 0x02; mBuffer[1] = 0x10; mBuffer[2] = CheckSumHelper.GetBytesFromDecimal(packet[0]); mBuffer[3] = CheckSumHelper.GetBytesFromDecimal(packet[1]); mBuffer[4] = CheckSumHelper.GetBytesFromDecimal(packet[2]); mBuffer[5] = CheckSumHelper.GetBytesFromDecimal(packet[3]); mBuffer[6] = CheckSumHelper.GetBytesFromDecimal(packet[4]); mBuffer[7] = CheckSumHelper.GetBytesFromDecimal(packet[5]); mBuffer[8] = CheckSumHelper.GetBytesFromDecimal(packet[6]); mBuffer[9] = CheckSumHelper.GetBytesFromDecimal(packet[7]); mBuffer[10] = CheckSumHelper.GetBytesFromDecimal(packet[8]); mBuffer[11] = CheckSumHelper.GetBytesFromDecimal(packet[9]); mBuffer[12] = CheckSumHelper.GetBytesFromDecimal(packet[10]); mBuffer[13] = CheckSumHelper.GetBytesFromDecimal(packet[11]); mBuffer[14] = CheckSumHelper.GetBytesFromDecimal(packet[12]); mBuffer[15] = CheckSumHelper.GetBytesFromDecimal(packet[13]); mBuffer[16] = CheckSumHelper.GetBytesFromDecimal(packet[14]); mBuffer[17] = CheckSumHelper.GetBytesFromDecimal(packet[15]); mBuffer[18] = 0x17; mBuffer[19] = 0x00; mBuffer[20] = 0x00; mBuffer[21] = 0x00; mBuffer[22] = Convert.ToByte(int.Parse(ckSum,System.Globalization.NumberStyles.Hexnumber)); mBuffer[23] = 0x03; serialPort.Write(mBuffer,mBuffer.Length); } catch (Exception ex) { ExceptionHandler exceptionHandler = new ExceptionHandler(); exceptionHandler.HandleException(ex); } }
解决方法
在写完第一帧后,在循环中等待完整响应.
// Set read timeout to value recommended in the communication protocol specification // so serial port operations don't stuck. _port.WriteTimeout = 200; _port.ReadTimeout = 200; public void OnClick() { // Write first frame. _port.Write(...); // Now wait for the full response. // Expected response length. Look for the constant value from the device communication // protocol specification or extract from the response header (first response bytes) if // there is any specified in the protocol. int count = ...; var buffer = new byte[count]; var offset = 0; while (count > 0) { var readCount = _port.Read(buffer,offset,count); offset += readCount; count -= readCount; } // Now buffer contains full response or TimeoutException instance is thrown by SerialPort. // Check response status code and write other frames. }
为了不阻止UI线程,您可能仍然需要使用同步API和Task.Run().请参阅有关StackOverflow的C# await event and timeout in serial port communication讨论.
有关更多信息,请查看Kim Hamilton的Top 5 SerialPort Tips文章.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。