m1 = Timer + 2 '限定等待时间2秒,超出后转出错并结束 Do While CommExit = 0 m2 = Timer If m2 > m1 Then MsgBox "通讯线路出错!请检查线路...", vbCritical MSComm1.PortOpen = False Exit Sub End If DoEvents '交出VB事件处理控制权 Loop
'通讯被人工打断 If CommExit > 1 Then MsgBox "通讯被取消...", vbExclamation MSComm1.PortOpen = False Exit Sub End If DoEvents '交出VB事件处理控制权 WriteData (FxAddress) '数据写入"PLC数据"工作表 c = c & ErrStr '给出本轮通讯结果状态 FxAddress = FxAddress + MaxLen '映象地址迁移 If FxAddress > &HFFFF& Then MsgBox "读入工作全部完成!", vbExclamation Exit For End If DoEvents '交出VB事件处理控制权 Next MSComm1.PortOpen = False err1: End Sub
'将CommandButton2改名为CancelB,打断正在进行的通讯 Private Sub CancelB_Click() CommExit = 3 End Sub
'在串口中断中接收PLC返回的字串 Private Sub MSComm1_OnComm() Dim s Select Case MSComm1.CommEvent Case comEvReceive s = MSComm1.Input Select Case s Case Chr(6) CommEnd = 3 Case Chr(21) CommEnd = 100 End Select FxString = FxString & s If Len(FxString) >= 3 Then If Asc(Right(FxString, 3)) = 3 Then CommEnd = 5 End If End If If CommEnd > 2 Then If CommEnd = 5 Then ErrStr = "OK" Else ErrStr = "ERR" CommError = CommError + 1 Range("a1") = "出错计数:" & CommError End If CommExit = 1 End If End Select End Sub
'将PLC每次返回的数据填写在"PLC数据"工作表里 Private Sub WriteData(n As Long) Dim i&, j& Dim s$ Static Row1%, Col1% With Worksheets("PLC数据") If n = 0 Then Row1 = 2 Col1 = 0 .Range(RowCo1) = "" End If .Range(Chr(&H61 + Col1) & Row1) = Right("000" & Hex(n), 4) _ & ":" & FxString If Chr(&H61 + Col1) = "p" Then Col1 = 0 Row1 = Row1 + 1 Else Col1 = Col1 + 1 End If FxString = "" CommExit = 0 End With End Sub
'将要发向PLC的命令字串组合:加起始符02h和结束符03h,及累加校验和,返回给调用者 Private Function FxChar$(s$) Dim m%, n% Dim s1$ s1 = UCase(s) For m = 1 To Len(s1) n = n + Asc(Mid(s1, m, 1)) Next n = n + 3 FxChar = Chr(2) & s1 & Chr(3) & Right(Hex(n), 2) End Function
'设置通讯口参数后,打开通讯口 Private Sub CommPortOpen(Port%) If MSComm1.PortOpen = True Then MSComm1.PortOpen = False End If MSComm1.CommPort = Port MSComm1.Settings = "9600,e,7,1" MSComm1.RTSEnable = True MSComm1.InputMode = comInputModeText MSComm1.SThreshold = 1 MSComm1.PortOpen = True End Sub
如果仅相要PLC数据包中的有效数据,Private Sub MSComm1_OnComm()中接收可改为: =======================================================
'在串口中断中接收FX-PLC返回的字串:仅截取有用数据 Private Sub MSComm1_OnComm() Dim s Select Case MSComm1.CommEvent Case comEvReceive s = MSComm1.Input Select Case s Case Chr(2) '串起始码 Case Chr(6), Chr(21) '单应答码和出错码 CommEnd = s Case Chr(3) '串结束码 CommEnd = 1 Case Else If CommEnd Then Select Case CommEnd Case 1 To 3 '串结束码到后,再等两个校验和码 CommEnd = CommEnd + 1 Case 4 To 6 '正常结束 ErrStr = "OK" CommExit = 1 Case Is > 6 '出错结束 ErrStr = "ERR" CommError = CommError + 1 Range("a1") = "出错计数:" & CommError CommExit = 1 End Select Else FxString = FxString & s '仅串接有效数据 End If End Select End Select End Sub