串口通讯程序,当串口数据突然中断时,程序老是卡死,如何解决啊,谢谢!

qq_37336946 2017-07-17 01:01:17

Private Sub MSComm1_OnComm()



Select Case MSComm1.CommEvent '判断MSComm1 通信事件
Case comEvReceive '收到Rhtreshold 个字节后产生接收事件

'///////////////中断程序开始///////////////////////////////////////////////////////////////////////////////////


Static sz(900) As String
Static a As Integer
Static b As Integer
Static i As Integer
Static Temp As String
Static Temp1 As Integer
Static add As Double
Static pi_data As Integer

pi_data = 140


If MSComm1.CommEvent = comEvReceive Then Temp = MSComm1.Input

Temp1 = Asc(Temp)

If Temp = "$" Then
a = 0: MSComm1.InBufferCount = 0

Text4.Text = "$"
Else
a = a + 1
Text4.Text = Text4.Text + Temp
sz(a) = Temp

End If

If Temp1 <> 13 And Temp1 <> 32 And Temp1 <> 36 Then
If Temp1 > 57 Or Temp1 < 48 Then a = 0
End If


If Text4.Text = "$at1" + vbCr Then Beep: a = 0: Text4.Text = "": f = MsgBox("电机有逻辑顺序", , "控制盒准备情况"): Check10.Value = 0: Check11.Value = 0
If Text4.Text = "$at0" + vbCr Then Beep: a = 0: Text4.Text = "": f = MsgBox("电机无逻辑顺序", , "控制盒准备情况"): Check10.Value = 0: Check11.Value = 0


If Text4.Text = "$atA" + vbCr Then Beep: a = 0: Text4.Text = "": f = MsgBox("控制盒准备就绪", , "控制盒准备情况"): Check10.Value = 0: Check11.Value = 0
If Text4.Text = "$atB" + vbCr Then Beep: a = 0: Text4.Text = "": f = MsgBox("数据写入成功", , "数据写入情况"): Check10.Value = 0: Check11.Value = 0
If Text4.Text = "$atC" + vbCr Then Beep: a = 0: Text4.Text = "": f = MsgBox("控制盒将重启", , "控制盒准备情况"): Check10.Value = 0: Check11.Value = 0: If Text2.Text = "416" Then MSComm1.Settings = 19200
If Text4.Text = "$atD" + vbCr Then Beep: a = 0: Text4.Text = "": f = MsgBox("控制盒需要解锁", , "控制盒准备情况"): Text15.Text = Text27.Text: Call send_data(Text15.Text, Text2.Text): Check10.Value = 0: Check11.Value = 0: Command1.Visible = True
If a >= pi_data Then a = 0: Text3.Text = "": Text4.Text = ""
If a >= (pi_data - 1) And Temp = vbCr Then
Text3.Text = Text4.Text


b = 0
For i = 1 To (pi_data - 8)
b = b Xor Val(sz(i))


If Val(Mid(Text3.Text, (pi_data - 7), 5)) = b Then

Text5.Text = Mid(Text3.Text, 2, 6)
Text6.Text = Mid(Text3.Text, 8, 6)
Text7.Text = Mid(Text3.Text, 14, 6)
Text8.Text = Mid(Text3.Text, 20, 6)
Text9.Text = Mid(Text3.Text, 26, 6)
Text10.Text = Mid(Text3.Text, 32, 6)
Text11.Text = Mid(Text3.Text, 38, 6)
Text12.Text = Mid(Text3.Text, 44, 6)
Text13.Text = Mid(Text3.Text, 50, 6)
Text14.Text = Mid(Text3.Text, 56, 6)

Text16.Text = Mid(Text3.Text, 62, 6)
Text17.Text = Mid(Text3.Text, 68, 6)
Text18.Text = Mid(Text3.Text, 74, 6)
Text19.Text = Mid(Text3.Text, 80, 6)
Text20.Text = Mid(Text3.Text, 86, 6)
Text21.Text = Mid(Text3.Text, 92, 6)


Text22.Text = Mid(Text3.Text, 98, 6)
Text23.Text = Mid(Text3.Text, 104, 6)
Text24.Text = Mid(Text3.Text, 110, 6)
Text25.Text = Mid(Text3.Text, 116, 6)
Text26.Text = Mid(Text3.Text, 122, 6)
Text27.Text = Mid(Text3.Text, 128, 6)



'文件保存开始////////////////////////////////////////////////////////////
If Check1.Value = 1 Then
fFile = FreeFile:
Open "f:\老化\tx1.txt" For Append As fFile
Write #fFile, Now; Text3.Text
Close fFile

End If

'/文件保存结束///////////////////////////////////////////////////////////

