工业控制中上位机的串口通信设计与实现

时间:2022-04-20 10:07:13

工业控制中上位机的串口通信设计与实现

摘要:本文使用API函数来实现工业控制中的串口通信,结合实例阐述了应用程序接口函数的用法以及在编制控制软件中的使用。

关键词:串口通信多线程AP}函数

Abstract:This paper used the API functions to realize industrial control in serial communication, combined with examples, expounds the application program interface functions in usage, and the use of control software.

Keywords:serialc ommunication,m ultithreading,APIfu nction

0 前言

本文中使用的Windows API函数是Microsoft32位平台的应用程序编程接口(Application Programming Interface),该接口在设置通信配置和发送错误敏感、无时间限制的数据时尤其有用。通过一个实例程序介绍串口通信程序的编制方法。这个程序用于调试下位机与上位机的通讯,可以根据不同的下位机设置和不同的通信协议对下位机进行实时检测,把采集的数据显示出来,送出测试信号。

1 API函数

Windows通讯API有二十多个,根据它们使用的不同时期分为三部分,并且仅使用其中的几个函数完全可以做出满足工业控制的串口通信函数。

1.1打开和配置串口

打开串口的函数为CreateFile,成功则返回一个打开串口的句柄,这个句柄被其他函数调用,用来读写和配置串口,否则返回Invalid Handl value。形式如下:

