当前位置:文档之家› 基于VC++和MFC的上位机与PLC的通讯系统

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

基于VC++和MFC的上位机与PLC的通讯系统
基于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所示。

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)应用向导建立一个基于对话框的应用程序ScommTest。

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

(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()和On

ButtonQuit()

void CSCommTestDlg::OnButtonQuit()

{

m_quit=TRUE;

}

void CSCommTestDlg::OnButtonStart()

{

m_quit=FALSE;

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

//发送请求信号

}

4 结束语

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

相关主题
文本预览
相关文档 最新文档