|
|
发表于 2009-5-17 23:42:53
|
显示全部楼层
来自: 中国北京
三菱的PLC可以直接和电脑通信,软件要自己设计。* q s7 w# g6 n& Q9 a$ K
PC与PLC通讯程序的设计。此部分的开发设计较难,需要掌握PC和PLC的有关通讯硬件驱动和通讯协议的知识。但对于小型控制系统来说,主要通过PC串口来通讯,所以通讯程序设计的关键是如何利用Visual Basic 6.0中的串口通信控件——MSComm控件,并根据PLC的串口通信协议设计出上下位机的数据交换程序。* S* O+ V3 s' Z+ F2 b
PC与PLC通讯程序设计分析3 O4 a+ x: x+ w+ H8 u
在分析具体的VB通讯程序之前,先要介绍有关VB串口通信控件MSComm的应用知识和三菱PLC 通讯协议。9 R8 r! o: C; I! h7 ]
1. MSComm控件简介" B$ A+ G2 v0 X/ J0 v
如图所示是Mscomm控件的图标。0 ^; `6 f6 A# P9 b7 G/ h! l# X! ~0 X
它可以用来提供简单的串行端口通信功能,也可以用来创建功能完备、事件驱动的高级通信工具。 Mscomm控件提供了一系列标准通信命令的使用界面。使用它可以建立与串行端口的连接,通过串行端口再连接到其它设备(如调制解调器、PLC),发出命令,交换数据,以及监视和响应串行连接中发生的事件和错误。
# k0 K$ V7 B# t5 {4 Q! \- q2. MSComm控件的基本属性( d' k# r+ r3 j# E
MSComm 控件有很多重要的属性,基本属性如下:
4 X: s& a) `0 T$ b" B$ z( S属性 描述
8 }0 a7 i, G8 g3 X, A3 tCommPort 设置并返回通讯端口号。 ' D! D# u d% ~
Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。
4 I9 N* E1 B3 ~& }PortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。
$ _2 L: z6 D! L8 FInput 从接收缓冲区返回和删除字符。
& W0 } c! U- B; ^8 J lOutput 向传输缓冲区写一个字符串。: |& x% T" D" ~, x" B& F% c
如下程序打开串行端口COM1. p& i2 y, I$ o9 L0 R
MSComm1.CommPort = 1 使用 COM1 & U! a: W. S7 a- A5 _
MSComm1.Settings = "9600,N,7,1" 9600波特率,无奇偶校验,7位数据,一个停止位。) y1 v. ?2 D- c
MSComm1.PortOpen = True ''打开端口,开始通信。, w: @7 ?. p9 G
3. MSComm控件的通信方式
7 |- n: B+ `) `( ~通信控件有2种不同的方式来处理和解决各类通信软件的开发和设计问题。
1 ~" o; W6 X( h9 f(1) 事件驱动
r8 [% q( F$ `7 J2 L8 o事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如:当线路数据到达本端或CD线和RTS信号线状态发生变化时,要求我们使用相应的事件来跟踪和出理。在这些情况下, Mscomm控件将触发OnComm事件,CommEvent属性值也将被改变。所以在OnComm事件中读取CommEvent属性值就可以检测和处理通信错误等方面的问题。$ g. z8 I. K$ E3 j. J
(2)查询方式
+ n2 S* A9 [8 v' I4 `, M$ O利用定时器控件Timer,我们可以设计程序每隔一段时间去读取CommEvent的值并处理所发生错误和事件。
$ V2 G1 y2 q$ q6 p. D( I4. 本实例中采用的通讯方式
9 r# F4 ]* E' `' |在本例子中,PC与PLC 采用无握手协议的串行通信,它们只用两根数据线 TD和RD、一根信号地线连接,数据通信采用查询方式。根据系统功能要求,PC需发送两种类型的命令:+ l# c V( l: F$ M- M m/ Y
(1) 周期性命令,它由定时器触发引起,每隔0.5秒发送一次。用它来向PLC查询实时显示的数据。如酒、水的瞬时流量,调节阀开度等。' }( v+ b8 @3 t+ p
(2) 非周期性命令,它由操作者按动命令按钮引起,非周期性发送。用它来传送输入参数、操作命令给PLC 。+ j. \& n ~# i, Z& e7 n
在啤酒稀释的人机操作界面中,有运行时不可见的通信控件(MSComm1)一个、定时器控件一个Timer1。通信控件(MSComm1)用于初始化串口数据并打开串口;定时器控件(Timer1)用于每隔0.5秒执行通讯命令,把查询命令从 PC发送到PLC,同时接收PLC返回的应答数据。设计通讯数据的发送和查询功能,必须掌握PLC所遵循的通讯协议。
( E9 v, T! U9 f @+ K5 W: K5. 三菱FX系列PLC通讯协议) v0 x' [% v b+ C& d
三菱FX系列PLC共有四种通信模式,本实例采用的是PLC与计算机专用协议通信方式(无须PLC编程,电脑直接读写操纵PLC),其通讯命令字和通讯格式介绍如下:$ o1 l; q- H9 o2 x: l
PC发送给PLC的通信命令字
7 m+ S: }% Z$ q8 v5 N& i, `命令字 注释
/ ~9 p" L" U8 {5 u# g2 O {2 eBR 以1点为单位,读出位元件的状态! K; H0 P! P& Z Z) a% E
WR 以16点为单位,读出位元件的状态,或以1字为单位,读出字元件的值
/ |; B6 \6 T& c! EBW 以1点为单位,写入位元件的状态
# y# C9 B3 [7 l3 uWW 以16点为单位,写入位元件的状态,或以1字为单位,写入值到字元件6 j( }! V* U& r* w
BT 以1点为单位,设置/复位 位元件9 ?9 S0 Q1 w1 T+ V b7 X
WT 以16点为单位,设置/复位 位元件,或以1字为单位,写入值到字元件7 l7 N. Z$ u7 A* h" X
RR 控制PLC运行RUN3 G% b& k8 \" Z. f" V
RS 控制PLC停止STOP
4 R O }6 R! Q; APC 读出PLC设备类型* s5 C# o9 D1 b3 Z, n
TT 连接测试
1 r9 A7 D6 Z( O* R7 h. M fPC发送给PLC的通信命令格式
) D; D \& Z# t$ X+ ?约定说明:ENQ为请求标志,ASCII值5,VB中以chr(5)表示;
4 r3 ~; K X4 p ACK为正确标志,ASCII值6,VB中以chr(6)表示;
' B* j. N) _ ~5 x) v3 ] STX为请求标志,ASCII值2,VB中以chr(2)表示;; i) H' m+ m) ~+ u) u$ s2 I
EXT为请求标志,ASCII值3,VB中以chr(3)表示; ' ^1 S9 R# \9 Y i2 I
表格中粗体字为需要求和效验的部分;2 x8 q! r6 k7 g" _7 D
和效验为每一项的ASCII值的总和转换成十六进制后,取其低两位;
9 y! ^8 o+ z- L7 `% R 站号、PLC号、元件数量、和效验都是以十六进制表示;
3 D7 c0 k8 B0 Y$ g" b: Z 等待延时为0-150毫秒,以十六进制0H-FH表示,如100ms为AH。
% K- d4 M, g5 q1 C4 L1) 批量读出位元件—BR指令格式
% z4 _) T& z" u$ m2 ^8 ^- k( Q1 2 3 4 5 6 7 8 15 16 17+ o! X c' [8 ~ y
PC侧: ENQ 站号 PLC号 BR 延时 首地址 数量 和校验 ACK 站号 PLC号
$ |! f$ b! {" |; _$ r7 q! E }% KPLC侧: STX 站号 PLC号 数据 EXT 和校验 " |6 R3 e' |+ f5 T* ^" j+ P4 K3 q
9 10 11 12 13 14
8 u [$ L& }6 x& |0 j例如:要读出站号为5的PLC的X40到X44共5点的状态值,延时100毫秒,假设PLC中X40与X43为OFF,其余为ON,则指令数据如下:
8 M; |7 o' r- E& _注释: 请求 站号 PLC号 命令 延时 元件首地址 元件数量 和校验% |/ ^& |0 h f( ^' ~) ]
代码: ENQ 0 5 F F B R A X 0 0 4 0 0 5 4 75 ^" U! E& A T% Y, b' c2 M
ASCII码: 05H 30H 35H 46H 46H 42H 52H 41H 58 30H 30H 34H 30H 30H 35H 34H 37H4 }7 A( y8 K+ H0 {4 G
只要将以上代码以字符串形式(VB中可以表示为chr(5)&”05FFBRAX00400547”)发送到PLC,就会有正确的回应信息,如下:8 k U( l w8 m) _
注释: 头 站号 PLC号 位元件状态值 尾 和校验
. V* B: f7 N9 t7 c/ U7 X代码: STX 0 5 F F 0 1 1 0 1 EXT E 7
3 }- Q! u O9 a+ B0 @0 eASCII码: 02H 30H 35H 46H 46H 30H 31H 31H 30H 31H 03H 45H 37H0 `+ @1 H+ k. ^) @
2) 批量读出字元件—WR指令格式. z$ l8 f6 ]( ?/ ?- Z
1 2 3 4 5 6 7 8 15 16 17
- b/ \: F1 y( X. M, v9 |" J$ V5 Z# u, ]PC侧: ENQ 站号 PLC号 WR 延时 首地址 数量 和校验 ACK 站号 PLC号7 w& F; S, c1 c" b4 w1 s/ \
PLC侧: STX 站号 PLC号 数据 EXT 和校验 ) Z' S! N3 x. P/ g1 ?0 K9 |; k
9 10 11 12 13 14
# I% m9 d( P R8 k7 W该命令使用与BR命令相同。) \* N% x2 Q7 n0 o3 g
3) 批量写入位元件—BW指令格式 0 R4 z( ]- Y- V# r; s7 w
1 2 3 4 5 6 7 8 9 - d" n. I1 w, M. Q% @
PC侧: ENQ 站号 PLC号 BW 延时 首地址 数量 写入值 和校验
# [ W! ~! R- Q4 @- O# j& r5 ^PLC侧: ACK 站号 PLC号
% o3 Q6 H. [( |# d/ y 10 11 128 O6 o/ O+ O1 C4 e' O( Z2 W
4) 批量写入字元件—WW指令格式! ?2 [3 c* ]* m; I
1 2 3 4 5 6 7 8 9 4 T" F6 [: ]) B" z* z
PC侧: ENQ 站号 PLC号 WW 延时 首地址 数量 写入值 和校验 ) y, U6 f" O, C
PLC侧: ACK 站号 PLC号
3 W" w, E: h) g1 `$ D! i 10 11 12* J! @, \) _5 b8 w% L( w- H
6. VB通讯功能块设计分析
7 ^. `' h% Z1 E1 y根据三菱PLC的通讯指令格式,在PC中编写数据查询功能块RevData( )和数据发送功能块SendData( ),就可以在定时中断处理块TIMER1( )中调用查询功能块RevData( ),实现PC界面数据定时刷新;在每一次操作命令执行时,调用数据发送功能块SendData( ),把控制值写入PLC中,从而实现控制。下面给出这两个功能块的设计程序。! q2 V8 k# x6 X- T) F
1) 查询数据函数RevData( )
' L \1 Y# q8 B" j3 g Z& k5 e(没有和校验)' u: {0 a1 |6 D
Sub RevPLC (iNo As String, iType As String, iAdd As String, iNum As String)
) j0 @8 o. U! n- _'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量9 \" Q9 q4 V# ^
Dim Stmp As String1 v* R4 ?6 N* f3 T% Q' p
Dim cha, j As Integer% w) U% r/ [% g. K! z- C3 g
Dim ChaCount As Integer
2 n5 i$ r7 j! H- X* XDim Comm As String
1 Z; q' s8 n& R+ p ]' VSelect Case iType
' Z/ i- }1 H5 q2 k" hCase "D" ''查询数据寄存器的值! i2 w% J$ J. W+ H! v
Comm = "WR" ''命令类型:数据字读
: J/ E4 c X# R4 g( K+ ycha = Val("&H" & iNum) * 4 ''数据寄存器的值为十六进制表示,占4个字符& k" Y# U* j' `' W! R. {9 q% f1 p9 k, G
Case "M", "X", "Y" ''查询继电器触电的值) O9 I7 J" U3 @) ?% A' }
Comm = "BR" ''命令类型:二进制位读
0 P, Y. m4 J" T, ^" c' ycha = Val("&H" & iNum). J& Y/ N' P; A
End Select$ a1 T( E! [. n* b3 e: l* K
iAdd = Right$("000" & iAdd, 4)
* m6 h5 a' W2 g8 T1 L8 ~# {3 I* fiNum = Right$("0" & iNum, 2)
& c$ [9 o7 q9 lStmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum ''输出命令格式7 H0 q/ ^9 c% @$ L5 ]
ChaCount = 6 + cha ''要返回字符个数
( X! S& v. B# x' ] u: lmain.MSComm1.InBufferCount = 0 ''输入缓冲区清零
& \% Q1 k5 I. s; }main.MSComm1.Output = Stmp ''设传送缓冲区内容为命令格式
$ \, g3 {1 T+ F! iNow=Second()3 n4 W3 `! V& y+ {+ G* n3 S, l0 H
Do
/ y! o% r8 O) w. g ?. h- S( b v XDoEvents ''转让控制权,以便让操作系统进行数据传输
, K( ^5 b. K! P$ [+ B3 vIf Second()-Now>1 Then Exit Sub
% ^1 ]& ^ \* c3 f* u4 X6 ALoop Until main.MSComm1.InBufferCount = ChaCount ''当接收到规定字符时停止循环- r& i8 d" r0 r3 }6 h: W# d# D
RevDataTmp = Mid$(main.MSComm1.Input, 6, cha) ''返回数据字符串保存在全局变量
: s+ P9 L; M" X+ z7 v% t I''RevDataTmp中0 h! s, e7 U9 j4 M: G
End Sub
/ F1 C5 e0 X8 C; }! P3 W& b! J2) 发送数据函数SendData( )9 w+ d4 f! E9 N, ~
(没有和校验)% }- h1 X/ u8 j ]
Sub SendPLC(iNo As String, iType As String, iAdd As String, iNum As String, iValue As String)1 l% y0 ]& l, t% B: t
'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量,iValue为写入值 s, L% E4 z/ S6 O/ J4 O; G
Dim Stmp As String! _: G, f! U% ?5 h H3 u
Dim Comm As String* j7 ?* y# U3 [- r8 }
Select Case iType
. e! h. A2 K; C5 t+ bCase "D" ''写数据寄存器的值
/ L/ G- j; n6 w6 ~: M/ A) iComm = "WW" ''命令类型:数据字写
- h# s9 B8 H7 L1 i+ RiValue = Right$("0000" + Hex$(Val(iValue)), 4) ''写入值转换成十六进制表示
$ k& C$ z8 c* U, t" i zCase "M" ''写继电器触点的值; Z1 ?% G* F9 a z9 B3 j
Comm = "BW" ''命令类型:二进制位写+ E+ ~! ?4 d: r! b L' s2 t8 \! j
End Select
) S; H, R# S' s/ FiAdd = Right$("000" & iAdd, 4)
: ~ x+ T$ Y% U' piNum = Right$("0" & iNum, 2), n) H1 `6 p; u
Stmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum & iValue ''输出命令格式6 }) \. F: D0 U7 `7 V
MSComm1.Output = Stmp ''输出命令到传送缓冲区
* L/ I' H# |+ I6 a N7 ^0 N' S9 z# @Now= Second()
5 a! {) v; S5 A% CDo
; @" s5 {5 d. j, mDoEvents ''转让控制权,以便让操作系统进行数据传输$ [/ \* G9 y$ w; c( M! n9 L
If Second()-Now>1 Then Exit Sub n3 ?& f2 X. T7 I
Loop Until main.MSComm1.OutBufferCount = 0 ''当命令传送完时停止循环
, {; w6 l3 K* X) [ _* dEnd Sub |
评分
-
查看全部评分
|