基于VC++和MFC的上位机与PLC的通讯系统

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

 

关键词:PLC VC++ MFC 通讯模式

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所示。

 


图1 通讯系统原理

 

  CPU226自带的通讯口RS485采用半双工通讯,只需用两根数据线TXD和RXD来发送数据和接收数据,所以通讯中没有硬件握手信号,而只能采用软件握手的通讯方式保持数据传输的同步。为了保证通讯的安全性,必须对发送的数据帧中加入帧校验码(FCS),采取的方法是:把所发送的数据帧中的数据按照字节进行异或运算后得到的FCS连同数据一起发送。接收方收到后,进行同样的运算,并把结果与FCS比较,如果两者不相等,则认为传输数据出错。对于检验到出错的数据采取放弃的措施,并立即发送反馈信号要求发送方重发数据。因此上位机和PLC发送数据的格式分别为表1和表2所示。控制命令如请求、应答等信号另有则不必加上校验码。

  表1上位机数据格式

 

  表2 PLC数据格式

 

3 系统的软件设计

  3.1系统的控制流程

  整个通讯由上位机触发开始,首先由上位机发送握手信号,PLC接收到握手信号后,发送回握信号;上位机收到回握信号,则开始发送请求指令,PLC收到指令后发送数据给上位机;上位机收到数据进行校验,出错则要求PLC重发,没有错误则处理输出显示。下面图2和图3分别就是上位机和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)应用向导建立一个基于对话框的应用程序ScommTest。

 


图4 通讯界面

 

  (2)在项目中插入MSComm控件:选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项,选择Microsoft Communications Control version 6.0,单击Insert按钮将它插入到Project中来,接受缺省的选项。

  (3)在对话框中添加控件:向主对话框中添加通讯控件、按钮、文本框、编辑框和组合框,其中部分属性如表3所示。

  表3控件属性表

 

  (4)初始化串口:在OnInitDialog()函数中添加初始化串口参数的代码

  // TODO: Add extra initialization here

  if(m_ctrlComm.GetPortOpen())

  m_ctrlComm.SetPortOpen(FALSE);

  m_ctrlComm.SetCommPort(1); //选择com1

  if( !m_ctrlComm.GetPortOpen())

  m_ctrlComm.SetPortOpen(TRUE);//打开串口

  else

  AfxMessageBox("cannot open serial port");

  m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位

  m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据

  m_ctrlComm.SetRThreshold(16); //参数15表示每当串口接收缓冲区中有多于或等于15个字符时将引发一个接收数据的OnComm事件

  m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0

  m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据

  (5)编写帧校验函数:首先在CSCommTestDlg类中加入公共成员函数说明

  BYTE PLCData[30];//定义输入数据存储区

  Void verfun(BYTE vdata[],int n);//定义校验函数

  然后写帧校验函数:

  void CSCommTestDlg::verfun(BYTE vdata[],int n)

  {

  int i;

  BYTE sum=vdata[0];

  for(i=1;i<=n-2;i++)

  sum︿=vdata[i];//计算校验码

  vdata[n]=sum;//保存帧校验码

  }

  (6)为通讯控件IDC_MSComm1添加OnComm消息处理函数OnComm()

  void CSCommTestDlg::OnComm()

  {

  VARIANT variant_inp;

  COleSafeArray safearray_inp;

  LONG len,k;

  BYTE rxdata[2048]; //设置BYTE数组(8位无符号整数)

  CString strtemp;

  if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符

  {

  variant_inp=m_ctrlComm.GetInput();//读缓冲区

  safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量

  len=safearray_inp.GetOneDimSize(); //得到有效数据长度

  for(k=0;k 

  safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组

  for(k=0;k 

  {

  PLCData[k]=rxdata[k];

  }

  verfun(PLCData,16);//计算校验码

  if(PLCData[15]==PLCData[16])

  { //接收数据正确发送确认信号

  m_ctrlComm.SetOutput(COleVariant(“K@”));

  //可以在下面自行加上对数据的处理

  if(!m_quit)//如果没有结束信号则续传数据

  m_ctrlComm.SetOutput(COleVariant(“C@”));

  else

  m_ctrlComm.SetOutput(COleVariant(“Z@”));

  }

  else //接收数据出错要求重发数据

  m_ctrlComm.SetOutput(COleVariant(“R@”));

  (7)为按钮IDC_BUTTON_START和IDC_BUTTON_QUIT添加消息处理函数OnButtonStart()和OnButtonQuit()

  void CSCommTestDlg::OnButtonQuit()

  {

  m_quit=TRUE;

  }

  void CSCommTestDlg::OnButtonStart()

  {

  m_quit=FALSE;

  m_ctrlComm.SetOutput(COleVariant("A@"));

  //发送请求信号

  }

4 结束语

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

参考文献

  [1] 李志虎等.基于Visual C++的上位机和PLC的通信实现.计算机工程,2000(8)

  [2] 朱正礼等.基于VC++的PLC与上位机的通讯.电气传动,2002(2)

  [3] 西门子有限公司.西门子S7-200可编程序控制器系统手册,1999

  • 7
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值