基于VC++和MFC的上位机与PLC的通讯系统
字体放大 字体缩小 字体恢复 杏仁黄 秋叶褐 胭脂红 芥末绿 天蓝 雪青 灰 银河白(默认色)
 


  摘要:本文介绍了用VC++和MFC开发的上位机和PLC的通讯系统,给出了系统的通讯原理和系统的软件设计方法。实践证明整个系统运行稳定,实用性和可扩展性强。
  关键词:PLC;VC++;MFC;通讯模式

  Abstract:This paper introduces the communication system between host computer and PLC using VC++ and MFC to develop. Its communication principle and software design method are given in the paper. In practice the system is reliable and easy to extend and has good application value.
    Key words:PLC; VC++; MFC; communication mode

1 概述
  PLC(Programmable Logic Controller)作为新一代工业控制器,以其高性能价格比在工业测控系统中获得了广泛应用。随着微电子及控制技术的不断发展,PLC已逐渐成为一种智能型、综合型控制器,由PLC构成的集散控制是现代工业控制的一个重要组成部分。在众多的小型集散控制系统中,若使用专业工控组态软件,如INTOUCH、FIX等,制作上位机的监控界面,而以专用的PLC通信接口模块以及其厂家推荐的DDE Server作为联系上位机和PLC的桥梁,则成本较高、投资较大。所以上位机直接与PLC的通讯是一种很好的技术方案。
  在Windows环境下开发与工业PLC通讯,可以利用C并借助Windows SDK提供的应用程序接口函数来完成软件的设计,但这样开发的程序很复杂;也可以利用Visual Basic提供的通讯控件来开发串行通讯程序,程序的编制十分简单,但在现实中,许多大的应用系统都是基于VC++平台开发的,VC++是现今最复杂、但也是最强大的一种Windows应用程序开发工程软件。它在图形处理和数据库管理等方面具有较强的优势,并且用它来实现底层的通讯控制有着更快的效率,使用MFC设计的界面与Visual Basic设计的界面一样简练。因此我们利用VC++6.0提供的通讯   MSComm,以MFC来设计界面编制程序,构造与PLC的通讯系统。系统中的PLC为西门子公司的S7-200系列CPU226型。
2 系统的通讯原理
  西门子S7-226型PLC是一种模块化结构的小型PLC,具有较高的性能价格比,它带有两个RS485通讯口,而上位机即工控机的串行口是RS232,所以采用西门子公司专用的PC/PPI编程电缆作为上下位机的连接电缆,它实现了RS232和RS485的转换,并且具有隔离抗干扰功能。整个系统原理图如图1所示。
  CPU226自带的通讯口RS485采用半双工通讯,只需用两根数据线TXD和RXD来发送数据和接收数据,所以通讯中没有硬件握手信号,而只能采用软件握手的通讯方式保持数据传输的同步。为了保证通讯的安全性,必须对发送的数据帧中加入帧校验码(FCS),采取的方法是:把所发送的数据帧中的数据按照字节进行异或运算后得到的FCS连同数据一起发送。接收方收到后,进行同样的运算,并把结果与FCS比较,如果两者不相等,则认为传输数据出错。对于检验到出错的数据采取放弃的措施,并立即发送反馈信号要求发送方重发数据。因此上位机和PLC发送数据的格式分别为表1和表2所示。控制命令如请求、应答等信号另有则不必加上校验码。


3 系统的软件设计
3.1系统的控制流程
  整个通讯由上位机触发开始,首先由上位机发送握手信号,PLC接收到握手信号后,发送回握信号;上位机收到回握信号,则开始发送请求指令,PLC收到指令后发送数据给上位机;上位机收到数据进行校验,出错则要求PLC重发,没有错误则处理输出显示。下面图2和图3分别就是上位机和PLC的通讯程序流程图。


3.2 PLC软件设计
  S7-200系列PLC有两种通讯模式:一种是点对点(PPI)通讯模式,另一种是对用户完全开放的自由口通讯模式(free port mode),PPI模式用于PLC间直接连接的通讯,可以组成网络,自由口模式应用于PLC与计算机间以及PLC间无线通讯等方面。本通讯系统采用自由口通讯模式。在通讯之前通过改写SMB30或SMB130来选择通讯模式,设定波特率以及数据长度和校验位。对于数据发送,采用专用发送指令XMT TABLE, PORT,其中TABLE为发送缓冲区的首地址,首地址中保存要发送的字节数,即数据长度,最大为255,其后的地址中保存要发送的数据,PORT指定用于发送的端口。对于数据接收,使用接收指令RCV TABLE, PORT,接收指令激活初始化或结束接收信息,通过指定端口(PORT)接收信息并存储于数据缓冲区(TABLE),数据缓冲区的第一个数据指明了接收的字节数。在西门子PLC编程语言中,共有33个中断事件,其中用于通讯口的中断事件就有6个。在通讯过程中,我们利用中断来实现发送数据和接收数据的切换,当数据发送完成,会产生发送字符中断事件,在中断程序中切换到接收状态;当接收数据完成,会产生接收信息完成中断事件,在中断程序中切换到发送状态,由于收发切换有一定的间隔,所以必须延时一段时间再发送数据,我们用定时中断来产生延时。为了产生接收信息完成中断事件,必须要对RCV指令设定结束信息作为判断接收完成的条件,通过向SMB89或SMB189中装入字符来设置,这个字符必须与上位机发送来的结束信息相吻合。
