VS2010 調試時串口接收換行正常,實際運行變成「隔幾個字符換行」,一條數據被拆成多行。
// DataReceived 事件中
data = serialPort1.ReadExisting(); // 讀取當前緩衝區所有字符
data += "\r\n"; // 無條件添加換行
this.Invoke(new EventHandler(DisplayText));
ReadExisting 返回「當前時刻緩衝區內所有字符」。DataReceived,每次可能只讀到幀的一部分(甚至幾個字節) → 顯示邏輯對每次讀取結果強制加換行 → 數據被碎片化換行。private StringBuilder rxBuffer = new StringBuilder(); // 成員變量持久化緩衝
void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) {
int bytes = serialPort1.BytesToRead;
byte[] buf = new byte[bytes];
serialPort1.Read(buf, 0, bytes);
rxBuffer.Append(Encoding.ASCII.GetString(buf)); // 或具體編碼
// 解析完整幀(以 \r\n 結尾為例)
while (true) {
int idx = rxBuffer.ToString().IndexOf("\r\n");
if (idx < 0) break; // 未收到完整幀
string frame = rxBuffer.ToString(0, idx + 2); // 含結尾
rxBuffer.Remove(0, idx + 2);
// 將完整幀拋給 UI 線程顯示
this.BeginInvoke(new Action(DisplayFrame), frame);
}
}
void DisplayFrame(string frame) {
txtReceive.AppendText(frame); // frame 已含換行,無需再加
}
BeginInvoke 異步拋送,避免阻塞接收線程。DisplayFrame 中統一轉換,不在接收邏輯混雜。DataReceived 記錄 bytes, buf[0..3] 到文件,對比調試/運行差異。**串口通信核心:流式字節流 → 幀邊界識別 → 業務解析。**