水电电工知识
电工知识|利用软件编程实现DCS通讯
2017-03-19  浏览:27
水电之家讯:利用软件编程方式,可以更加灵活实现各种非常规的通讯。

由于自行编写的程序在工程师站/操作员站运行,需要占用一定的CUP时间及内存,因此在通讯数据量较大,同时要求通讯速度较快时,由于没有专业通讯软件的“例外报告”机制,建议不要采用自行开发程序的办法。

由于自行编写的程序通常没有“数据缓存”机制,在传送非常重要的数据时应该谨慎使用。

自行编程主要工作为了两方面,一为I/A数据的读写及处理,一为通讯的实现。

通常自行开发通讯软件包括:串口通讯(如智能前端)、TCP/IP通讯(如实时数据传送)、FTP通讯(如定期传送报表文本)、基于TCP/IP的MODBUS协议通讯。

以上几种通讯方式在通讯的实现方式上不同,但在I/A’s内数据的读写操作是一样的,接下来将阐述软件编程时的主要函数及方式:

1.I/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;



staticintgw[SETNUM][OBJNUM];

charname[SETNUM][OBJNUM][32];

chardesc[SETNUM][OBJNUM][15];

staticintvaltype[SETNUM][OBJNUM];

staticintacctype=1;

staticfloatrdelta[SETNUM][OBJNUM];

staticfloatwdelta[SETNUM][OBJNUM];

interror[SETNUM][OBJNUM];

intindex[SETNUM][OBJNUM];

intstatus[SETNUM][OBJNUM];

IAXVALvalue[SETNUM][OBJNUM];

staticintrsr=4;

staticintwsr=4;

staticintclexit=1;

intreterr[SETNUM];



intset[SETNUM];

intTotal_SET;

intLast_SET_Num;

intTotal_Num;

intTotal_File;

intINTERVAL;

intCol_Num;

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进行编程。

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);



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();



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);

}……

水电之家为您提供最全面的管材,管件,水电,电线,电工,管材水电品牌的装修知识点和各种管材水电的导购与在线购买服务,拥有最便宜的管材水电价格和最优质的售后服务,每天都有秒杀的抢购活动哦!敬请登陆水电之家:http://shuidian.jc68.com/
更多»您可能感兴趣的文章:
更多»有关 管材 的产品:
  • 水电电工资讯
  • 发表评论 | 0评
  • 评论登陆
  • 移动社区 天花之家 木门之家 灯具之家 铁艺之家 幕墙之家 五金头条 楼梯头条 墙纸头条 壁纸头条 玻璃头条 老姚之家 灯饰之家 电气之家 全景头条 照明之家 防水之家 防盗之家 区快洞察 建材 枣庄建材 临沂建材 南昌建材 上饶建材 抚州建材 宜春建材 吉安建材 赣州建材 鹰潭建材 新余建材 九江建材 萍乡建材 景德镇陶瓷 石家庄建材 衡水建材 廊坊建材 沧州建材 承德建材 建材之家 企业之家 720全景
    (c)2015-2017 BYBC.CN SYSTEM All Rights Reserved