Handlecreatefile (LpctstrI pfilename,//文件名指针(这里是coml,com2等)

DworddwDesiredAccess,//访问模式:读(GENERIC_READ)、写(GENERIC-READ)或者二者的组合(GENERIC_ READorGENERIC-READ)

Dword dwshareMode,//共享模式,是否允许其它的设备对串口同时进行操作,串口通信中一般设为0,即不共享。

Lp security一ttributesI pSecurityAttributes,//安全属性指针,一般值为nil,表示函数返回的句柄不能被其它的过程继承。

Dword dwcreationDistribution,//创建方法,申口通信中设为Open-existing

Dwordd wFIagsAndAttributes//为申口打开标志,使用多线程异步方式时必须设定为file_Flag_ Overlapped,用以指明将要使用文件完成重叠I/0日a nd le h丁emplatefile//这个参数对串口通讯没有什么意义,设为0即可)

初始化配置串口的函数主要使用以下几种:

(1)设置输人输出缓冲区大小

BOOL SetupComm(HA N DL E hFile, //设备句柄,即为createfile返回的句柄

DWORD dwInQueue. //输人缓冲区的大小

DWORD dwOutOueue //输出缓冲区的大小);

取得指定通信端口的当前控制设置填充端口控制块

BOOL GetCommState(

HANDLE hFile, //设备句柄,即为createfile返回的句柄

LPDCB IpDCB / DCB结构);

(2)用设置好的相应端口的控制块配置端口

BOOL SetCommState(HANDL EhFile, /设备句柄,即为createfile返回的句柄

LDCB IpDCB //用GetCommState函数得到的DCB结构,并且经过配置);

这两函数如果成功则返回一个非零值,否则返回零值。

1.2读写串口

读写申口主要使用4个函数,分别对串口进行读写和监控操作。介绍如下:

(1)读串口函数

BOOL ReadFile(HANDL EhFile, //设备句柄,即为createfile返回的句柄

LPVOID IpBuffer,//读取到的字符的存放位置

DWORD nNumberOfBytesToRead,//读字符的数目,小于接收缓冲区的大小

LPDWORD IpNumberOfBytesRead,// 本次读得的字节数

LPOVERLAPPED IpOverlapped //指向一个OVERLAPPED结构,异步读取时更新此结构。);

函数成功 ,返回值为true,否则为false.

结构OVERLAPPED在异步读取时是必须的,用于管理重叠的I/0口,把这个结构传给读写函数,直到操作完成才释放它。它里面有两个参数用于标示端口读写的位置Ofset(指定端口读写的开始置),OfsetHigh(端口读写的开始位置的高字节)。

(2)写串口函数

BOOL WriteFile(HA ND LE h File //设备句柄,即为createfile返回的句柄

LPCVO旧 IpBufer,刀指向要写人串口的变量

DWORD nNumberOfBytesToWrite / 要写的字节数目

LPDWORD IpNumberOfBytesWritten,//已经写的字节的数目

LPOVERLAPPED IpOverlapped //指向一个OVERLAPPED结构,异步读取时更新此结构。);

它的返回值等和读串口函数相同。

(3)指定监视事件集函数

BOOL SetCommMask(

HANDLE hFile, //设备句柄,即为createfile返回的句柄

DWORD dwEvtMask /使能的端口事件掩码);

这个函数 用于指定要对串口监视的事件,dwEvtMask可以取不同的值(具体使用时需参考帮助进行选择),分别表示监视不同的事件。采用异步方式时主要使用:① EV_TXEMPTY,用于对发送(写端口)监视,当发送缓冲区内的最后一个字符发送完成后触发。)EV_Rxchar,用于对读取端口监视,当接收缓冲区接收到一个字符时发生。

(4)等待事件函数

BOOL WaitCommEvent(

HANDLE hFile, //设备句柄,即为createfile返回的句柄

LPDWORDIpEvtMask,/ /指向描述发生事件的掩码的变量

LPOVERLAPPED IpOverlapped,//指向一个OVERLAPPED结构);

这个函数 用于等待SetCommMask设定的事件发生。当这个事件发生时,判断IpEvtMask是否和要求的事件类型相同,如果相同则进行相应的操作。

2 程序实现

此部分介绍一下实例中的读线程、写线程和主线程内的端口初始化和关闭部分,以加深对API函数的理解和具体使用方法。

2.1读端口线程

我们创建读端口线程,重载多线程类的构造函数如下:

本文为全文原貌 未安装PDF浏览器用户请先下载安装 原版全文

constructorTreadthread.create(vard ataW:Tmemo;Commw:Thandle);

端口的句柄通过构造函数的参数Commw获得。

读端口的实现部分函数如下:

SetCommMask(com,EV_RXchar);//设置对EV Rxchar事件关注,等char来到是系统会通知

WaitCommEvent(com,dwEvtmask,@Os);//等待EV Rxchar事件发生

if (dwevtmask and EV_Rxchar)=EV_Rxchar then

//如果发生的事件为EV Rxchar事件则执行下程序

begin

readfile(com,inputbufer,commstate.cblnQue,dwnumr,.Read_OS);

//Read_O S为OVERLAPPED结构变量

Read_os.Ofset:=read_os.Ofset+dwnumr;

str:=inputbufer;

str[dwnumr]:=#0;

datamemo.Lines.Add(strpas(str));//把读到的值放人控件Demo中显示

end

应该把以上程序放在一个函数里,由Synchronize调用,以使线程同步,避免资源冲突。Delphi的多线程类在Execute中调用Synchronize函数来实现避免多线程访问造成的资源冲突现象。

2.2写端口线程

创建写端口线程,重载多线程类的构造函数如下

constructor Comsend.create(var dataW:Tmemo;Commw:Thandle);

端口的句柄通过构造函数的参数Commw获得。

读端口的 实现部分函数如下:

try

setcommMask(com,EV_TXEMPTY);//设置对〔VesT XEMPTY事件关注,等发送完最后一个字符时系统会通知

repe t

WaitCommEvent(com, EV_TXEMPTY,@Os);//等待EVewT XEMPTY事件发生

if (dwevtmask and EV_Rxchar)=EV_Rxchar then//如果发生的事件为EV Rxchar事件则执行以下程序

writeFile(com,pdataw[dwwsw],dwnum,dwnumbed,@Write_OS)//Write_OS为OVERLAPPED结构变量

dec(dwnum,dwnumbed);//dwnum要发送的字节数,dwnumbed上次执行发送的字节数

INc(dwwsw,dwnumbed);//dwwsw发送的字节开始的位置

//做控制软件时,需发送的指令或数据都很少且为实时发送,所以不需要//这些结构

until(d w num

finally

strDispose(pdataw);

end;

2.3端口的关闭部分

端口闭我们放在主线程里,在程序退出时关闭,这符合控制的要求。语句如下:

Closehandle(hCom);

3 结语

工业控制软件中串口通信被大量采用,使用Delphi调用API函数可以方便灵活地编写可靠的程序,用于通信的API函数还有很多,本文只是介绍了其常用的几个,在做程序时还须根据Delphi提供的帮助,考虑实际情况,灵活运用。

参考文献

[1]黄军.Delphi串口通信编程[M].北京:人民邮电出版社,2001.

[2]戴梅粤,史嘉权.微型计算机技术及应用[M].北京:清华大学出版社,1996.

[3季雪岗.Delphi编程疑难详解[M].北京:人民邮电出版社,2000.

本文为全文原貌 未安装PDF浏览器用户请先下载安装 原版全文

上一篇:利用Winsock控件实现局域网通信 下一篇:基于WEBGIS的园林灌溉系统的设计