|
|
发表于 2009-5-17 23:42:53
|
显示全部楼层
来自: 中国北京
三菱的PLC可以直接和电脑通信,软件要自己设计。8 T! B) f$ ^- v4 P+ \
PC与PLC通讯程序的设计。此部分的开发设计较难,需要掌握PC和PLC的有关通讯硬件驱动和通讯协议的知识。但对于小型控制系统来说,主要通过PC串口来通讯,所以通讯程序设计的关键是如何利用Visual Basic 6.0中的串口通信控件——MSComm控件,并根据PLC的串口通信协议设计出上下位机的数据交换程序。* ^0 g, n- L8 `& r/ ^
PC与PLC通讯程序设计分析
! @" }4 z( ^! Z6 D0 Y6 Z$ ~' a6 d在分析具体的VB通讯程序之前,先要介绍有关VB串口通信控件MSComm的应用知识和三菱PLC 通讯协议。
8 d' A# a1 Y0 ]7 d6 K6 O1. MSComm控件简介
2 M( q. s3 i! ~5 y- D5 d. t9 T如图所示是Mscomm控件的图标。
. z% z3 E: r S w! f% r# }+ T4 a& I它可以用来提供简单的串行端口通信功能,也可以用来创建功能完备、事件驱动的高级通信工具。 Mscomm控件提供了一系列标准通信命令的使用界面。使用它可以建立与串行端口的连接,通过串行端口再连接到其它设备(如调制解调器、PLC),发出命令,交换数据,以及监视和响应串行连接中发生的事件和错误。" n' I# r% `5 l3 e
2. MSComm控件的基本属性
2 Q3 g7 _- n+ L0 \8 M% ZMSComm 控件有很多重要的属性,基本属性如下:; d/ D* i7 k3 C2 q! I* c: u
属性 描述 2 _( l1 A ]% T* F9 ^3 N9 C; u- ]
CommPort 设置并返回通讯端口号。
, ?9 W4 {4 u" I3 |2 k- u' }Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。 ! B8 x. j+ N' k" E8 f9 z
PortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。
$ J9 C) Z* }' W6 W8 ^: i% TInput 从接收缓冲区返回和删除字符。
- Q, `& m7 v' X) b; ~4 j1 rOutput 向传输缓冲区写一个字符串。
4 M& @ I8 k. {- K2 g0 F1 D如下程序打开串行端口COM1
% N# i3 m( m& ?/ w& _MSComm1.CommPort = 1 使用 COM1 8 r3 F% t+ Y& @: _; i& f1 `
MSComm1.Settings = "9600,N,7,1" 9600波特率,无奇偶校验,7位数据,一个停止位。* _1 h, B1 v$ M3 z8 [* l
MSComm1.PortOpen = True ''打开端口,开始通信。2 E+ Y$ }& J, D% e. \# J
3. MSComm控件的通信方式
5 S- R# z6 N# e! O, Q通信控件有2种不同的方式来处理和解决各类通信软件的开发和设计问题。* j* A3 _' Z; l
(1) 事件驱动
2 N2 `4 q) w/ _; H1 G事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如:当线路数据到达本端或CD线和RTS信号线状态发生变化时,要求我们使用相应的事件来跟踪和出理。在这些情况下, Mscomm控件将触发OnComm事件,CommEvent属性值也将被改变。所以在OnComm事件中读取CommEvent属性值就可以检测和处理通信错误等方面的问题。
- H- p2 r" y4 [! K: h( G; k(2)查询方式
/ {" b1 ?+ U) R. x4 j4 y/ v0 }2 C利用定时器控件Timer,我们可以设计程序每隔一段时间去读取CommEvent的值并处理所发生错误和事件。% m4 ?8 N4 j8 z' x+ \+ F
4. 本实例中采用的通讯方式
" x4 ~- s* p( c$ [在本例子中,PC与PLC 采用无握手协议的串行通信,它们只用两根数据线 TD和RD、一根信号地线连接,数据通信采用查询方式。根据系统功能要求,PC需发送两种类型的命令:8 [: N2 H& M* |) N5 F$ R
(1) 周期性命令,它由定时器触发引起,每隔0.5秒发送一次。用它来向PLC查询实时显示的数据。如酒、水的瞬时流量,调节阀开度等。
& g4 A# _% o' z' i- V(2) 非周期性命令,它由操作者按动命令按钮引起,非周期性发送。用它来传送输入参数、操作命令给PLC 。4 e/ \; F% V7 I3 l7 |
在啤酒稀释的人机操作界面中,有运行时不可见的通信控件(MSComm1)一个、定时器控件一个Timer1。通信控件(MSComm1)用于初始化串口数据并打开串口;定时器控件(Timer1)用于每隔0.5秒执行通讯命令,把查询命令从 PC发送到PLC,同时接收PLC返回的应答数据。设计通讯数据的发送和查询功能,必须掌握PLC所遵循的通讯协议。" X& k) S' H$ ~7 t( b0 w
5. 三菱FX系列PLC通讯协议7 r9 B' N8 y Q$ G
三菱FX系列PLC共有四种通信模式,本实例采用的是PLC与计算机专用协议通信方式(无须PLC编程,电脑直接读写操纵PLC),其通讯命令字和通讯格式介绍如下:5 t; ^8 U; c; o/ e# ?# k
PC发送给PLC的通信命令字
& C: [7 M8 @( E2 { T( O/ h! G. `; I命令字 注释& z% G2 e1 b: j$ j8 J
BR 以1点为单位,读出位元件的状态: I. r0 a5 M. v6 J2 |$ D1 j; U
WR 以16点为单位,读出位元件的状态,或以1字为单位,读出字元件的值! [5 H9 R# \: K* C1 m* S
BW 以1点为单位,写入位元件的状态, A. Z) M+ u9 Q. P3 Y1 [
WW 以16点为单位,写入位元件的状态,或以1字为单位,写入值到字元件9 W: Y0 I7 ?# L
BT 以1点为单位,设置/复位 位元件' E. x% o/ n& X) T# q2 Q' z
WT 以16点为单位,设置/复位 位元件,或以1字为单位,写入值到字元件
) Y# L6 m1 ^ w, XRR 控制PLC运行RUN
! U0 n% s* V) m; ]% J/ Z3 XRS 控制PLC停止STOP
* r. Y& P. `, U9 _* y4 UPC 读出PLC设备类型8 u' F' L9 ]& \+ E. V
TT 连接测试
( E8 D/ K) |2 CPC发送给PLC的通信命令格式
& {" A) L" p5 U5 E ?4 u, ~- [2 O/ f7 G约定说明:ENQ为请求标志,ASCII值5,VB中以chr(5)表示;
% y- ^6 q* h3 e3 k1 p) a# { ACK为正确标志,ASCII值6,VB中以chr(6)表示;
- |7 n2 `7 I* l, ]/ _' }8 ]( k STX为请求标志,ASCII值2,VB中以chr(2)表示;
* C- {3 v- W. p8 {! S) c% x EXT为请求标志,ASCII值3,VB中以chr(3)表示; 9 u2 W& Y! R t3 q- E
表格中粗体字为需要求和效验的部分;
1 @/ G/ ~, x v- C3 W3 i 和效验为每一项的ASCII值的总和转换成十六进制后,取其低两位;4 y( ~3 ^: r7 ]1 F: {
站号、PLC号、元件数量、和效验都是以十六进制表示;+ b8 g- {2 r4 O W& M
等待延时为0-150毫秒,以十六进制0H-FH表示,如100ms为AH。
6 i1 G- t5 a+ x2 H1) 批量读出位元件—BR指令格式
4 |* O6 [8 h4 `) |6 v1 2 3 4 5 6 7 8 15 16 17
* P' g9 E3 g7 m$ uPC侧: ENQ 站号 PLC号 BR 延时 首地址 数量 和校验 ACK 站号 PLC号
2 V5 S6 s. L8 i% bPLC侧: STX 站号 PLC号 数据 EXT 和校验
5 K! [9 Y' p. d, l5 r# ] 9 10 11 12 13 14 9 z* U% x3 L( O1 ^1 S
例如:要读出站号为5的PLC的X40到X44共5点的状态值,延时100毫秒,假设PLC中X40与X43为OFF,其余为ON,则指令数据如下:
4 s# E! m. S1 a9 R+ |7 I0 Z: K注释: 请求 站号 PLC号 命令 延时 元件首地址 元件数量 和校验0 X- z6 Q, X! g5 Y
代码: ENQ 0 5 F F B R A X 0 0 4 0 0 5 4 7
4 E/ \: s9 i* G& C9 i& RASCII码: 05H 30H 35H 46H 46H 42H 52H 41H 58 30H 30H 34H 30H 30H 35H 34H 37H
/ Z" o6 Z- l) B; s只要将以上代码以字符串形式(VB中可以表示为chr(5)&”05FFBRAX00400547”)发送到PLC,就会有正确的回应信息,如下:
- l7 }. {* S: r. S注释: 头 站号 PLC号 位元件状态值 尾 和校验4 h) V* G+ q9 T! z* ]# ~4 X8 ^4 F
代码: STX 0 5 F F 0 1 1 0 1 EXT E 7
! D: Q# ~2 k; MASCII码: 02H 30H 35H 46H 46H 30H 31H 31H 30H 31H 03H 45H 37H
3 z+ m2 W1 ^# r2 d2) 批量读出字元件—WR指令格式9 v% O% i2 J* ~
1 2 3 4 5 6 7 8 15 16 17
9 A6 E0 w1 l) D0 [4 P7 j" IPC侧: ENQ 站号 PLC号 WR 延时 首地址 数量 和校验 ACK 站号 PLC号
2 S6 k; p$ L& R& _! M# ~! gPLC侧: STX 站号 PLC号 数据 EXT 和校验
6 f- U8 y# f: V7 P! x7 M5 W j; A: { 9 10 11 12 13 14 R: q2 q; O$ @% C9 n7 G
该命令使用与BR命令相同。
t5 j- ~2 V4 r5 x- B3) 批量写入位元件—BW指令格式 6 T! V3 `) D0 N
1 2 3 4 5 6 7 8 9
5 o3 Y# J+ \/ C. T" {PC侧: ENQ 站号 PLC号 BW 延时 首地址 数量 写入值 和校验
5 W1 d! K3 r- c8 ^6 _7 EPLC侧: ACK 站号 PLC号# R( J/ b' s$ c h, r* D- W
10 11 12
6 X9 K2 T/ f/ h- b4) 批量写入字元件—WW指令格式7 A; @# i$ d7 j9 k
1 2 3 4 5 6 7 8 9
$ v9 O, Z, d6 g9 uPC侧: ENQ 站号 PLC号 WW 延时 首地址 数量 写入值 和校验
1 \' H6 A9 a) o$ _( vPLC侧: ACK 站号 PLC号( V( t7 m9 l3 j `5 h! P5 X! ?
10 11 12
" V- w6 B* X! T" e& q2 ^% P6. VB通讯功能块设计分析) g7 J( `0 D& m" \2 `2 s/ W: U
根据三菱PLC的通讯指令格式,在PC中编写数据查询功能块RevData( )和数据发送功能块SendData( ),就可以在定时中断处理块TIMER1( )中调用查询功能块RevData( ),实现PC界面数据定时刷新;在每一次操作命令执行时,调用数据发送功能块SendData( ),把控制值写入PLC中,从而实现控制。下面给出这两个功能块的设计程序。
d, _9 U/ L K% l: o+ Z9 q8 J {1) 查询数据函数RevData( )
( u6 @: b+ H8 k# l# V1 P! y2 c(没有和校验)
9 P% j+ K, |1 e" ?5 q9 aSub RevPLC (iNo As String, iType As String, iAdd As String, iNum As String)4 m. ?$ J, x3 I; N% r* n' h" y
'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量2 q& f$ d' C+ m: _/ i
Dim Stmp As String
+ E- m3 ^, G# e5 c# `Dim cha, j As Integer2 Y2 w4 d, W5 L2 y9 b
Dim ChaCount As Integer: q. K4 N9 ]) R7 [+ M
Dim Comm As String
" `4 d0 R9 |$ S7 b! nSelect Case iType
1 Y( M. ~3 \) l4 |Case "D" ''查询数据寄存器的值
0 l7 _- ^5 j" ]$ y- b3 jComm = "WR" ''命令类型:数据字读
$ g% r8 i; U- echa = Val("&H" & iNum) * 4 ''数据寄存器的值为十六进制表示,占4个字符
. v4 O# I1 c9 T8 ECase "M", "X", "Y" ''查询继电器触电的值# U; O, i& S! F9 v
Comm = "BR" ''命令类型:二进制位读( o" u# ~1 E$ M
cha = Val("&H" & iNum)6 G p3 R: K. y: q& f0 C
End Select
: \6 p. Z4 N& l- k: n, KiAdd = Right$("000" & iAdd, 4); O) g! r* \: L
iNum = Right$("0" & iNum, 2)
, W0 |" l7 f0 c! R& EStmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum ''输出命令格式
. K2 H0 s9 p' {9 f/ SChaCount = 6 + cha ''要返回字符个数% k( Z' b$ j- u' o( Z
main.MSComm1.InBufferCount = 0 ''输入缓冲区清零* s$ b$ j: `+ Q# V
main.MSComm1.Output = Stmp ''设传送缓冲区内容为命令格式1 Y0 v, b. g: j( b, A
Now=Second()
/ j! @# E! i! U- q+ o! w+ rDo
% G& A: m7 e3 T% S- ]% vDoEvents ''转让控制权,以便让操作系统进行数据传输
E, ~/ F/ l# V% p; P; fIf Second()-Now>1 Then Exit Sub
4 f% \/ a+ E5 k! `Loop Until main.MSComm1.InBufferCount = ChaCount ''当接收到规定字符时停止循环% r8 U. K% r3 P) `
RevDataTmp = Mid$(main.MSComm1.Input, 6, cha) ''返回数据字符串保存在全局变量
+ a- w% l7 Z# M* Y) L) d''RevDataTmp中) I m8 ]) j3 {% P0 f
End Sub: V9 l$ \ v0 u7 u& m+ J# x6 D
2) 发送数据函数SendData( )) P3 d0 L N- g+ e4 ^
(没有和校验)
/ q9 D% ` |9 {: \4 h8 I; Q# B% J( iSub SendPLC(iNo As String, iType As String, iAdd As String, iNum As String, iValue As String)
$ l$ b+ m4 Y* m- i, R'' iNo为PLC站号,iType为元件类型,iAdd为首地址,iNum为元件数量,iValue为写入值
% Z, w" V, N: G' H- QDim Stmp As String1 n6 U5 B, z7 C8 x: M8 E/ h
Dim Comm As String
# \$ i7 u9 |4 s. Z! bSelect Case iType# B& w& P2 ]! Z s5 {, d' B
Case "D" ''写数据寄存器的值: K) O( `0 G- Y
Comm = "WW" ''命令类型:数据字写. {( H3 q# T; m4 L
iValue = Right$("0000" + Hex$(Val(iValue)), 4) ''写入值转换成十六进制表示
5 T/ D8 T" A, c, J7 k! yCase "M" ''写继电器触点的值& u7 J3 ~4 X& x2 C% {
Comm = "BW" ''命令类型:二进制位写7 x6 ?$ V) I9 @! K6 E4 S1 E
End Select
- V5 U+ @! k& E/ E: d- uiAdd = Right$("000" & iAdd, 4)1 j; I2 g# x5 f& }
iNum = Right$("0" & iNum, 2)
6 H9 d" i2 ]4 E0 @0 @- R+ |5 g9 NStmp = Chr$(5) & iNo & "FF" & Comm & "A" & iType & iAdd & iNum & iValue ''输出命令格式
* y5 B9 P. b( h+ v- @' _' G2 qMSComm1.Output = Stmp ''输出命令到传送缓冲区$ J+ i5 z Z/ [4 {. l
Now= Second(). r. k1 I' J9 d) {4 L
Do
2 L% [$ A& O# z7 zDoEvents ''转让控制权,以便让操作系统进行数据传输
. h8 z' Z2 i* o% k+ ~0 @! m$ LIf Second()-Now>1 Then Exit Sub
: E" x# ~/ c9 S) ]5 Y5 RLoop Until main.MSComm1.OutBufferCount = 0 ''当命令传送完时停止循环8 f8 P1 j$ y7 I: N% s% @& |
End Sub |
评分
-
查看全部评分
|