|
|
发表于 2009-5-17 23:42:53
|
显示全部楼层
来自: 中国北京
三菱的PLC可以直接和电脑通信,软件要自己设计。6 V6 S7 f5 ]9 ~8 Q/ j
PC与PLC通讯程序的设计。此部分的开发设计较难,需要掌握PC和PLC的有关通讯硬件驱动和通讯协议的知识。但对于小型控制系统来说,主要通过PC串口来通讯,所以通讯程序设计的关键是如何利用Visual Basic 6.0中的串口通信控件——MSComm控件,并根据PLC的串口通信协议设计出上下位机的数据交换程序。
: j) E8 z# {% e$ |4 c. lPC与PLC通讯程序设计分析) E- |. S/ S) B V/ W
在分析具体的VB通讯程序之前,先要介绍有关VB串口通信控件MSComm的应用知识和三菱PLC 通讯协议。
' n$ Z! b8 f5 h* r b% ? M1. MSComm控件简介* w9 g, D7 I2 v, B/ R8 m
如图所示是Mscomm控件的图标。
& l$ \7 d2 }; w# \" u5 B它可以用来提供简单的串行端口通信功能,也可以用来创建功能完备、事件驱动的高级通信工具。 Mscomm控件提供了一系列标准通信命令的使用界面。使用它可以建立与串行端口的连接,通过串行端口再连接到其它设备(如调制解调器、PLC),发出命令,交换数据,以及监视和响应串行连接中发生的事件和错误。
3 E5 x3 _: |6 }2 X# Q2. MSComm控件的基本属性3 X. E6 w k* X5 {: {! Q
MSComm 控件有很多重要的属性,基本属性如下:- q: y3 q9 ]2 n3 K( ?7 o1 G
属性 描述
" G0 T& a. }" P9 q% @3 U- \, e. P! r5 nCommPort 设置并返回通讯端口号。
4 ?% L2 }* N0 \: R( e; M+ U: n7 _Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。 ' K8 p: V. ]! T
PortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。
' u3 Y) I; O% Y) S5 t. y3 ^Input 从接收缓冲区返回和删除字符。
8 [3 P6 A; _0 t7 q0 i" R: ?8 \! sOutput 向传输缓冲区写一个字符串。
1 ^& t) q: P) w1 M. p: E3 d如下程序打开串行端口COM19 H2 p v* H$ `; f
MSComm1.CommPort = 1 使用 COM1
$ z7 x+ d3 F) g4 q0 v+ FMSComm1.Settings = "9600,N,7,1" 9600波特率,无奇偶校验,7位数据,一个停止位。
9 W3 j, |; ~8 A% s! b3 wMSComm1.PortOpen = True ''打开端口,开始通信。3 M, F. ?, \" P
3. MSComm控件的通信方式
( } p" b9 Y1 E通信控件有2种不同的方式来处理和解决各类通信软件的开发和设计问题。
& L" b+ `' q' c$ B. S0 J. Z% r' z(1) 事件驱动
& U- a) Q5 ? z4 b事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如:当线路数据到达本端或CD线和RTS信号线状态发生变化时,要求我们使用相应的事件来跟踪和出理。在这些情况下, Mscomm控件将触发OnComm事件,CommEvent属性值也将被改变。所以在OnComm事件中读取CommEvent属性值就可以检测和处理通信错误等方面的问题。
; S+ u7 f" ~, H, K(2)查询方式
9 b, J" I8 S/ W$ L$ ~利用定时器控件Timer,我们可以设计程序每隔一段时间去读取CommEvent的值并处理所发生错误和事件。 i7 I* n8 u* [3 h, r! q
4. 本实例中采用的通讯方式! h" e6 ?/ v3 E2 F
在本例子中,PC与PLC 采用无握手协议的串行通信,它们只用两根数据线 TD和RD、一根信号地线连接,数据通信采用查询方式。根据系统功能要求,PC需发送两种类型的命令:
, `( b/ Z+ a, M' J4 ^(1) 周期性命令,它由定时器触发引起,每隔0.5秒发送一次。用它来向PLC查询实时显示的数据。如酒、水的瞬时流量,调节阀开度等。. `2 e" L, }7 ]/ H& E3 `- }8 m8 a
(2) 非周期性命令,它由操作者按动命令按钮引起,非周期性发送。用它来传送输入参数、操作命令给PLC 。4 @8 V5 S3 n5 \" K2 E, G% C
在啤酒稀释的人机操作界面中,有运行时不可见的通信控件(MSComm1)一个、定时器控件一个Timer1。通信控件(MSComm1)用于初始化串口数据并打开串口;定时器控件(Timer1)用于每隔0.5秒执行通讯命令,把查询命令从 PC发送到PLC,同时接收PLC返回的应答数据。设计通讯数据的发送和查询功能,必须掌握PLC所遵循的通讯协议。$ T" U$ w ? C7 p0 _% V2 d& |% F
5. 三菱FX系列PLC通讯协议+ ?9 D# ~& ~& w, F
三菱FX系列PLC共有四种通信模式,本实例采用的是PLC与计算机专用协议通信方式(无须PLC编程,电脑直接读写操纵PLC),其通讯命令字和通讯格式介绍如下:- z* y: K. d$ P' o8 L9 T
PC发送给PLC的通信命令字0 E- R- K6 n* G& B8 ]
命令字 注释" Y' |$ F W: \5 |$ {
BR 以1点为单位,读出位元件的状态
- H1 t6 N; ~" m- HWR 以16点为单位,读出位元件的状态,或以1字为单位,读出字元件的值
: r- Z$ ? F/ o0 D0 ~0 mBW 以1点为单位,写入位元件的状态0 K, c* L7 D* x" _" B* r
WW 以16点为单位,写入位元件的状态,或以1字为单位,写入值到字元件
8 A) {: [0 o9 R" r: ABT 以1点为单位,设置/复位 位元件' L* d- b; g) @, e+ c
WT 以16点为单位,设置/复位 位元件,或以1字为单位,写入值到字元件7 s6 d/ d) m3 m1 z8 p n
RR 控制PLC运行RUN" r2 o2 i7 v' v
RS 控制PLC停止STOP$ ^: _5 v K+ ^; z5 W. A N
PC 读出PLC设备类型0 V+ n* N4 K% Z1 N$ b! \
TT 连接测试
X$ L: Q' t) w; n+ I9 ?& N6 a; IPC发送给PLC的通信命令格式
' n, `7 S0 i/ F* E0 u7 }约定说明:ENQ为请求标志,ASCII值5,VB中以chr(5)表示;
1 v" V6 C- I8 ^ ACK为正确标志,ASCII值6,VB中以chr(6)表示; 6 C1 T! G1 t1 O/ a1 v* {! \4 \; l
STX为请求标志,ASCII值2,VB中以chr(2)表示;; j, J' C+ [% s9 `) O0 {' f, V
EXT为请求标志,ASCII值3,VB中以chr(3)表示; ]5 J/ d& e# b5 z! {
表格中粗体字为需要求和效验的部分; W2 G7 I7 q; Z1 w3 p
和效验为每一项的ASCII值的总和转换成十六进制后,取其低两位;
6 G5 K0 J4 d$ h( a% \6 \% A 站号、PLC号、元件数量、和效验都是以十六进制表示;
5 D* y% p2 B# `3 f. c2 A ? 等待延时为0-150毫秒,以十六进制0H-FH表示,如100ms为AH。
' m1 ^, |( ~8 b; \# r1) 批量读出位元件—BR指令格式1 U7 v7 S3 n/ U5 x, |2 K3 ~
1 2 3 4 5 6 7 8 15 16 17
! W$ d: @" b9 v" L/ f: D/ lPC侧: ENQ 站号 PLC号 BR 延时 首地址 数量 和校验 ACK 站号 PLC号
' w* l) t' f$ y$ p& k# sPLC侧: STX 站号 PLC号 数据 EXT 和校验 5 {/ C3 A7 [3 k) F$ J/ C) ^* l9 {
9 10 11 12 13 14
+ l: U& z+ B* m& u& M) J例如:要读出站号为5的PLC的X40到X44共5点的状态值,延时100毫秒,假设PLC中X40与X43为OFF,其余为ON,则指令数据如下:- D7 Y8 T# V# ?6 A$ V7 o! J
注释: 请求 站号 PLC号 命令 延时 元件首地址 元件数量 和校验
9 W3 N' f. u$ ~3 _' P: ^$ B代码: ENQ 0 5 F F B R A X 0 0 4 0 0 5 4 77 b$ Z8 e& ?$ I& d+ m+ W
ASCII码: 05H 30H 35H 46H 46H 42H 52H 41H 58 30H 30H 34H 30H 30H 35H 34H 37H
l- z4 @2 Y9 w5 ?只要将以上代码以字符串形式(VB中可以表示为chr(5)&”05FFBRAX00400547”)发送到PLC,就会有正确的回应信息,如下:( {8 W' q- n h, ]
注释: 头 站号 PLC号 位元件状态值 尾 和校验
3 q( Z/ c0 ~! i/ j代码: STX 0 5 F F 0 1 1 0 1 EXT E 7+ \9 H5 W- R' c$ \2 t5 m
ASCII码: 02H 30H 35H 46H 46H 30H 31H 31H 30H 31H 03H 45H 37H' |9 F N# O7 J8 Z, C! _
2) 批量读出字元件—WR指令格式
6 W4 o8 M/ ~: w/ j/ }0 p1 2 3 4 5 6 7 8 15 16 17
0 x2 k0 P& F) r6 [8 |, iPC侧: ENQ 站号 PLC号 WR 延时 首地址 数量 和校验 ACK 站号 PLC号
' h: v3 g# N! A% M! \4 r# c: e2 tPLC侧: STX 站号 PLC号 数据 EXT 和校验 7 j) ]& @) [" X) E% d
9 10 11 12 13 14
, w9 k% d7 h3 D该命令使用与BR命令相同。
3 Z# @6 u( X8 |' |2 s3) 批量写入位元件—BW指令格式 2 F2 x+ s) {- u, T& f1 C! K
1 2 3 4 5 6 7 8 9
9 \* X" M) \+ X2 {. l( k, L, x9 wPC侧: ENQ 站号 PLC号 BW 延时 首地址 数量 写入值 和校验 8 X* r2 f4 C& `5 _
PLC侧: ACK 站号 PLC号4 [% C, u1 U; |2 o
10 11 122 O7 O- L7 G; [2 }
4) 批量写入字元件—WW指令格式
2 P: z$ }+ \7 g1 2 3 4 5 6 7 8 9
0 W# D5 s. B* S- h; b1 u$ UPC侧: ENQ 站号 PLC号 WW 延时 首地址 数量 写入值 和校验
G* ]) \ W$ {7 N( T$ w$ xPLC侧: ACK 站号 PLC号9 L0 }' m( X' F8 I' ?( E
10 11 125 {3 o5 ]+ N! c- {; J
6. VB通讯功能块设计分析
, X( y1 g) v1 V; a8 b3 h5 e7 z根据三菱PLC的通讯指令格式,在PC中编写数据查询功能块RevData( )和数据发送功能块SendData( ),就可以在定时中断处理块TIMER1( )中调用查询功能块RevData( ),实现PC界面数据定时刷新;在每一次操作命令执行时,调用数据发送功能块SendData( ),把控制值写入PLC中,从而实现控制。下面给出这两个功能块的设计程序。
7 d- O3 N# ?4 O1) 查询数据函数RevData( )
. m+ y# C, k$ X(没有和校验)/ |+ ?8 r: j' Y2 l6 \
Sub RevPLC (iNo As String, iType As String, iAdd As String, iNum As String)
4 U* L# u% J Q, Y1 z& l A. R'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量4 a2 `- m X8 Q& c4 T9 ~
Dim Stmp As String
4 ]) y# B9 f3 C1 K' \0 sDim cha, j As Integer- F/ R$ K/ [ N8 {% i) A
Dim ChaCount As Integer
f( Y- ] t8 n4 pDim Comm As String
1 o$ d4 F+ b% O9 M- J" \6 s" LSelect Case iType
* X9 w# C0 k" \2 W. P' ICase "D" ''查询数据寄存器的值3 Q: K7 Y: R4 K! d
Comm = "WR" ''命令类型:数据字读
' |% f' G. i& T$ R; P0 mcha = Val("&H" & iNum) * 4 ''数据寄存器的值为十六进制表示,占4个字符
$ {' e0 M) Z9 U- q, vCase "M", "X", "Y" ''查询继电器触电的值9 ^* Z4 u& g" t1 }+ a3 T* `
Comm = "BR" ''命令类型:二进制位读
2 w- B- o o4 e, _9 Ocha = Val("&H" & iNum)
' f& T5 C3 A$ u4 o( A4 yEnd Select
/ R/ }* i. D- n2 giAdd = Right$("000" & iAdd, 4)) v; |" Y/ \1 P
iNum = Right$("0" & iNum, 2)
R% G9 e4 B+ GStmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum ''输出命令格式
* J Z( n0 f" G/ x' oChaCount = 6 + cha ''要返回字符个数
+ Z% x3 i2 v. |7 q2 g9 |; q$ `& Emain.MSComm1.InBufferCount = 0 ''输入缓冲区清零
7 ]& B- S5 N. e# o: dmain.MSComm1.Output = Stmp ''设传送缓冲区内容为命令格式
! K, n1 D8 f3 c- _Now=Second()5 H) ^3 E; i& u/ Q
Do
. Z6 O' T* ^0 h& c4 VDoEvents ''转让控制权,以便让操作系统进行数据传输# d Q) A" n) {! @9 J
If Second()-Now>1 Then Exit Sub, C5 v: Z2 I, J7 s4 s
Loop Until main.MSComm1.InBufferCount = ChaCount ''当接收到规定字符时停止循环
u4 ^9 b' _3 _, ]6 l3 IRevDataTmp = Mid$(main.MSComm1.Input, 6, cha) ''返回数据字符串保存在全局变量8 C) a9 i% A1 L/ `* @) [, `: P
''RevDataTmp中* K! m& \1 x+ J) w
End Sub
2 m# ~: v- p$ X1 T& a4 x2) 发送数据函数SendData( )
) G8 {0 W( D( F& q! P(没有和校验)$ w/ [- ^8 x1 X, {! h- q
Sub SendPLC(iNo As String, iType As String, iAdd As String, iNum As String, iValue As String)9 K h6 a% X% \0 |' G
'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量,iValue为写入值
3 Q3 H! V. h7 }" R6 IDim Stmp As String
5 a' T" C l0 j6 }9 V5 i5 o0 dDim Comm As String1 u( Q1 @# W3 z+ z
Select Case iType' @* u- c( `" A
Case "D" ''写数据寄存器的值- X0 F' ~( ~$ f8 ]# K- _, W
Comm = "WW" ''命令类型:数据字写' y8 ?* L w) D) n* c. ~
iValue = Right$("0000" + Hex$(Val(iValue)), 4) ''写入值转换成十六进制表示
& g6 q, A; q) `2 u6 G# `Case "M" ''写继电器触点的值
% C+ K) O5 ^9 C" Y4 `/ bComm = "BW" ''命令类型:二进制位写
; \( f S8 [3 V- `) I3 z2 VEnd Select) y0 R2 I9 a: h; T
iAdd = Right$("000" & iAdd, 4)
5 b. t0 B8 s, u' \2 V1 yiNum = Right$("0" & iNum, 2)
% A5 S/ S7 f% F4 dStmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum & iValue ''输出命令格式
: R% f5 l. \ TMSComm1.Output = Stmp ''输出命令到传送缓冲区' t/ c4 v$ G1 _2 I8 L, E
Now= Second()# i! }$ |) d0 i
Do: c: G& u& C! ?8 J# R
DoEvents ''转让控制权,以便让操作系统进行数据传输: W% K3 {: U" U. h+ [
If Second()-Now>1 Then Exit Sub! c8 v8 w4 D4 N8 t* ]& T5 t3 H0 w
Loop Until main.MSComm1.OutBufferCount = 0 ''当命令传送完时停止循环1 Z2 `' m3 |7 S0 X9 y1 j
End Sub |
评分
-
查看全部评分
|