用FX-PLC编程口通讯电缆遍历读PLC的映象区 FX-PLC的编程口通讯协议只有几个命令,这就是"0,1,7,8"(读/写/强制位ON/强制位OFF), 它以PLC内部映象地址为操作对象,所有元件地址都从一张映象地址表中换算出来,包括用户 程序。 它属于低层操作协议,有最强大的功能,诸如元件读写、强制位元件、程序读写、密码读 写、非连续地址通讯时用的指针队列读写....有厂家编程软件所提供的全部功能(它也是 通过编程口与PLC连接的)。在上位机独占PLC的直连条件下,是一种最得心应手的通讯方 法。
本人尝试在Execl电子表格中编程,遍历读出FX-PLC的全部映象地址里的数据和它的状态 ,当然它包含了PLC的全部元件区和用户程序区(PLC密码在程序区内)了。
具体做法: 1. 在新建的XLS文档里,命名一个“遍历读FXPLC”和一个“PLC数据”工作表。 2. VBA程序全部放在与“遍历读FXPLC”工作表对应的代码区内,工作表的第一行放3个控件 ,一个MSCOMM通讯控件和两个命令按钮。这里要说明的是,用户在安装了VB6.0后才可使用 MSCOMM控件,当然可以在自有 MSCOMM32.OCX 时自行注册后使用。 MSCOMM控件的引用: 在Exexl的菜单栏中点击: 视图 -> 工具栏 -> 控件工具箱, 将它拖到工具栏上或其它合 适的位置. 点击控件工具箱工具上的"查看代码"按钮,进入代码编辑区,再点击VB编辑器的菜单栏中的: 工具 -> 引用,在"可使用的引用" 区中寻找"MSCOMM32.OCX"控件并选中它。如找不到,点 击"浏览"按钮,在Windows的系统文件区(system/system32)可找到它, 注意在文件类型栏 中应选"ActiveX控件(*.OCX)",找到"MSCOMM32.OCX"文件后点击选择,退出。 3.返回Execl编辑器,点击控件工具箱上的"其它控件"按钮,在它的菜单栏中选中: Microsoft Chart Control, version 6.0 或: Microsoft Communications Control, version 6.0 把这个电话机图标安放在"遍历读FXPLC"工作表的第一行上,它的缺省名为MSComm1 再在控件工具箱拖放两个命令按钮放到第一行:CommandButton1和CommandButton2, 给按钮分别命名为"开始测试"和"打断操作"。 4.说明:"遍历读FXPLC"工作表从第二行起由程序自动填写每次操作的状态,如:"0000:OK", 表示读映象地址0000区时得到了正确的数据,而“8000:ERR”则表示在读8000h映象地址 时出错。 "PLC数据"工作表由程序自动填写由PLC返回的对应数据,如"8000:XXXXXXX.....",它表示 PLC返回8000h首地址开始的完整数据(含起始符、结束符和校验码)。 程序开始运行后,整个读入过程大约需时10-15分钟。 5.下面就可以在"遍历读FXPLC"的代码区编制代VB代码了。
'操作状态CommExit: 0=通讯进行状态,>1=通讯被打断 '通讯状态CommEnd:0=开始发送和等待接收,>1:接收串已结束 'CommError=通讯出错计数 'FxAddress=PLC映象地址计数 'FxString=存放每次PLC返回的应答串 'ErrStr=每串操作的结果提示,"OK" 或 "ERR" 'RowCo1=每次操作结果放在电子表格的填充区域 Public CommExit%, CommEnd% Public CommError&, FxAddress& Public FxString$, ErrStr$, RowCo1$ '将CommandButton1改名为Beginning,开始测试 Private Sub Beginning_Click() Dim c As Range Dim m1, m2 Dim s$, s1$, MaxLen& On Error GoTo err1 CommPortOpen 1 '设置串口参数和打开端口 CommExit = 0 CommError = 0 Range("A1") = "" Range(RowCo1) = "" FxAddress = 0 RowCo1 = "a2:p257" '操作结果填写在表格的区域 MaxLen = 16 '每次读PLC映象的字节数 '遍历读FX-PLC映象区 For Each c In Range(RowCo1) '命令串转换 s = "0" & Right("000" & Hex(FxAddress), 4) & Hex(MaxLen) '指示正在读入的区域 c = Right("000" & Hex(FxAddress), 4) & ":" '清接收区残余数据,和发命令 s1 = MSComm1.Input MSComm1.Output = FxChar(s) FxString = "" '清接收区 CommEnd = 0 '置发送状态 c.Select '焦点指向当前单元格 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
[此贴子已经被作者于2006-9-2 18:40:50编辑过] |