以下是PLC的部分程序:

MAIN(主程序)
NETWORK 1
LD      SM0.1
MOVB    16#09, SMB30//初始化自由端口,选择9600波特率,8位数据,无校验
MOVB    16#A0, SMB87//RCV允许,检测信息结束字符
MOVB '@',SMB89//设定信息结束字符为'@'
MOVB    10, SMB94//设定最大字符数为10
MOVB    5, SMB34 //定时中断0为5ms
ATCH    0,23//接收完成事件连接到中断0
ENI//允许全局中断
NETWORK  2
RCV     VB300, 0//接收数据
NETWORK  3
LD      SM0.0
MOVB    16,VB200//发送16个字符
MOVD    16#4521347E, VD201//以下是实验数据
MOVW    +9860, VW205
MOVD    16#12345678, VD207
MOVW    +10562, VW211
MOVW    +8568, VW213
MOVB    8, VB215
CALL    SBR_0
INT_0  (中断0子程序)
NETWORK 1//如果接收到的字符为'K',则继续接收
LDB=    VB302, 'K'
RCV     VB300,  0
NETWORK 2 //如果接收到的字符为'A'、'C'或者'R',则发送数据
LDB=    VB302, 'A'
OB=     VB302, 'R'
OB=     VB302, 'C'
ATCH    INT_1, 10//启动定时中断
NETWORK 3   //如果接收到的字符为“Z”,则停止延时发送
LDB=    VB302, 'Z'
DTCH    10
INT_1 (中断1子程序)
LD      SM0.0
XMT     VB200, 0//发送数据
DTCH    10//关定时中断
3.3 上位机软件设计
  系统中上位机的软件部分利用VC++提供的通讯控件MSComm,以MFC为基础编制通讯程序。MSComm通讯控件提供了使用RS232开发串行通讯软件的细则,它使用事件驱动或查询方式来解决开发通讯软件中遇到的问题。事件驱动是一种功能强大的处理问题的方法,对事件发生的跟踪和处理在通讯控件中是用  OnComm来实现的,它包括检测和处理通讯错误以及数据的处理显示等。为了清楚了解现场的工作状态,可以在界面上实时显示摄像机观察到的内容,为此,需要对图像采集卡采集到的图像进行分析处理,这里就不再详述。图4为通讯界面。
程序设计方法如下:
(1) 建立项目:启动VC++6.0,利用MFC AppWizard(exe)应用向导建立一个基于对话框的应


(2) (2)在项目中插入MSComm控件:选择Project菜单下Add To Project子菜单中的 Components and Controls...选项,在弹出的对话框中双击
Registered ActiveX Controls项,选择Microsoft Communications Control  version 6.0,单击Insert按钮将它插入到Project中来,接受缺省的选项。
(3) (3)在对话框中添加控件:向主对话框中添加通讯
(4) 控件、按钮、文本框、编辑框和组合框,其中部分属性如表3所示。


