|
|
发表于 2009-5-17 23:42:53
|
显示全部楼层
来自: 中国北京
三菱的PLC可以直接和电脑通信,软件要自己设计。
/ c/ h7 \9 n. B1 {4 |# g O5 s8 T8 K1 ^PC与PLC通讯程序的设计。此部分的开发设计较难,需要掌握PC和PLC的有关通讯硬件驱动和通讯协议的知识。但对于小型控制系统来说,主要通过PC串口来通讯,所以通讯程序设计的关键是如何利用Visual Basic 6.0中的串口通信控件——MSComm控件,并根据PLC的串口通信协议设计出上下位机的数据交换程序。
' U: E4 z; e) m3 k4 A7 r0 aPC与PLC通讯程序设计分析
* U I* g" V- \在分析具体的VB通讯程序之前,先要介绍有关VB串口通信控件MSComm的应用知识和三菱PLC 通讯协议。( o9 J/ v5 @3 q+ f/ A/ M: X6 W
1. MSComm控件简介
/ z! q6 t' X& U. a如图所示是Mscomm控件的图标。
& Q6 p2 E9 Z# m. B( u' C' d它可以用来提供简单的串行端口通信功能,也可以用来创建功能完备、事件驱动的高级通信工具。 Mscomm控件提供了一系列标准通信命令的使用界面。使用它可以建立与串行端口的连接,通过串行端口再连接到其它设备(如调制解调器、PLC),发出命令,交换数据,以及监视和响应串行连接中发生的事件和错误。6 ^9 B2 d9 D# h! j! r
2. MSComm控件的基本属性! g% P) `: n' l$ L9 j* B* f
MSComm 控件有很多重要的属性,基本属性如下:
A" v9 e, e' X6 |+ Z9 }* ?( }属性 描述
& O4 h, q: }; B) w/ C6 n0 \CommPort 设置并返回通讯端口号。 . C, l& L+ |9 Q. x$ D
Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。
6 ^7 v' T4 M- h6 j0 SPortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。
7 j' H! G0 v" ]# `# dInput 从接收缓冲区返回和删除字符。 ( n9 n1 L6 X C1 N+ t- r1 h; g
Output 向传输缓冲区写一个字符串。3 ^& J2 p& k/ m' F) T, n
如下程序打开串行端口COM1
3 |, k) f# r$ B) Z4 Y- iMSComm1.CommPort = 1 使用 COM1
) O1 t4 \7 }4 S' _+ uMSComm1.Settings = "9600,N,7,1" 9600波特率,无奇偶校验,7位数据,一个停止位。" M6 i* N% v6 p% f
MSComm1.PortOpen = True ''打开端口,开始通信。- l( j+ ]* f# \2 _( e( Y
3. MSComm控件的通信方式$ X$ a& D7 K2 c& ^* D* _6 V
通信控件有2种不同的方式来处理和解决各类通信软件的开发和设计问题。
4 V8 Z$ m0 I2 X7 C& ]2 H! [ M( v(1) 事件驱动$ K$ j9 k) S' e/ y
事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如:当线路数据到达本端或CD线和RTS信号线状态发生变化时,要求我们使用相应的事件来跟踪和出理。在这些情况下, Mscomm控件将触发OnComm事件,CommEvent属性值也将被改变。所以在OnComm事件中读取CommEvent属性值就可以检测和处理通信错误等方面的问题。) [( K9 a/ ^. E t
(2)查询方式% y) A/ K" u' q# G
利用定时器控件Timer,我们可以设计程序每隔一段时间去读取CommEvent的值并处理所发生错误和事件。
; ^# O5 A# s$ L# Q u) m0 f* M& Y4. 本实例中采用的通讯方式 q# k! \8 Q6 ~+ R- S1 Z
在本例子中,PC与PLC 采用无握手协议的串行通信,它们只用两根数据线 TD和RD、一根信号地线连接,数据通信采用查询方式。根据系统功能要求,PC需发送两种类型的命令:/ k; |! J+ B. C9 X: y
(1) 周期性命令,它由定时器触发引起,每隔0.5秒发送一次。用它来向PLC查询实时显示的数据。如酒、水的瞬时流量,调节阀开度等。
4 D( @) a! v' ]* o(2) 非周期性命令,它由操作者按动命令按钮引起,非周期性发送。用它来传送输入参数、操作命令给PLC 。
0 h# c# F0 p/ H# u* g在啤酒稀释的人机操作界面中,有运行时不可见的通信控件(MSComm1)一个、定时器控件一个Timer1。通信控件(MSComm1)用于初始化串口数据并打开串口;定时器控件(Timer1)用于每隔0.5秒执行通讯命令,把查询命令从 PC发送到PLC,同时接收PLC返回的应答数据。设计通讯数据的发送和查询功能,必须掌握PLC所遵循的通讯协议。
6 ^2 J( C3 l. r) t: ]( n5. 三菱FX系列PLC通讯协议
# ?7 Z7 a5 {' B5 U. O三菱FX系列PLC共有四种通信模式,本实例采用的是PLC与计算机专用协议通信方式(无须PLC编程,电脑直接读写操纵PLC),其通讯命令字和通讯格式介绍如下:
* p* l8 \2 j1 a/ {; X2 wPC发送给PLC的通信命令字
' o% z* }% j- H- i; z命令字 注释6 O, J! s+ F, K& P
BR 以1点为单位,读出位元件的状态
! a, y7 r/ ~" P' b0 U2 W$ U! rWR 以16点为单位,读出位元件的状态,或以1字为单位,读出字元件的值
6 c# p- [0 f$ n* ?BW 以1点为单位,写入位元件的状态3 z( ?- m3 B2 V
WW 以16点为单位,写入位元件的状态,或以1字为单位,写入值到字元件2 Y4 O& S1 [3 w- N
BT 以1点为单位,设置/复位 位元件
% S0 G5 z1 w# Z2 NWT 以16点为单位,设置/复位 位元件,或以1字为单位,写入值到字元件% i% [* l6 B. N
RR 控制PLC运行RUN, a ]2 Z8 J/ Y' ]5 ^: V; M
RS 控制PLC停止STOP& |4 E1 O) k0 j, t& k
PC 读出PLC设备类型, v& Z; x7 r6 G+ t' D, c
TT 连接测试
" N, _6 \& H5 u' @2 x Z/ qPC发送给PLC的通信命令格式% H5 U+ E# D1 H, E {0 { Q$ ]
约定说明:ENQ为请求标志,ASCII值5,VB中以chr(5)表示;
- A5 w+ Y- \2 M6 l/ _0 T# }9 C ACK为正确标志,ASCII值6,VB中以chr(6)表示; # k% c$ m7 Q$ m4 y+ I! j2 N
STX为请求标志,ASCII值2,VB中以chr(2)表示;
) {- p, j% k* J6 W$ C6 A" K EXT为请求标志,ASCII值3,VB中以chr(3)表示;
! n6 K# S/ Z% T6 i7 w 表格中粗体字为需要求和效验的部分;# l" V7 A7 M% g D
和效验为每一项的ASCII值的总和转换成十六进制后,取其低两位;
% r' a# q1 P0 i- f5 U2 L 站号、PLC号、元件数量、和效验都是以十六进制表示;( X$ x! ^3 A' Q) P" i
等待延时为0-150毫秒,以十六进制0H-FH表示,如100ms为AH。. g0 F5 n6 d3 d5 _9 t# }3 ], S
1) 批量读出位元件—BR指令格式' c0 {/ G( D/ T( a
1 2 3 4 5 6 7 8 15 16 17" a) |/ P" a/ ?4 {
PC侧: ENQ 站号 PLC号 BR 延时 首地址 数量 和校验 ACK 站号 PLC号4 c5 n$ V# R4 v: P6 s; \+ ~5 s% x3 D
PLC侧: STX 站号 PLC号 数据 EXT 和校验
( P" n6 q/ `9 v4 G% x5 J* [ 9 10 11 12 13 14
0 j2 B7 J( a, ?/ C例如:要读出站号为5的PLC的X40到X44共5点的状态值,延时100毫秒,假设PLC中X40与X43为OFF,其余为ON,则指令数据如下:" a/ ~1 I4 g& l& l% _4 ]
注释: 请求 站号 PLC号 命令 延时 元件首地址 元件数量 和校验
N; @7 Q( |5 F; q, Y代码: ENQ 0 5 F F B R A X 0 0 4 0 0 5 4 7
4 k* t4 ^6 _; U' b* w( FASCII码: 05H 30H 35H 46H 46H 42H 52H 41H 58 30H 30H 34H 30H 30H 35H 34H 37H4 S3 ~8 e. Y9 z# m9 j6 J
只要将以上代码以字符串形式(VB中可以表示为chr(5)&”05FFBRAX00400547”)发送到PLC,就会有正确的回应信息,如下:* }$ \# Y+ b" R5 w
注释: 头 站号 PLC号 位元件状态值 尾 和校验
- ?$ S5 P0 N6 c( L# N D P代码: STX 0 5 F F 0 1 1 0 1 EXT E 70 }$ B+ a( L: S9 F
ASCII码: 02H 30H 35H 46H 46H 30H 31H 31H 30H 31H 03H 45H 37H
" _3 a) O. C& v8 `/ B0 i2) 批量读出字元件—WR指令格式$ Z4 I7 R4 K5 ]9 |! p4 l3 C
1 2 3 4 5 6 7 8 15 16 17
9 O4 R. |2 m- ^5 FPC侧: ENQ 站号 PLC号 WR 延时 首地址 数量 和校验 ACK 站号 PLC号
. b0 y, X1 T4 b$ ~' S* PPLC侧: STX 站号 PLC号 数据 EXT 和校验 5 k' j7 w& g: _3 f2 Y
9 10 11 12 13 14 * j( s0 B0 a. _3 r& O- `& s
该命令使用与BR命令相同。9 z8 @. H8 {5 ~6 A/ f
3) 批量写入位元件—BW指令格式
4 r% q9 E" `# M6 _/ r$ O1 2 3 4 5 6 7 8 9 ) C! C' X4 m' m% u- O# F
PC侧: ENQ 站号 PLC号 BW 延时 首地址 数量 写入值 和校验 $ Q, r, n$ `- ~' X0 B
PLC侧: ACK 站号 PLC号
5 Y# G+ ^3 X, o7 f8 E# t% I/ ^) U 10 11 123 f$ P0 j" c" h
4) 批量写入字元件—WW指令格式. A' i/ x6 ?8 _( f
1 2 3 4 5 6 7 8 9 0 }" Z, C' @) `) @5 R7 K
PC侧: ENQ 站号 PLC号 WW 延时 首地址 数量 写入值 和校验 5 M, i$ X5 M! W$ D/ S8 M _. `
PLC侧: ACK 站号 PLC号
; Q4 a+ @; q7 B! B 10 11 122 l/ P9 _3 u" e; G; k
6. VB通讯功能块设计分析
+ u: z1 {& R: p8 o3 W- C, ^, c6 v根据三菱PLC的通讯指令格式,在PC中编写数据查询功能块RevData( )和数据发送功能块SendData( ),就可以在定时中断处理块TIMER1( )中调用查询功能块RevData( ),实现PC界面数据定时刷新;在每一次操作命令执行时,调用数据发送功能块SendData( ),把控制值写入PLC中,从而实现控制。下面给出这两个功能块的设计程序。
6 M- o# e+ ~, C: d' \% F8 E: i1) 查询数据函数RevData( )2 s# q/ \$ A3 u5 s
(没有和校验)' z3 W3 [0 I' m6 ]; l! o
Sub RevPLC (iNo As String, iType As String, iAdd As String, iNum As String)
5 L- B0 Y# K6 U( `3 w% x'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量) V, |! \3 j- v! i" R
Dim Stmp As String$ X% l) m" y, L: H$ X
Dim cha, j As Integer
% s" |* I: C! f: QDim ChaCount As Integer9 m) Q* M4 z2 B# F2 ^
Dim Comm As String
8 E& |4 |# P. k3 R& R @# o" Z7 KSelect Case iType$ ?4 @8 O( X& W6 M5 B+ N
Case "D" ''查询数据寄存器的值4 Z) X/ P6 Q3 u& E4 E# E
Comm = "WR" ''命令类型:数据字读& y' a8 z& z# t1 C. k9 ^/ O: |
cha = Val("&H" & iNum) * 4 ''数据寄存器的值为十六进制表示,占4个字符- P+ P, m4 O6 S; M
Case "M", "X", "Y" ''查询继电器触电的值
5 \7 W! V- S8 ]2 p; ~Comm = "BR" ''命令类型:二进制位读
0 \! s5 @; J8 O* D( Kcha = Val("&H" & iNum)
9 m! n+ S) Y9 r6 BEnd Select, d! q1 Y( u1 p/ f
iAdd = Right$("000" & iAdd, 4)2 h& z' ^, {8 b( |1 f
iNum = Right$("0" & iNum, 2)
: \% F4 G" e' Y8 j* `" A( Z/ tStmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum ''输出命令格式
, N1 R, L8 t: e' ZChaCount = 6 + cha ''要返回字符个数7 u. f" ]& F! ~7 j2 q
main.MSComm1.InBufferCount = 0 ''输入缓冲区清零
8 y1 W+ P5 Y; S2 E' c' Kmain.MSComm1.Output = Stmp ''设传送缓冲区内容为命令格式
- e8 T( l2 V( {9 B" ?Now=Second()
7 v0 e# \/ @: }4 Q. v3 gDo3 [- [( X! D* Z/ l' m% Q
DoEvents ''转让控制权,以便让操作系统进行数据传输
6 U$ ^. r, [/ x) z4 J3 HIf Second()-Now>1 Then Exit Sub' j. m8 M3 d4 ]3 F0 K. |/ P
Loop Until main.MSComm1.InBufferCount = ChaCount ''当接收到规定字符时停止循环
: B& r1 Z! B2 s( W _RevDataTmp = Mid$(main.MSComm1.Input, 6, cha) ''返回数据字符串保存在全局变量. E0 V g: C$ Z+ g* e
''RevDataTmp中# P+ p# S3 H0 w; { @9 j
End Sub" v3 R. v4 L; E/ d- @; h
2) 发送数据函数SendData( )
; a0 C: f5 L1 o9 Q7 h(没有和校验)
, H/ A) o. V1 w9 f5 b$ MSub SendPLC(iNo As String, iType As String, iAdd As String, iNum As String, iValue As String)
) s+ ]: Y$ l- P( Q* ~'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量,iValue为写入值5 l- H T6 a5 w! d) ?4 `+ C
Dim Stmp As String
( @( f8 M7 l* g U+ I" bDim Comm As String
/ A, `/ r& H% x6 L PSelect Case iType
1 A G% }( Q# ?8 C; M7 b7 bCase "D" ''写数据寄存器的值5 n' ]" ^( g3 f! R2 G# m6 `
Comm = "WW" ''命令类型:数据字写8 ~ X: d/ i8 T+ X/ B K7 {
iValue = Right$("0000" + Hex$(Val(iValue)), 4) ''写入值转换成十六进制表示& `: {. o- \! `* u% d
Case "M" ''写继电器触点的值
7 G; E t0 f$ G4 ~4 f2 u6 s# E0 UComm = "BW" ''命令类型:二进制位写
0 l& Y5 i s1 O- A: oEnd Select% f3 J3 g; W5 G6 R# O, {/ x
iAdd = Right$("000" & iAdd, 4) m. K7 q3 ?* p% h! P. {; C2 L6 t8 l
iNum = Right$("0" & iNum, 2)4 z, U5 i- L G* G* N& W% r
Stmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum & iValue ''输出命令格式' Z, e$ M7 ]: x7 Z
MSComm1.Output = Stmp ''输出命令到传送缓冲区
0 }6 Y7 y9 W% P, V9 r: lNow= Second()
. x L+ N. D$ K5 l3 J9 s& o6 YDo
/ O- s' H# M6 j' r$ D: u1 y; UDoEvents ''转让控制权,以便让操作系统进行数据传输5 r K6 \7 X! ]* j1 M! ~
If Second()-Now>1 Then Exit Sub1 n" r+ |& u8 D2 ]- g
Loop Until main.MSComm1.OutBufferCount = 0 ''当命令传送完时停止循环; S# @/ m0 b7 ~ F4 E G
End Sub |
评分
-
查看全部评分
|