End If

Next i
End If


'///////////////中断程序结束///////////////////////////////////////////////////////////////////////////////////


End Select
End Sub
...全文
4475 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-07-21
  • 打赏
  • 举报
回复
引用 13 楼 of123 的回复:
程序架构的问题。你在事件中加入 For 循环,如果在这中间通讯中断,必死无疑。 改成状态机架构。你的接收事件根据状态进行数据处理。
qq_37336946 2017-07-19
  • 打赏
  • 举报
回复
谢谢学长,我来改改看,
of123 2017-07-19
  • 打赏
  • 举报
回复
程序架构的问题。你在事件中加入 For 循环,如果在这中间通讯中断,必死无疑。 改成状态机架构。你的接收事件根据状态进行数据处理。
of123 2017-07-19
  • 打赏
  • 举报
回复
引用 5 楼 qq_37336946 的回复:
MsgBox关掉也是一样的,似乎不是这个问题
是不是也得去掉,哪有通讯中插入人机界面操作的?
笨狗先飞 2017-07-18
  • 打赏
  • 举报
回复
http://download.csdn.net/detail/bakw/9902081 改得好累啊,设计思路不同,估计还是不能用的。。。。
qq_37336946 2017-07-18
  • 打赏
  • 举报
回复
在家好,我把程序 的下载连接发上来,感谢大家 http://yun.baidu.com/xcloud/csdn/pan/share/link?shareid=1253483664&uk=2042050637
舉杯邀明月 2017-07-17
  • 打赏
  • 举报
回复
引用 8 楼 qq_37336946 的回复:
如何上传压缩文件啊,我想把整个文件打包,传上来让大家看看,谢谢!

你登录后,在“CSDN论坛首页”左上角,有个“CSDN网盘”(其实是百度提供的),
你“点进去”后,新建一个文件夹,再把你打包的工程上传到里面,
然后进行“分享”,把分享链接贴出来,别人就可以下载、测试了。
qq_37336946 2017-07-17
  • 打赏
  • 举报
回复
如何上传压缩文件啊,我想把整个文件打包,传上来让大家看看,谢谢!
zdingyun 2017-07-17
  • 打赏
  • 举报
回复
严格按照通信协议和数据帧约定编写代码,完整接收后判断进入数据处理。 MscComm属性Rhtreshold设置=1。 以下是应用于某个工业控制上位机的OmComm事件代码。
Private Sub ctrMSComm_OnComm()
Dim bytInput  As String
Select Case frmMain.ctrMSComm.CommEvent
    Case comEvReceive
        If blnReceiveFlag Then
            If Not frmMain.ctrMSComm.PortOpen Then
                frmMain.ctrMSComm.CommPort = intPort
                frmMain.ctrMSComm.Settings = strSet
                frmMain.ctrMSComm.PortOpen = True
            End If
        '此处添加处理接收的代码
            bytInput = frmMain.ctrMSComm.Input
            strRec = bytInput '
            Text2 = strRec
            jscd = Len(Text2)
            If Left(bytInput, 1) <> Chr(27) Or jscd > 21 Then '
                 fuweiTimer.Enabled = True
                FrmRun.Label7.BackColor = vbRed
                FrmRun.Label7.ForeColor = vbWhite
                FrmRun.Label7.Caption = "接收信号出错!"
                frmMain.Label3.BackColor = vbRed
                frmMain.Label3.ForeColor = vbWhite
                frmMain.Label3.Caption = "接收信号出错!"
            ElseIf Left(bytInput, 1) = Chr(27) And Mid(Text2, 21, 1) = Chr(13) Then
                Dim i As Long
                Dim sumLng As Long
                Dim sumLng1 As Long
                For i = 2 To Len(strRec) - 3
                    sumLng = sumLng + Asc(Mid(strRec, i, 1))
                Next
                sumLng1 = Val("&H" & Mid(strRec, Len(strRec) - 2, 2))
                If (sumLng Mod 256) = sumLng1 Then
                    frmMain.Label3.BackColor = vbGreen
                    frmMain.Label3.ForeColor = vbBlack
                    frmMain.Label3.Caption = "接收信号正常!"
                    FrmRun.Label7.BackColor = vbGreen
                    FrmRun.Label7.ForeColor = vbBlack
                    FrmRun.Label7.Caption = "接收信号正常!"
                    If Left(bytInput, 6) = Chr(27) & "R0032" And jscd = 21 Then