4)初始化串口:在OnInitDialog()函数中添加初始化串口参数的代码
(7) // TODO: Add extra initialization here
(8) if(m_ctrlComm.GetPortOpen())
(9)   m_ctrlComm.SetPortOpen(FALSE);
(10) m_ctrlComm.SetCommPort(1); //选择com1
(11) if( !m_ctrlComm.GetPortOpen())
(12)   m_ctrlComm.SetPortOpen(TRUE);//打开串口
(13) else
(14)  AfxMessageBox("cannot open serial port");
(15) m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位
(16) m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据
(17) m_ctrlComm.SetRThreshold(16); //参数15表示每当串口接收缓冲区中有多于或等于15个字符时将引发一个接收数据的OnComm事件
(18) m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
(19) m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据
(20) (5)编写帧校验函数:首先在CSCommTestDlg类中加入公共成员函数说明
(21)  BYTE PLCData[30];//定义输入数据存储区
(22)  Void verfun(BYTE vdata[],int n);//定义校验函数
(23)  然后写帧校验函数:
(24) void CSCommTestDlg::verfun(BYTE vdata[],int n)
(25) {
(26)    int i;
(27)    BYTE sum=vdata[0];
(28)    for(i=1;i<=n-2;i++)
(29)       sum^=vdata[i];//计算校验码
(30)    vdata[n]=sum;//保存帧校验码
(31) }
(32) (6)为通讯控件IDC_MSComm1添加OnComm消息处理函数OnComm()
(33)    void CSCommTestDlg::OnComm()
(34) {
(35) VARIANT variant_inp;
(36) COleSafeArray safearray_inp;
(37) LONG len,k;
(38) BYTE rxdata[2048]; //设置BYTE数组(8位无符号整数)
(39) CString strtemp;
(40) if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
(41) {
(42) variant_inp=m_ctrlComm.GetInput();//读缓冲区
(43) safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
(44) len=safearray_inp.GetOneDimSize(); //得到有效数据长度
(45) for(k=0;k<len;k++)
(46) safearray_inp.GetElement(&&k,rxdata+k);//转换为BYTE型数组
(47) for(k=0;k<len;k++)//将数组转入存储区
(48) {
(49)    PLCData[k]=rxdata[k];
(50) }
(51) verfun(PLCData,16);//计算校验码
(52) if(PLCData[15]==PLCData[16])
(53) { //接收数据正确发送确认信号
(54)   m_ctrlComm.SetOutput(COleVariant("K@"));
(55)     //可以在下面自行加上对数据的处理
(56) if(!m_quit)//如果没有结束信号则续传数据
(57)   m_ctrlComm.SetOutput(COleVariant("C@"));
(58)   else
(59)   m_ctrlComm.SetOutput(COleVariant("Z@"));
(60) }
(61) else //接收数据出错要求重发数据
(62) m_ctrlComm.SetOutput(COleVariant("R@"));
(63) (7)为按钮IDC_BUTTON_START和IDC_BUTTON_QUIT添加消息处理函数OnButtonStart()和On
(64) ButtonQuit()
(65)   void CSCommTestDlg::OnButtonQuit()
(66) {
(67)   m_quit=TRUE;
(68) }
(69)   void CSCommTestDlg::OnButtonStart()
(70) {
(71)   m_quit=FALSE;
(72)   m_ctrlComm.SetOutput(COleVariant("A@"));
(73)     //发送请求信号 
(74) }

4 结束语
  本文运用VC++和MFC开发了计算机与PLC的通讯系统,充分利用计算机和PLC本身的资源实现了上位机对PLC的实时监控,可以有效地对作业工具进行监控和管理。本文介绍的通讯系统用于超高压带电作业机器人的控制系统,实践表明,系统简练、稳定,取得了令人满意的效果。

参考文献:
[1]朱正礼等.基于VC++的PLC与上位机的通讯.电气传动,2002(2).
[2]西门子有限公司.西门子S7-200可编程序控制器系统手册,1999.

作者简介:杨东海(1977—),男,江苏省新沂市人,上海交通大学机械电子工程专业在读硕士生,研究方向为机器人、机电系统控制。电话:021-62933894,(0)13916682471,E-mail:ydonghai@sjtu.edu.cn。翁新华,1954年生,女,上海市人,高级工程师,研究方向为机器人、机电控制。杨汝清,1944年生,男,江苏人,上海交大教授、博导,主要从事机器人学、智能控制和生产线规划等方面的研究。
(200030  上海市上海交通大学机器人研究所)杨东海  翁新华  杨汝清
通信地址:(200030 上海交通大学B0006093班)杨东海










    来源:中国自控网
日期:2005年11月15日   来源: 
相关文章:
·用超低功耗MSP430单片机设计数据采集系统 2005-06-27
·Atmega16在开关磁阻电机调速系统中的应用 2005-06-28
·火灾探测器受干扰的原因及改进方法 2005-07-02
·特殊构件的焊接技术 2005-10-18
·触摸屏的工作原理及典型应用 2005-11-25
·高质量C++/C编程指南---类的构造函数,析构函数,赋值 2005-12-13
·基于ATmega8的新型电动自行车调速控制系统设计 2005-12-20
·电子产品高温老化的原理以及一间智能温控老化室的应用 2006-01-05
·新近成功开发无霍尔传感器无刷电机控制器 2006-01-20
·归纳一下最近比较流行的电动自行车技术 2006-01-23
·电子工作台 --- workbench 电子仿真软件 2006-05-23
·液晶字模工具 ------ HZDotReader V3 2006-05-23
·51系列单片机仿真软件----伟福e6000w  2006-05-23
·无传感器无刷电机驱动控制器系统的优点 2006-06-10
·PIC单片机C语言编译器 --PICC 8.05 完整破解版 2006-07-09