串口数据接收异常:含起始符的第一部分数据未存入变量
串口分段接收时起始段丢失的问题修复
嘿,我看了你的代码和问题描述,咱们来一步步揪出问题根源:
核心问题分析
dataRxd变量作用域错误:你只提到DotFound是全局变量,但如果dataRxd是DataReceived事件里的局部变量,那每次触发串口数据接收事件时,dataRxd都会被重新初始化为空!这就导致第一次接收的带{的数据,在事件结束后直接丢失,第二次触发时只能从空开始累加,自然只有第二部分能显示出来。- 字符处理逻辑漏洞:你的代码里遇到
{时会重复添加一次该字符,而且遇到}时根本没把终止符加到dataRxd里,同时循环的索引处理也容易出错。
修复后的代码
先确保dataRxd和DotFound一样是全局变量(放在类的顶部,事件方法外面),然后重构字符处理逻辑:
' 全局变量声明,放在类的最上方 Private DotFound As Boolean = False Private dataRxd As String = "" Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived Dim portData = SerialPort1.ReadExisting() Console.WriteLine(portData & "@") ' 用For Each遍历字符,比索引操作更简洁不易错 For Each c As Char In portData Select Case c Case "}"c If DotFound Then ' 先把终止符加入数据,再输出 dataRxd &= c txtRx.Text &= dataRxd & "*" & vbLf ' 重置接收状态 dataRxd = "" DotFound = False End If Case "{"c If Not DotFound Then ' 遇到起始符,开始接收,初始化dataRxd DotFound = True dataRxd = c.ToString() End If Case Else ' 处于接收状态时,累加普通字符 If DotFound Then dataRxd &= c End If End Select Next End Sub
修复点说明
- 全局变量修正:把
dataRxd设为全局,这样分段接收的数据能在多次事件触发间保留,不会丢失起始段。 - 终止符处理:遇到
}时先把它加入dataRxd,保证你拿到的是完整的{...}数据包。 - 避免重复添加:遇到
{时直接初始化dataRxd为该字符,不会像原来那样重复添加两次。 - 简化遍历逻辑:用
For Each和Select Case让代码逻辑更清晰,减少索引操作可能带来的错误。
用这个代码测试你的示例数据:第一次接收{FF2D035482时,dataRxd会保留{FF2D035482;第二次接收08027915807487}时,会把后续字符累加进去,最后遇到}时输出完整的{FF2D03548208027915807487}到文本框里。
内容的提问来源于stack exchange,提问作者AngeSS
相关产品推荐
相关产品推荐

