|
|
发表于 2009-5-17 23:42:53
|
显示全部楼层
来自: 中国北京
三菱的PLC可以直接和电脑通信,软件要自己设计。" T4 H9 m: j2 m
PC与PLC通讯程序的设计。此部分的开发设计较难,需要掌握PC和PLC的有关通讯硬件驱动和通讯协议的知识。但对于小型控制系统来说,主要通过PC串口来通讯,所以通讯程序设计的关键是如何利用Visual Basic 6.0中的串口通信控件——MSComm控件,并根据PLC的串口通信协议设计出上下位机的数据交换程序。
9 D f" Q3 h# V$ B& N# G0 LPC与PLC通讯程序设计分析
) L2 C) {# K, K, Q4 @7 V在分析具体的VB通讯程序之前,先要介绍有关VB串口通信控件MSComm的应用知识和三菱PLC 通讯协议。
+ O' b+ H5 o! V5 s' t5 D1. MSComm控件简介
( f$ b) }, n1 D+ s3 m5 i如图所示是Mscomm控件的图标。
, e4 a8 j+ C7 \' Y它可以用来提供简单的串行端口通信功能,也可以用来创建功能完备、事件驱动的高级通信工具。 Mscomm控件提供了一系列标准通信命令的使用界面。使用它可以建立与串行端口的连接,通过串行端口再连接到其它设备(如调制解调器、PLC),发出命令,交换数据,以及监视和响应串行连接中发生的事件和错误。3 Z) p& I- k V& e0 X, e
2. MSComm控件的基本属性
( E- [/ p- |& g. i/ kMSComm 控件有很多重要的属性,基本属性如下:+ ?2 t* U/ s& Y7 a3 {( i, O
属性 描述 ) E! Y% }) G8 q( a" s6 J, @3 X
CommPort 设置并返回通讯端口号。
3 H5 t$ M4 @; V( H$ lSettings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。 7 W0 I' M1 `6 p% x+ y* ?0 J
PortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。
3 I# K; P% j' M8 q8 Y" L9 ]Input 从接收缓冲区返回和删除字符。
& f2 \2 q% G$ ]. FOutput 向传输缓冲区写一个字符串。, p0 G: X& O9 K4 k/ }
如下程序打开串行端口COM1
: F- A" V* X, G1 bMSComm1.CommPort = 1 使用 COM1
* ~! L6 s/ D' U' E% u, PMSComm1.Settings = "9600,N,7,1" 9600波特率,无奇偶校验,7位数据,一个停止位。' B5 o4 L# t. N0 D( _ ~# O
MSComm1.PortOpen = True ''打开端口,开始通信。( F8 W- D/ b' `( g: Z' F7 `
3. MSComm控件的通信方式
: R" U0 y3 w; s% l G通信控件有2种不同的方式来处理和解决各类通信软件的开发和设计问题。& T3 Q7 e' u+ k
(1) 事件驱动" t( s* F, d [
事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如:当线路数据到达本端或CD线和RTS信号线状态发生变化时,要求我们使用相应的事件来跟踪和出理。在这些情况下, Mscomm控件将触发OnComm事件,CommEvent属性值也将被改变。所以在OnComm事件中读取CommEvent属性值就可以检测和处理通信错误等方面的问题。+ ]7 v5 F3 J! E3 e
(2)查询方式
# Z+ T+ I; S7 |' F8 ~( b利用定时器控件Timer,我们可以设计程序每隔一段时间去读取CommEvent的值并处理所发生错误和事件。
" a8 k. w+ |( E. D0 S2 ?# h+ L' P9 i/ L4. 本实例中采用的通讯方式3 e$ W! M+ C/ m2 L9 n: l0 m8 V
在本例子中,PC与PLC 采用无握手协议的串行通信,它们只用两根数据线 TD和RD、一根信号地线连接,数据通信采用查询方式。根据系统功能要求,PC需发送两种类型的命令:
& [3 b% q$ M+ ~8 @(1) 周期性命令,它由定时器触发引起,每隔0.5秒发送一次。用它来向PLC查询实时显示的数据。如酒、水的瞬时流量,调节阀开度等。
7 L- L- _1 A0 T/ \6 T" ^3 i(2) 非周期性命令,它由操作者按动命令按钮引起,非周期性发送。用它来传送输入参数、操作命令给PLC 。7 u5 n: l* F2 u2 q
在啤酒稀释的人机操作界面中,有运行时不可见的通信控件(MSComm1)一个、定时器控件一个Timer1。通信控件(MSComm1)用于初始化串口数据并打开串口;定时器控件(Timer1)用于每隔0.5秒执行通讯命令,把查询命令从 PC发送到PLC,同时接收PLC返回的应答数据。设计通讯数据的发送和查询功能,必须掌握PLC所遵循的通讯协议。$ w. T1 Y, j. m# d2 h! ]8 N% {! W+ {
5. 三菱FX系列PLC通讯协议) s0 a- T2 t% \" A0 c
三菱FX系列PLC共有四种通信模式,本实例采用的是PLC与计算机专用协议通信方式(无须PLC编程,电脑直接读写操纵PLC),其通讯命令字和通讯格式介绍如下: U* c; e0 ?$ ]7 C, t5 T( U# }
PC发送给PLC的通信命令字; P1 T# b/ c5 s$ x2 k- d' P
命令字 注释
' k! Q0 @8 _, ~2 m" b1 g2 NBR 以1点为单位,读出位元件的状态0 e3 d) o/ R. P( w% Y1 ^( P
WR 以16点为单位,读出位元件的状态,或以1字为单位,读出字元件的值3 W& N8 f- o: X, S% k
BW 以1点为单位,写入位元件的状态
- @7 E# D( }" q% i5 AWW 以16点为单位,写入位元件的状态,或以1字为单位,写入值到字元件
# }8 A e) F/ e' `! ~BT 以1点为单位,设置/复位 位元件
# |; |/ W; D7 V5 ~4 `WT 以16点为单位,设置/复位 位元件,或以1字为单位,写入值到字元件) }9 k- G: z m2 Q5 K
RR 控制PLC运行RUN5 @( g8 R* Q3 M& v- }( d4 x" m
RS 控制PLC停止STOP
! z! Y( X! k# J' dPC 读出PLC设备类型
; S: i* V* M! \1 |' b0 ]2 fTT 连接测试
; W" D1 s: j r. UPC发送给PLC的通信命令格式
' s! G7 l% i% J' x( f约定说明:ENQ为请求标志,ASCII值5,VB中以chr(5)表示;
2 ^, m# {1 M3 x" i7 ` ACK为正确标志,ASCII值6,VB中以chr(6)表示;
* v( l9 b4 I# M [ STX为请求标志,ASCII值2,VB中以chr(2)表示;0 @0 i- |- ^* U
EXT为请求标志,ASCII值3,VB中以chr(3)表示;
. J t' q8 ^# W2 h e7 K- D; T 表格中粗体字为需要求和效验的部分;8 X/ \& y* S* l& T) t
和效验为每一项的ASCII值的总和转换成十六进制后,取其低两位;8 J" V3 G! h4 y K
站号、PLC号、元件数量、和效验都是以十六进制表示;# D7 K) k# y0 J9 t2 d, B
等待延时为0-150毫秒,以十六进制0H-FH表示,如100ms为AH。* O+ V" Z' Q0 X* Y5 m" c
1) 批量读出位元件—BR指令格式
4 g6 e) m& B% h. A1 r( Q& c1 2 3 4 5 6 7 8 15 16 17
! j3 J: O/ w0 s# oPC侧: ENQ 站号 PLC号 BR 延时 首地址 数量 和校验 ACK 站号 PLC号
% t' n7 m1 B7 tPLC侧: STX 站号 PLC号 数据 EXT 和校验
" z' M5 ?3 p$ N( q! ~ 9 10 11 12 13 14 8 h+ G6 |1 l; |; a
例如:要读出站号为5的PLC的X40到X44共5点的状态值,延时100毫秒,假设PLC中X40与X43为OFF,其余为ON,则指令数据如下:0 U. ?# ~6 O) [8 s
注释: 请求 站号 PLC号 命令 延时 元件首地址 元件数量 和校验3 s& C# R7 R( t; V
代码: ENQ 0 5 F F B R A X 0 0 4 0 0 5 4 7
: c* L- ?4 @1 y. e) g- v0 D, aASCII码: 05H 30H 35H 46H 46H 42H 52H 41H 58 30H 30H 34H 30H 30H 35H 34H 37H/ ^; F& @& z* J& M5 J. { N
只要将以上代码以字符串形式(VB中可以表示为chr(5)&”05FFBRAX00400547”)发送到PLC,就会有正确的回应信息,如下:. O; T* S6 E. s& q+ B8 x( H6 p
注释: 头 站号 PLC号 位元件状态值 尾 和校验. k, H$ X8 G) v' v* c
代码: STX 0 5 F F 0 1 1 0 1 EXT E 7
% S) u- n9 j) q+ \' EASCII码: 02H 30H 35H 46H 46H 30H 31H 31H 30H 31H 03H 45H 37H
( A( f& k" H& k x2) 批量读出字元件—WR指令格式
- U) f7 |0 P: K: T1 2 3 4 5 6 7 8 15 16 171 p5 y4 N) u7 Y, @% a: z
PC侧: ENQ 站号 PLC号 WR 延时 首地址 数量 和校验 ACK 站号 PLC号* \) q1 E6 q) a0 e+ I" @
PLC侧: STX 站号 PLC号 数据 EXT 和校验
4 X# ] z: @: P& [ 9 10 11 12 13 14 m% C' g5 c- V' i# y
该命令使用与BR命令相同。
k) U9 r& w/ u0 M( N! u$ }3) 批量写入位元件—BW指令格式 . c2 S j; Q; R+ `3 v/ P
1 2 3 4 5 6 7 8 9
+ J, h* V+ L: [! KPC侧: ENQ 站号 PLC号 BW 延时 首地址 数量 写入值 和校验
# _8 j; o* a; l6 a- g2 wPLC侧: ACK 站号 PLC号
8 R9 _, _' ^8 B, L 10 11 123 X; r4 F+ |6 [" `+ G5 E
4) 批量写入字元件—WW指令格式
3 }9 H* L' X: p1 E2 @& m1 2 3 4 5 6 7 8 9 3 H; A$ {6 s5 A0 g
PC侧: ENQ 站号 PLC号 WW 延时 首地址 数量 写入值 和校验
% c1 [4 {5 x. p, J/ e6 l5 CPLC侧: ACK 站号 PLC号
. l% {0 B8 \! n 10 11 12
3 c* X6 c. Q4 Y3 K6. VB通讯功能块设计分析1 C; y- w+ J- A# r2 y$ t
根据三菱PLC的通讯指令格式,在PC中编写数据查询功能块RevData( )和数据发送功能块SendData( ),就可以在定时中断处理块TIMER1( )中调用查询功能块RevData( ),实现PC界面数据定时刷新;在每一次操作命令执行时,调用数据发送功能块SendData( ),把控制值写入PLC中,从而实现控制。下面给出这两个功能块的设计程序。
5 C5 r" E9 O6 }1 W! ?! o6 {# I1) 查询数据函数RevData( )6 F Q O" d* W; b! B* ]4 `
(没有和校验)
4 u% @& y! w# n W" RSub RevPLC (iNo As String, iType As String, iAdd As String, iNum As String)/ k L8 P6 |) x, a# z
'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量
& }/ V, B% h1 a+ |Dim Stmp As String0 G8 o D: ~9 ]
Dim cha, j As Integer
- C% ?0 l( y& x& {- ?3 y% W2 ~Dim ChaCount As Integer/ M1 o0 H, F/ G' l
Dim Comm As String
E- O: k$ C3 xSelect Case iType
0 k5 `2 I: W9 p, B7 GCase "D" ''查询数据寄存器的值1 s) U! D4 S9 y4 Z
Comm = "WR" ''命令类型:数据字读
* d& Y9 l& ^% w: R _: A6 Zcha = Val("&H" & iNum) * 4 ''数据寄存器的值为十六进制表示,占4个字符. t9 S3 }0 ?9 B; V
Case "M", "X", "Y" ''查询继电器触电的值
. w2 u. O S* x) e8 EComm = "BR" ''命令类型:二进制位读
" e4 E' B9 x0 tcha = Val("&H" & iNum): X0 J# g- d2 C! r
End Select6 b" e2 P' @2 @6 D$ D5 F, m
iAdd = Right$("000" & iAdd, 4)- w1 Y& k2 }9 `$ F6 K) {/ d
iNum = Right$("0" & iNum, 2)
7 W& p" h \$ v2 _# Q) `Stmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum ''输出命令格式
& a7 `! v% g+ e( X( SChaCount = 6 + cha ''要返回字符个数. M, t6 f- B7 o# E$ E9 a
main.MSComm1.InBufferCount = 0 ''输入缓冲区清零3 z' C7 ]1 t1 U G; ?
main.MSComm1.Output = Stmp ''设传送缓冲区内容为命令格式
$ i' I5 L" ]* l! @( B8 U aNow=Second()
/ J" ^8 Q: b. ^) {7 E2 FDo
1 v/ i, Q5 d3 H i' RDoEvents ''转让控制权,以便让操作系统进行数据传输
4 a$ ]/ J1 H7 Z$ AIf Second()-Now>1 Then Exit Sub' k# Z& V/ J0 X4 m" n
Loop Until main.MSComm1.InBufferCount = ChaCount ''当接收到规定字符时停止循环
. j- a, X W2 Z, \( n) s/ a) `RevDataTmp = Mid$(main.MSComm1.Input, 6, cha) ''返回数据字符串保存在全局变量
. `. l1 k1 A0 x- i9 E( c+ W''RevDataTmp中+ S/ s7 ~; l9 b$ O% A
End Sub/ t% d8 Y# X+ K* s
2) 发送数据函数SendData( ) Y0 `" Z) @9 a4 f; l- T$ ~1 \3 n
(没有和校验)8 ?; ]& V9 V G, D
Sub SendPLC(iNo As String, iType As String, iAdd As String, iNum As String, iValue As String)
+ M: M$ [2 h- C: R9 l" o" `4 l'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量,iValue为写入值
0 b8 ^' m3 K5 uDim Stmp As String0 m( i! E1 n- t. W' y
Dim Comm As String
7 n8 k0 l! W) A C& NSelect Case iType. C; q" z$ E3 S3 v. a
Case "D" ''写数据寄存器的值: c4 ?. e" y( _) P5 X; g& x
Comm = "WW" ''命令类型:数据字写; E9 r! H- A6 e/ `
iValue = Right$("0000" + Hex$(Val(iValue)), 4) ''写入值转换成十六进制表示& F/ B) z5 I9 u! e! s
Case "M" ''写继电器触点的值
# y9 l2 E: P, }5 t3 UComm = "BW" ''命令类型:二进制位写
8 e3 N' S( _- E7 DEnd Select* ^+ t% L# X9 b" @
iAdd = Right$("000" & iAdd, 4)
* W* n+ t' F: qiNum = Right$("0" & iNum, 2)7 i5 @9 N, K- g2 Y/ f
Stmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum & iValue ''输出命令格式
& I5 H/ X9 W$ h- ~5 I |9 y3 AMSComm1.Output = Stmp ''输出命令到传送缓冲区
' t1 O4 x& K: `+ UNow= Second()
* L( _# ^7 I" ~( |5 b O, EDo5 t1 p! J- B2 t# q" U, C
DoEvents ''转让控制权,以便让操作系统进行数据传输
( U5 G1 [3 Y1 o- Y) Z6 }If Second()-Now>1 Then Exit Sub/ R5 `6 D! @" z7 W( @+ r/ ?8 ?
Loop Until main.MSComm1.OutBufferCount = 0 ''当命令传送完时停止循环6 L* s# s) {, b2 \! S
End Sub |
评分
-
查看全部评分
|