'                        If Val(fa2) >= 0 And Len(fa2) = 4 Then
'                            'fa2 = "0" & Mid(fa2, 2, 3)
'                        End If
                        If FrmProgInput.Option1.Value = True Then
                            txtSend = gy_ml
                            lenTxtSend = Len(txtSend) '
                            If lenTxtSend = 129 Then
                                Call commFasong
                            End If
                        Else
                            txtSend = fa0 & fa1 & fa5 & zhenkong & fa2 & fa3 & fa4    '& Chr(13)
                            lenTxtSend = Len(txtSend)
                            If lenTxtSend = 25 Then
                                Call commFasong
                            Else
                                FrmRun.Label7.BackColor = vbRed
                                FrmRun.Label7.ForeColor = vbWhite
                                FrmRun.Label7.Caption = "发送信号出错!"
                                frmMain.Label3.BackColor = vbRed
                                frmMain.Label3.ForeColor = vbWhite
                                frmMain.Label3.Caption = "发送信号出错!"
                            End If
                        End If
                        blL1 = Mid$(bytInput, 11, 2)
                        If blL1 = "01" Then
                            record_jmm(0) = Format(pcsz_sj(0) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '板程温度
                        ElseIf blL1 = "02" Then
                            record_jmm(1) = Format(pcsz_sj(1) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '02捕水器1温度*
                        ElseIf blL1 = "03" Then
                            record_jmm(2) = Format(pcsz_sj(2) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '03捕水器2温度*
                        ElseIf blL1 = "04" Then
                            record_jmm(3) = Format(pcsz_sj(3) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '04捕水器3温度*
                        ElseIf blL1 = "05" Then
                            record_jmm(12) = Format(pcsz_sj(5) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '11捕水器4温度*
                        '15 2010-03-16
                        ElseIf blL1 = "06" Then
                            record_jmm(16) = Format(pcsz_sj(6) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '制品2温度*
                        ElseIf blL1 = "07" Then
                            record_jmm(6) = Format(pcsz_sj(7) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '制品3温度*
                        ElseIf blL1 = "08" Then
                            record_jmm(7) = Format(pcsz_sj(8) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '制品4温度*
                        ElseIf blL1 = "09" Then
                            record_jmm(8) = Format(pcsz_sj(9) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '制品5温度*
                        ElseIf blL1 = "10" Then
                            record_jmm(9) = Format(pcsz_sj(10) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '制品6温度*
                        ElseIf blL1 = "11" Then
                            record_jmm(4) = Format(pcsz_sj(4) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") ''制品1温度*
                        ElseIf blL1 = "12" Then
                            record_jmm(13) = Format(pcsz_sj(11) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '14制品7温度*
                        ElseIf blL1 = "13" Then
                            record_jmm(14) = Format(pcsz_sj(12) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '15制品8温度*
                        ElseIf blL1 = "14" Then
                            record_jmm(15) = Format(pcsz_sj(13) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '16制品9温度*
                        '06 2010-03-16
                        ElseIf blL1 = "15" Then
                            record_jmm(5) = Format(pcsz_sj(14) * -1 + Val(Mid$(Text2, 13, 4)) / 10, "##.0") '17制品10温度*
                        ElseIf blL1 = "17" Then
                            record_jmm(10) = pcsz_sj(16) * -1 + Val(Mid$(Text2, 13, 4)) '11干箱真空*
                        ElseIf blL1 = "18" Then
                            record_jmm(11) = pcsz_sj(17) * -1 + Val(Mid$(Text2, 13, 4)) '12捕水器真空*
                        End If
                        FrmRun.Label2(0).Caption = record_jmm(0) & "℃" '板程温度ok       01

                        FrmRun.Label2(12).Caption = record_jmm(12) & "℃" ''捕水器4温度*  05
                        FrmRun.Label2(13).Caption = record_jmm(13) & "℃" '制品7温度
                        FrmRun.Label2(14).Caption = record_jmm(14) & "℃" '制品8温度
                        FrmRun.Label2(15).Caption = record_jmm(15) & "℃" '制品9温度
                        FrmRun.Label2(16).Caption = record_jmm(16) & "℃" '制品10温度      06
                        frmDazixs.Label1(0).Caption = record_jmm(3) & "℃"
                        frmDazixs.Label1(1).Caption = record_jmm(4) & "℃"
                        frmDazixs.Label1(2).Caption = record_jmm(5) & "℃"
                        frmDazixs.Label1(3).Caption = record_jmm(6) & "℃"
                        frmDazixs.Label1(4).Caption = record_jmm(0) & "℃"
                        frmDazixs.Label1(5).Caption = record_jmm(10) & "Pa"
                        record_jm(0) = Val(record_jmm(0)) '板程温度
                        record_jm(1) = Val(record_jmm(1)) '捕水器温度1

                        record_jm(11) = Val(record_jmm(11)) '捕水器真空
                        record_jm(12) = Val(record_jmm(12)) '制品温度7
                        record_jm(13) = Val(record_jmm(13)) '制品温度8
                        record_jm(14) = Val(record_jmm(14)) '制品温度9
                        record_jm(15) = Val(record_jmm(15)) '制品温度10
                        record_jm(16) = Val(record_jmm(16)) '捕水器4温度
                        record_jm(17) = Val(record_jmm(17)) '备用
                    ElseIf Mid(bytInput, 2, 1) = "U" And jscd = 21 Then '?疑为"U"   2010126
                        blL = Mid$(bytInput, 3, 9)
                        If blL <> blLOld Then
                            'Call Hex_bin '输出口状态鉴别
                            Call ZT_Panbie '输出口状态鉴别
                        End If
                        blLOld = blL
                        blLg = Mid$(bytInput, 12, 7)
                        If blLg <> blLgOld Then
                            Call hex_bin1 '输出口故障状态鉴别
                        End If
                        blLgOld = blLg
                        FrmRun.Text8 = blLgOld
                        txtSend = ""
                    ElseIf Mid(bytInput, 2, 3) = "W60" And jscd = 21 Then
                        txtSend = gy_ml
                        lenTxtSend = Len(txtSend)
                        If lenTxtSend = 129 Then
                            Call commFasong
                        End If
                    ElseIf Mid(bytInput, 2, 1) = "D" And jscd = 21 Then '2011129修改
                        riqi_run = Mid(bytInput, 6, 6)
                        Debug.Print riqi_run
                        'frmMain.txtSend = "Date" & riqi_run & gongyi_sj(0) & "123"
                        Unload frmchaxunRun
                        FrmRun.Text3 = "20" & Mid(riqi_run, 1, 2) & "-" & Mid(riqi_run, 3, 2) & "-" & Mid(riqi_run, 5, 2)
                        frmRef.Timer1.Enabled = False
                        Open App.Path & "\data\riqi_run.txt" For Output As #2
                            Print #2, riqi_run
                        Close
                        record_rq = riqi_run
                        SUM0 = 0
                        Open App.Path & "\data\zt2.txt" For Output As #2
                            Print #2, SUM0
                        Close
                        sum = 0
                        Unload frmRef
                        Load frmchaxunRun
                   End If
                End If
            End If
            If Not blnAutoSendFlag And Not blnReceiveFlag Then
                frmMain.ctrMSComm.PortOpen = False
            End If
        End If
    End Select
End Sub
zdingyun 2017-07-17
  • 打赏
  • 举报
回复
串口应该按数据帧完整接收后判断进入数据处理。
qq_37336946 2017-07-17
  • 打赏
  • 举报
回复
MsgBox关掉也是一样的,似乎不是这个问题
zdingyun 2017-07-17
  • 打赏
  • 举报
回复
注释掉所有的MsgBox语句,此类中断不宜在MsComm控件的OnComm时间中使用,会干扰串口正常的通信,属于没事找事。 串口应该按数据帧完整接收后判断进入数据处理。
笨狗先飞 2017-07-17
  • 打赏
  • 举报
回复
我也没试过,不知道灵不灵,看看能不能设置超时

Private Type COMMTIMEOUTS
        ReadIntervalTimeout As Long
        WriteTotalTimeoutConstant As Long
        ReadTotalTimeoutConstant As Long
        WriteTotalTimeoutMultiplier As Long
        ReadTotalTimeoutMultiplier As Long
End Type

Private Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long

Private Sub Form_Load()
  Dim lpCommTimeouts As COMMTIMEOUTS

    ... ... ... ...

    MSComm1.PortOpen=True    
'设定通讯超时参数,ms,这段代码加在MSComm1.Open=True之后
    lpCommTimeouts.ReadIntervalTimeout = 2
    lpCommTimeouts.ReadTotalTimeoutConstant = 4
    lpCommTimeouts.ReadTotalTimeoutMultiplier = 3
    lpCommTimeouts.WriteTotalTimeoutConstant = 5000 '一次写入串口数据的固定超时。
    lpCommTimeouts.WriteTotalTimeoutMultiplier = 50 '写入每字符间的超时。
    SetCommTimeouts MSComm1.CommID, lpCommTimeouts

    ... ... ... ...

End Sub
qq_37336946 2017-07-17
  • 打赏
  • 举报
回复
希望有人可以解决,多谢!
笨狗先飞 2017-07-17
  • 打赏
  • 举报
回复
Rhtreshold调到1,然后在oncomm事件里把数据收完整再出去。 其实就一个通讯超时的问题,字节没有收完整不触发oncomm事件,不知道哪里设置。

1,451

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