产品描述
铜陵西门子S7-1200代理商
基于Windows环境的实时串行通讯
一、概述
随着电力电子技术和计算机技术的发展,各种各样的智能终端也出现了。但智能终端管理功能较小,需要将其检测与控制的参数送到计算机上进行管理,为克服各厂家设备的不兼容性,一般采用标准RS-232C接口串行通讯来传送数据,由于在实时性方面具有严格的要求,所以大多数的工控软件还是基于DOS环境的,其综合性能对于Windows程序就弱一些,造成这种现象的原因在于,在Windows环境中,系统接管了中断,所有资源均由其统一管理,以便多个程序共享,它通过设备驱动程序为用户提供标准的外设接口,禁止程序员通过Windows直接访问内存和外设。基于此文提出了在Windows下响应硬件中断的串行通讯的方法,并针对不同语言的特点,用BorlandC++编制程序对端口直接操作,并响应执行硬件中断程序接收数据,利用DDE(动态数据交换)将数据传送给用Delphi编制的程序处理数据,将其加入数据库,建立实时数据库、动态显示、打印及报警等。
二、串行通讯的原理
串行通讯口的连接
如图1所示,串行通讯口的连接采用七根线直接连接方式,通过两对应答信号线相连,可进行全双工传输。UART是可编程的异步串行通信芯片。用户对其编程实际上是对UART内部寄存器的读出或写入操作。CPU可通过相应的输入输出指令对UART内部寄存器访问。通过访问寄存器可初始化串行口、发送数据、接收数据、检测线路设备状态以达到通讯的目的。其端口地址名称如表1所示(以串行口2为例)。
表1 UART内部寄存器端口分配
端口地址 | 指令 | 寄存器名称及作用 |
2F8H | OUT | 写入发送保持寄存器 |
2F8H | IN | 读出接收数据寄存器 |
2F8H | OUT | 写入波特率因子(LSB) |
2F9H | OUT | 写入波特率因子(MSB) |
2F9H | OUT | 写入中断允许寄存器 |
2FAH | IN | 读出中断标识寄存器 |
2FBH | OUT | 写入线路控制寄存器 |
2FCH | OUT | 写入MODEM控制寄存器 |
2FDH | IN | 读出线路状态寄存器 |
二、通讯的实现
一般通讯软件采用的协议是这样的:
发送者定时向串行口发送数据;
接收者以中断方式或查询方式读取数据;
接收者将读取的数据发送给发送者;
发送者将原发送数据与接收者发送的数据进行比较,如果一致则发送一个成功的标志给接收者,继续发送数据,否则发送一个失败的标志给接收者,再重发送数据;
重复1-4的过程直到数据传送完成。
但这种传送方式由于智能终端的速度处理数据较慢及协议繁琐以致传送速率变慢,且使智能终端程序变得复杂。为加快速度,本文将上述通讯协议进行了一些修改,利用计算机计算速度快的特点,由计算机进行数据处理,并采用异步通讯中断方式接收,以增加接收数据的可靠性。其通讯协议如下:
发送者定时传送两个相同带结束标志数据;
接收者以中断方式读取这两个数据,并进行比较,如一致则发送一个成功的标志给发送者,否则发送一个失败的标志给接收者,再重发送数据。
异步通讯中断接收程序主要由通讯中断初始化程序和通讯中断服务程序两部分组成。
1、通讯中断初始化程序
通讯中断初始化程序安整个通讯程序之前,它的工作如图2所示,首先修改中断向量表,按使用的串行口COM2,接管中断0BH,使新的中断向量指向自行编制的通讯中断程序;其次确定UART操作方式,设置中断寄存器相应位的允许或禁止,并允许中断操作;*三确定通讯波特率及数据帧传输格式;最后对中断控制器的屏蔽寄存器编程,允许中断IRQ3。必须注意在应用程序终止退出时,从变量中获取原中断向量恢复到中断向量表中,否则将引起系统死机。
2、通讯中断服务程序
通讯中断服务程序如图3所示,当智能终端有数据发送时,引起硬件中断执行中断服务程序。当接收数据就绪时,将接收数据放入缓冲区,且接收到结束标志时,发出一个用户消息到应用程序队列中,由应用程序继续处理数据,以便使中断服务程序时间尽量压缩到较小,让其他应用程序获得CPU的服务。在中断返回前应向中断控制器发出结束中断命令,否则以后将屏蔽对同级中断和低一级中断的处理,只能接收一次数据。
异步通讯中断接收程序代码由Borland C++编制。利用inportb和outportb函数对表1中所列出的端口地址直接操作初始化和读取数据,用interrupt函数设置自己的中断服务程序接收数据。另外由于对端口的直接操作,也使得执行中断服务程序的时间减少,以致CPU能获得充分利用
动态数据交换及数据处理
动态数据交换是Windows提供的一种利用共享内存进行程序间数据交换或传递信息的方法,它充分体现了Windows的多任务优点,使得各应用程序间的数据传递可以随时方便地进行,尤其适合于程序间动态数据的传递。本文利用了Microsoft公司在Windows 31下推出的动态数据交换管理库DDEML来实现程序间的动态数据交换。它使得所有的DDE程序采用了同样的方式交换数据,增加了程序的可靠性,使得用Borland C++编制的程序和Delphi编制的程序进行动态数据交换成为了可能。
本文以Borland C++编制的DDE客户程序为数据源,一旦接收数据正确立即将数据传送给Delphi编制的DDE服务器程序处理。
1、编写DDE客户程序
(1)初始化
客户程序在使用DDEML函数前必须进行初始化,进行初始化可调用DdeInitialize函数,可如下操作:
DdeInitialize(&idInst,(PFNCALLBACK)lpCallBack,APPCMDCLIENTONLY,0);
其中idInst为客户程序需要保护的此呈现户的标识符地址,标识符的值由DDEML给出;lpCallBack为回调函数的地址;APPCMDCLIENTONLY指明此程序的性质。
另外创建服务名、话题名及项目名句柄:
hszService=DdeCreateStringHandle(idInst,"Server",CP[CD#*2]WINANSI);
hszTopic=DdeCreateStringHandle(idInst,"DdeServer",CP[CD#*2]WINANSI);
hszItem=DdeCreateStringHandle(idInst,"DdeServerIteml",CP[CD#*2]WINANSI);
(2)建立会话
调用DdeConnect建立单个会话:
hConv=DdeConnect(idInst,hszService,hszTopic,NULL);
这里idInst是客户程序在调用DdeInitalize时由DDEML传递过来的代表客户程序的标识符;hszService是服务名字符串的句柄;hszTopic是话题名字符串的句柄。
(3)向服务器传递数据
DdeClientTransaction((LPBYTE)szData,strlen(szData)+1,hConv,hszItem,
CF[CD#*2]TEXT,XTYP[CD#*2]POKE,0,NULL)
这里SzData是需传递的字符串指针;strlen(szData)+1是数据的大小;hConv是会话名;hszItem是项目名字符串的句柄;XTYPPOKE是调用DdeClientTransaction函数时事务;CFTEXT是数据格式。
(4)会话结束
应用程序结束时需要调用DdeFreeStringHandle函数来释放所占用的空间,调用DdeDisConnect函数结束会话。
DdeFreeStringHandle(idInst,hszService);
DdeFreeStringHandle(idInst,hszTopic);
DdeFreeStringHandle(idInst,hszItem);
DdeDisconnect(hConv);
2、编写DDE服务器及数据处理程序
在服务器Server端的窗体中放一DdeServerItem组件将其属性Name设为DdeServerIteml,当有数据向服务器传递时,触发事件OnPokeDate接收处理数据。另外Delphi提供了丰富的绘图功能,利用此特性将接收的数据在虚拟界面上显示数据及波形,并对数据进行报警打印,采用客户/服务器形式,使用WINNTF的SQL Server服务器作为后台,用Delphi编制程序作为前端工具将数据加入数据库,建立实时数据库,以便工程人员及管理层通过网络共享数据。
四、软件功能结构
软件功能结构如图4所示,程序由通讯程序和数据管理程序构成,其工作步骤如下:
1、由中断通讯模块接收智能终端发送的数据放入缓冲区,并发出消息。
2、响应消息对数据进行处理,对智能终端发送数据正确或错误标志,并将缓冲区的数据经DDE客户模块发送给数据管理程序的DDE服务器模块。
3、数据管理程序将DDE服务器模块接收的数据分别给数据库模块、动态显示模块、报警及打印模块进行处理。
产品推荐