一.简介
随着我国工业的自动化整体水平的提高,企业中的控制系统及控制设备的种类也越来越多;同时,随着市场经济的发展,各个企业也对DCS系统的要求也越来越高,除了要满足常规的控制以外,还要求DCS系统能将控制系统的各个运行参数实时传送到上位的MIS系统或SIS系统中去,进行数据后处理加工、共享、性能优化。所有的这些,都对DCS系统提出了通讯问题,包括和其它DCS或PLC的通讯、以及与上位机的通讯。
在谏壁发电厂的四台300MW机组(7#、8#、9#、10#)的DCS改造中,全部采用的Foxboro公司的I/A’s系统,与I/A’s通讯的装置有893类智能数据采集前端、锅炉高过壁温分析系统、基于PC机的实时报表数据库系统、PI海量数据库(SIS系统),几乎涵盖了DCS系统与其他系统进行通讯的所有方式:使用专业通讯硬件实现通讯、使用专业通讯软件实现通讯、自行开发通讯程序(包括:串口通讯、TCP/IP通讯、FTP通讯、基于TCP/IP的MODBUS协议通讯)。
下面,将对以上几种通讯方式的实现做一个简单介绍并比较,给出在选择通讯方式时的几点建议。
二.利用硬件实现通讯
对于市场上广泛使用的A-B公司PLC产品,Foxboro公司专门开发专用的通讯硬件--集成在I/A’s中的AB-STATION,通过AB-STATION,在I/A’s中可以直接对A-B的PLC进行管理、组态、通讯及数据采集监视,使整个系统既具有PLC快速的优点,又具有DCS系统友好的人机界面,强大的数据库管理的优势。
对于工业界广泛采用的MODBUS协议(含ASCII协议及RTU协议),Foxboro公司开发了多种符合MODBUS协议的硬件,主要有:MODBUSGATEWAY,MODBUSGATEWAYPLUS,适用于RS-232通讯及RS-485通讯,并可以选择做为仆方或主方。采用专门的通讯硬件,可以与一切提供MODBUS协议通讯接口的设备进行通讯,包括其它公司的DCS系统、PLC产品等。在上海Foxboro公司所实施的大部分需要进行通讯的项目中均采用这种方式。
除以上两种专门通讯硬件外,Foxboro公司还有一个可以自定义协议的通讯硬件—FOREIGNDEVICEINTIGRATOR30(设备集成器30)。使用此通讯硬件,需要通讯的双方只要定义好通讯数据包格式(包括数据包报头信息、数据格式、数据包报尾信息)和通讯参数(包括起始位、停止位、数据位、波特率)即可实现通讯。在镇江电厂项目中,上海Foxboro公司就采用这个方法实现了与GEPLC及无锡阳山智能数据采集前端的通讯,大大减少了用户的投资。
此外,对于市场上使用较多的PLC和DCS产品,Foxboro公司提供专门的通讯软件进行通讯。
以上所有的通讯方式所采用的硬件是一样的:通讯处理机30(COMMUNICATIONPROCESSOR30),不同之处在于所选用的通讯软件不一样。
对于MODBUS协议,采用的波特率通常为9600bps,因此每秒所能通讯的数据包是有限制的。
对于MODBUS协议,如果MODBUS设备不同,每个通讯包所能通讯的量是不一样的,通常使用的548设备可以通讯到256个字节,亦即128个模拟量或2048个数字量。
标准的MODBUS通讯帧格式为:“〈仆方地址〉〈功能码〉〈起始地址〉〈数据传送量〉〈校验码〉”。对于不同的设备具有不同的MODBUS地址;同一设备,不同数据类型(外部寄存器、内部寄存器、外部保持线圈、内部保持线圈等)具有不同的功能码;同一数据类型,读/写操作不同时,也具有不同的功能码。
因此,在考虑MODBUS协议通讯时,不能只看有多少个模拟量/数字量,而必须同时考虑:有多少个设备,每个设备的通讯模拟量/数字量数据有多少,数据是否双向传送,通讯速率为多少。综合考虑以上因数后,计算出需要多少个通讯处理器。
需要强调的是:Foxboro公司的硬件通讯产品COMM30与许多公司的硬件通讯方式通过采用插在工程师站/操作员站主板上的串口通讯卡实现不同,Foxboro公司的COMM30具有专用的CPU芯片,独立于工程师站及操作员站运行,是控制网络中一个独立的处理站,即使在工程师站/操作员站死机时仍能保证通讯的正常运行,这在参与控制的通讯(如与定排程控、吹灰程控等)中显的尤为重要。
三.用专业通讯软件实现通讯
专业的通讯软件主要分为两类:一类实现数据的实时采集与传送,另一类实现流程画面的实时传送。
3.1数据的实时采集及传送
用Foxboro公司开发的通讯软件或利用第三方开发的针对I/A’s的通讯软件实现通讯是一种非常方便的办法,它可以大大缩短项目周期。
Foxboro公司的专业通讯软件从早期的DataforWindow、PIMS中的DataLink到现在使用的AIM*AT软件秉承始终如一的思想,利用AISAPI(FOXAPI的早期版本),FOXAPI的内部函数调用实现数据的实时读写;利用TCP/IP实现数据在I/A’s与PC机之间的双向传送;利用DDE技术将I/A’s的数据在支持DDE技术的程序(如:Excel、Lotus1-2-3、Delphi等)中显示,同时提供VB调用函数,便于用户的二次开发。该软件的最快传送速率为0.1秒。在目前的项目中,比较多的采用了这种办法。
对于目前较流行的OPC通讯协议,Foxboro公司提供专门的OPC通讯软件,同时也可以选用第三方,如:MATRICON公司的OPC通讯软件。
第三方通讯软件主要是美国OSI公司的PI实时数据库。OSI公司的PI系统基于C/S结构,能将100多家的DCS系统或PLC中的实时数据传送到WindowNT服务器中,利用其专利的“螺旋门压缩”技术,将数据进行压缩加工,使其保存周期可长达数年以上(取决于硬盘容量)。同时,利用其强大的系统工具实现二次开发,包括流程画面显示、趋势显示、优化处理、性能计算等。PI实时数据库在Foxboro的I/A’s中的应用在国外已经有了上百个成功使用的业绩。谏壁发电厂利用PI系统将其#7、#8、#9、#10四台300MW机组多达20,000点的数据实现了实时传送、长达2年的数据存储,并利用其强大的二次开发工具,为全厂MIS(或SIS)系统的应用开发服务。
专业的通讯软件,如:PI,除了具有高率、高速、数据保存时间长、安全可靠、功能强大、界面友好、使用方便等优点外,通常在数据传送时还具有以下特性:
l采用“例外报告”方式:设定数据需要传送的变化范围,对未超过变化范围的数据不传送,这一机制大大降低了通讯负载。
l具有“数据缓存”机制:在网络通讯中断时,将需要传送的数据缓存在工作站的硬盘上,待网络通讯恢复时,在网络通讯的空闲时再将数据传送到数据库中。这一机制保证了数据不丢失。
3.2流程画面的实时传送
将流程画面实时传送到PC机上,可以使企业领导和运行管理人员、热工仪表维护人员可以及时掌握现场的生产运行情况,便于整个企业的资源共享、状态监视及物流管理。
关于流程画面的实时传送,目前使用较多的是使用HumingBird公司的Exceed软件。利用Exceed软件的Telnet功能和I/A’s的附加显示管理器(AdditionalDisplayManager),将I/A’s中的流程画面实时传送至PC机中,并可以定义在PC机中的操作权限是否可以操作。
除Exceed软件外,还可以使用GraphOn公司的GO_Global软件,该软件可以直接利用网络传输,也可以用拨号方式,将I/A’s中的流程画面实时传送至PC机中。
在使用Exceed及GO_Global软件时,利用Modem拨号,就可以实现“远程诊断”(FOXWATCH),即:将I/A’s使用情况等信息,及时传送回Foxboro公司,Foxboro公司的工程技术人员在公司内就可以对用户的各种要求进行及时响应,对其系统进行诊断,并对用户提出使用建议。在谏壁发电厂的I/A’s系统中,就安装有FOXWATCH软件,使用效果非常好,厂级领导、热工维护人员等在办公室内即可了解机组生产运行情况;在出现故障时,可以迅速将DCS系统使用情况传送给Foxboro公司的工程技术人员,在最短的时间内得到技术支持,最大程度地降低损失。
无论是采用专门的硬件实现通讯,还是使用专业的通讯软件实现通讯,实现方法都比较简单,下面将重点介绍在Foxboro公司I/A’s产品中用软件编程方法实现通讯的几种方法。
四.利用软件编程实现通讯
利用软件编程方式,可以更加灵活实现各种非常规的通讯。
由于自行编写的程序在工程师站/操作员站运行,需要占用一定的CUP时间及内存,因此在通讯数据量较大,同时要求通讯速度较快时,由于没有专业通讯软件的“例外报告”机制,建议不要采用自行开发程序的办法。
由于自行编写的程序通常没有“数据缓存”机制,在传送非常重要的数据时应该谨慎使用。
自行编程主要工作为了两方面,一为I/A数据的读写及处理,一为通讯的实现。
通常自行开发通讯软件包括:串口通讯(如智能前端)、TCP/IP通讯(如实时数据传送)、FTP通讯(如定期传送报表文本)、基于TCP/IP的MODBUS协议通讯。
以上几种通讯方式在通讯的实现方式上不同,但在I/A’s内数据的读写操作是一样的,接下来将阐述软件编程时的主要函数及方式:
4.1I/A’s数据的读写及处理
Foxboro公司I/A’s系统提供强大的内部编程函数(C函数、FORTRAN),主要包括有:
lOMCALL函数–实现I/A’s系统内部数据的读写操作。
主要函数有:
2intgetval(char*name,intobj_type,intimport,char*value,unsignedint*status,intdata_len)
此函数实现单个数据的读操作。
2intom_getval(char*name,intobj_type,intimport,charvalue,unsignedint*status,intdata_len,PSAP_ADDR*psap_ptr)
此函数实现单个数据的读操作,它使用PSAP指针。
2intsetval(char*name,intobj_type,intimport,char*value,unsigned*status,intdata_len)
此函数实现单个数据的写操作。
2intom_setval(char*name,intobj_type,intimport,char*value,unsigned*status,intdata_len,PASP_ADDR*psap_ptr);
此函数实现单个数据的写操作,它使用PSAP指针。
2intomopen(structom_header_node*om_descriptor,intopen_id)
此函数实现打开一个LIST,为数据的读写操作做准备。
2intomread(intomopen_id,intsize_list,structvalue*var_list)
此函数实现从打开的LIST中读取数据。
2intomwrite(intomopen_id,intsize_list,structvalue*var_list);
此函数实现向打开的LIST中写数据。
2intomclose(intopen_id,structom_header_node*header,structopen_var*var_list,structnet_addr*addr_tbl)
此函数实现关闭一个已经打开的LIST。
2头部文件、OM结构及例程
#include
#include
#include
#include
#include
main()
{
structopen_varin_var_list[8];
structheader_nodein_om_desc;
structnet_adrin_net_adr_tbl[2];
intin_open_id;
intrtn;
floatdelta_temp,delta_fc,delta_df;
structvalue*in_data_list,*temp;
inti;
delta_temp=5.0;
delta_fc=1.0;
delta_df=0.5;
in_om_desc.task_status=OM_R_ACCESS;
in_om_desc.net_adr_tbl_ptr=in_net_adr_tbl;
in_om_desc.size_net_adr_tbl=2;
in_om_desc.open_list_ptr=in_var_list;
in_om_desc.size_open_list=8;
……
}
2特点
使用getval、setval、om_getval、om_setval函数进行编程比较简单,但效率较差;用omopen、omread、omwrite、omclose编程需要复杂的声明,编程比较复杂,但程序通用性好(不要FOXAPI的支持)、效率高。
lFOXAPI函数–实现I/A’s系统内部数据的读写操作及强大的C/S结构编程。
主要函数有:
2intsbopen(int*gw_array,intnument,char*name_array,int*valtyp_array,intacctyp,float*delta_array,intclexit,intrsr,intwsr,float*wdelta_array,int*dset,int*index_array,int*error_array,int*reterr)
此函数实现以连续更新的方式打开一个读写SET。
2intbread(intdset,long*value_array,int*status_array,int*reterr)
此函数实现从一个已经打开SET中读取数据。
2intbwrite(intdset,long*value_array,int*error_array,int*reterr)
此函数实现向一个已经打开SET中写数据。
2intclsset(intdset,int*reterr)
此函数实现关闭一个已经打开SET,释放程序所使用的内存空间,释放对CP中数据的控制权。
2头部函数,FOXAPI结构定义及例程
#include
#include
#include
#include
#include
#include
#include
#defineOBJNUM100
#defineSETNUM20
typedefunion
{
longlval;
shortival;
floatfval;
charbval;
}IAXVAL;
/*PredefinedParameterofI/Avalue*/
staticintgw[SETNUM][OBJNUM];/*GatewayArray*/
charname[SETNUM][OBJNUM][32];/*ObjectNameArray*/
chardesc[SETNUM][OBJNUM][15];/*ObjectdescriptionArray*/
staticintvaltype[SETNUM][OBJNUM];/*ObjectValueTypeArray*/
staticintacctype=1;/*Read-onlyArray*/
staticfloatrdelta[SETNUM][OBJNUM];/*ObjectsReadDeltaArray*/
staticfloatwdelta[SETNUM][OBJNUM];/*ObjectsWriteDeltaArray*/
interror[SETNUM][OBJNUM];/*ObjectsErrorArray*/
intindex[SETNUM][OBJNUM];/*ObjectsIndexesArray*/
intstatus[SETNUM][OBJNUM];/*ObjectsStatusArray*/
IAXVALvalue[SETNUM][OBJNUM];/*ObjectsValueArray*/
staticintrsr=4;/*ReadScanRate*/
staticintwsr=4;/*WriteScanRate*/
staticintclexit=1;/*IgnoredinUNIX*/
intreterr[SETNUM];/*OpenSetreturnErrorCode*/
/*PredefineParameterofutility*/
intset[SETNUM];/*OpenSetNumber*/
intTotal_SET;/*TotalSetNumber*/
intLast_SET_Num;/*LastSetValueNuber*/
intTotal_Num;/*TotalNumberofobjects*/
intTotal_File;/*TotaloutputfilesNumber*/
intINTERVAL;/*Communicateinterval*/
intCol_Num;/*Valuenumberperline*/
main()
{
……scopen(gw[i],k,name[i],valtype[i],acctype,rdelta[i],clexit,rsr,\
wsr,wdelta[i],&set[i],index[i],error[i],&reterr[i]);
printf("ReturnErrorCode=%-d\n",reterr[i]);
printf("ReturnDataSet=%-d\n",set[i]);
……rtn=bread(set[i],value[i],status[i],&reterr[i]);
if(reterr[i]!=0)
{
printf("BufferedReadObjectsError%d,%d,%d\n",rtn,\
reterr[i],set[i]);
}
……for(i=0;i
{
clsset(set[i],&reterr[i]);
}
……
}
2特点
使用FOXAPI编程比较简单,程序效率也很高,但程序的执行需要FOXAPI的支持,编译好的程序只能在装有FOXAPI的AW、AP机器中运行。PI实时数据库实际上便是利用FOXAPI函数编写的应用程序。
lHICALL函数–实现具有I/A’s风格的人机界面(HUMANINTERFACE)编程,包括显示元素,如:矩形、圆弧、填充色;对话框、菜单结构、鼠标键盘驱动、查询、文件驱动等,事实上,整个I/A’s的人机界面编写既是通过这些函数完成。
lIPCALL函数–实现I/A’s系统内部通讯编程,如:SOE软件等。
lICCAPI函数–实现I/A’s控制处理器CP中CIO的相关操作。
l数学库–提供各种经典数值计算的调用函数。
l物理特性库–提供各种物理特性计算的调用函数,包括水、蒸汽的焓、熵等计算。
2intvpt(floatp,floatt,float*v)
此函数根据蒸汽的压力及温度计算蒸汽的容积。
2inthpt_stm(floatp,floatt,float*h)
此函数根据蒸汽的压力及温度计算蒸汽的焓。
2intspt_stm(floatp,floatt,float*s)
此函数根据蒸汽的压力及温度计算蒸汽的熵。
2inthpt_wtr(floatp,floatt,float*h)
此函数根据水的压力及温度计算水的焓。
2intspt_wtr(floatp,floatt,float*s)
此函数根据水的压力及温度计算水的熵。
2inthpt_air(floatp,floatt,float*h)
此函数根据空气的压力及温度计算空气的焓。
2intspt_air(floatp,floatt,float*s)
此函数根据空气的压力及温度计算空气的熵。
lINFORMIX编程。
在某些需要对历史数据进行操作的场合,可以利用INFORMIX及E-SQL进行编程。
4.2通讯的实现
在用软件编程实现通讯时所采用的具体的通讯硬件上,既可以通过串口实现RS-232通讯,也可以通过AUI网卡、BNC网卡、RJ-45网卡实现FTP通讯、TCP/IP通讯。
当与I/A’s通讯的其它设备(如智能数据采集前端、GPS、自动同期装置等非通用设备)可以提供串口通讯,且通讯点数量不多时,采用专门的硬件实现通讯硬件不是一个非常经济的方案,此时可以采用RS-232实现通讯。
用RS-232实现通讯时,首先应初始化通讯端口,然后可以按RS-232通讯规程(RXD,TXD,RTS,CTS,DSR,DTR,DCD信号),发送指令并接受数据。
以下是初始化端口的一段例程:
intinit_port(intk,int*fd,char*comport)
{
intsavef;
if((*fd=open(comport,O_RDWR|O_NDELAY|O_NONBLOCK))<0)
return(1);
fflush(stdout);
fflush(stdin);
if(savef=fcntl(*fd,F_GETFL,0)<0)
return(2);
if(fcntl(*fd,F_SETFL,savef|O_NDELAY)<0)
return(3);
if(ioctl(*fd,TCGETS,&termio)<0)
return(4);
/*Settheportparameteras9600Baudrate,8databits,1siopbit,
Enablereceiver,Evenparityenable*/
termio.c_cflag=B9600|CS8|CREAD|PARENB|CLOCAL;
termio.c_cflag&=~CSTOPB;
termio.c_cflag&=~PARODD;
termio.c_iflag=INPCK;
termio.c_iflag&=~ISTRIP;
termio.c_lflag=0;
termio.c_oflag=0;
termio.c_cc[VMIN]=1;
termio.c_cc[VTIME]=0;
if(ioctl(*fd,TCSETS,&termio)<0)
return(5);
sleep(1);
return(0);
}
以下是读写端口的一段例程:
intcomm(unsignedcharnum,intfd)
{
intI,rtn,tioc;
unsignedcharT[200];
unsignedcharbuff[200];
……ioctl(fd,TIOCMGET,&tioc);
tioc=tioc|TIOCM_RTS;
ioctl(fd,TIOCMSET,&tioc);
……write(fd,T,200);
rtn=ioctl(fd,TCSBRK,1);
strcpy(buf,”“,200);
read(fd,buf,200);
}
如果与I/A’s进行通讯的是PC机或其它DCS,比较好的通讯办法是利用RJ-45等通讯口,按FTP协议或TCP/IP协议进行通讯。其中,FTP通讯的效率较低,且一直有读盘/写盘动作,对机器的影响较大,但此方法比较简单,容易实现,因此,在通讯不频繁的时候(建议大于一小时),也可以采用这个办法。在更多的时候,则建议使用TCP/IP协议进行通讯。
利用TCP/IP进行通讯时,有两个协议可以选择:TCP及UDP,其中TCP(TransportControlProtocol,传输控制协议)是面向联接的,它提供高可靠性服务,尤其适用于传输大量报文信息。UDP(UserDatagramProtocol,用户数据报协议)是无联接的,它提供高效率的服务,适用于一次传输少量报文信息的场合。
UDP通讯的程序的编写也比较容易,只需指定客户机的IP地址(或主机名)及传送端口号即可,下面是一段利用UDP初始化例程:
#include
#include
#include
#include
#include
#include
intsock,length;
structsockaddr_in,sockname;
charbuff[1024];
intInit_Socket()
{
char*clientName=“AW5101”;
intportNum=10002;
structhostent*hp,*gethostbyname();
/*Creatsocketonwhichtosend.*/
sock=socket(AF_INET,SOCK_DGRAM,0);
if(sock==-1)
{
perror(“opendatagramsocketerr0r”);
exit(1);
}
hp=gethostbyname(clientName);
if(hp==(structhostent*)0)
{
printf(“unkownhost:%s\n”,clientName);
exit(2);
}
memcpy((char*)&sockname.sin_addr,(char*)hp->h_addr,hp->h_length);
sockname.sin_family=AF_INET;
sockname.sin_port=htons(atoi(portNum);
return(0);
}……
五.通讯安全性的考虑
在采用了I/A’s和PC或其它DCS之间双向通讯后,安全性就成为一个比较突出的问题,应尽力避免不必要的人为破坏。安全性是一个非常复杂的问题,请参考专业文献。在此不做详细讨论,只就一般性原则提出几点建议:
I.自行开发软件时,必须考虑到安全性,包括对控制处理器数据的读写操作权限、软件的事件处理功能(进程的意外中断、程序的死循环、边界处理、内存的释放等)、TCP/IP的操作权限。
II.对于专业软件,由于功能强大,在使用时,应对软件不必要的部分加以封闭,并对软件的操作加以口令授权。
III.建立通讯程序握手机制时,必须考虑安全性。
IV.加强有关的安全性规章制度的建设,避免人为的破坏。
V.DCS系统与MIS/SIS系统之间设置网关,企业MIS/SIS系统联结到INTERNET时配置防火墙。
六.结论
本文通过以谏壁发电厂使用的Foxboro公司的I/A’s系统为例,讨论了DCS系统中实行通讯的几种方法。归纳起来有:使用专业硬件、使用专门通讯软件,以及自行开发软件三种。
对主流通讯协议(MODBUS、A-BPLC)以及通讯数据量较多时,采用专业通讯硬件实现通讯是一个比较好的办法。这种配置方式的优势在于:通讯可靠、安全性好、容易实现、开发周期短;不足之处在于:增加了硬件投资。需要指出:在考虑MODBUS协议通讯时,不能只看有多少个模拟量/数字量,而必须同时考虑:有多少个设备,每个设备的通讯模拟量/数字量数据有多少,数据是否双向传送,通讯速率为多少。综合考虑以上因数后,计算出需要多少个通讯处理器。
专门的通讯软件由于功能强大,在使用时首先要考虑的是安全性,同时要增加软件费用(大型的数据库如:PI,I-FIX等价格都比较贵)。但它也有非常明显的优势:实现通讯容易、二次开发工具充足,项目周期短,项目质量有保证。
在需要实时传送流程画面时,当然应采用专业通讯软件,如:Exceed、GO_Global等。
如果自行开发通讯程序,需要考虑的有:编程工具—C语言投资、程序的鲁棒性、编程的工作量、项目周期、通讯效率、对工程师站/操作员站的CPU占用等问题。它的优势在于:开发灵活,容易实现用户的各种特殊需求。
如果通讯量不大(50点左右),建议使用增加I/O卡件,不同系统系统之间通过硬接线连接的方式实现。这样既考虑到了总体投资、项目周期,也增加了系统的可靠性。
如果通讯只提供RS-232通讯,则采用RS-232C协议进行通讯。
如果通讯量较大,但时间间隔较长,可以考虑采用FTP方式传送文本数据。
如果通讯频率较高,建议采用TCP/IP中的UDP协议进行通讯。