第20卷第4期 2007年10月 镇 江 高 专 学报 V0l_20 No.4 Oct.,2007 Journal of Zhenjiang College API实现的串口通信在测控系统中的应用 仲志燕,张文 (镇江市高等专科学校电子信息系,江苏镇江212003) 摘要:Windows环境下与其它设备进行通信,是通过RS-232串行口进行二进制数据异步传输的。 在打开串口、配置串口、读写串口及关闭串口中,给出部分实现通信的源代码及注释。 关键词:Win32 API;串口通信;测控系统 中图分类号:TP273 文献标识码:C 文章编号:1008—8148(2007)04-0057-04 0 引 言 在某些测试系统设计过程中,经常需要在Windows环境下通过RS-232串行口与其它设备进行通信。目 前的各种操作系统中,以Microsoft公司的Wjn98/win2000等32位平台较为普及。Win32下的串口通信与 DOS环境下和16位操作系统下的串口通信有很大的区别。在Win32下,可以使用两种方法通过编程实现 串口通信,一是使用ActiveX控件MSCOMM,此方法简单实用,编程时只需设置串口属性,尤其在Visual C+ +、Visual Basic等可视化面向对象的编程环境中,把串口看作一个对象,理解起来比较容易,但通信控件经 过层层包装,通信效率较低,缺乏灵活性。二是直接调用Window API函数,使用API调用,可以清楚地理解 串口通信的机制,根据需要灵活地配置串口的各种参数和属性,而且直接调用低层API函数,通信效率比 较高。 1 RS-232串行通信基本知识 RS-232接口标准是美国电子工业协会EIA(Electronic Indust ̄Association)在1969年颁布的一种目前使 用最广泛的串行物理接口标准。RS(Recommended Standard)的意思是“推荐标准”,232是标识号码。常用 的RS-232串口有25芯和9芯,25芯串口是标准连接器,9芯串口是RS-232标准机械特性的实用简化。串 口间的通信只要连接三条线(即三线连接法)就可进行简单的通信,即发送数据线(TXD)、接收数据线 (RXD)、地线(SG)。在使用中,它只能实现最基本的数据传输,在接收端不能产生中断信号,不能实现硬件 握手协议和流量控制。如果需要中断处理接收数据,还必须连接其它信号线。 2程序设计思路 2.1 打开串口 使用CreateFile()函数可以打开串口。打开方式有两种:同步方式(NonOverlapped)和异步方式(Nover. 1apped)。为了防止程序死锁,可以采用异步方式打开串口: BOOL OpenPo ̄() { HANDLE hComPoa;//串口设备句柄 hComPo ̄=::CreateFile(“COM1”,GENERIC—READ l GENERIC—WRITE,0,0,OPEN—EXISTING, FILEFLAG_一0VERLAPPED,0); 收稿日期:2007—04—06 作者简介:仲志燕(1977一),女,江苏镇江人,讲师,主要从事信号检测与控制方向研究;张事信号检测与控制方向研究。 文(1960一),男,江苏镇江人,副教授,主要从 ・57・ 维普资讯 http://www.cqvip.com if(hComPort==INVALID—HANDLE—VALUE) { //打开端口失败,进行错误处理 retum FALSE; } return TRUE;//成功打开串口 } 打开串口时,必须指定OPEN—EXISTING标记,模板文件句柄必须为0。FILE—FLAG—OVERLAPPED标 记表示是以异步方式打开串口。 2.2配置串口 2.2.1 配置DCB(Device Control Block)结构 DCB(Device Control Block)结构定义了串口通信设备的控制设置。许多重要的配置都是在DCB结构中 设置的。使用SetCommState()函数灵活地配置端口属性。该函数根据用户指定来配置串口,并重新初始化 硬件和控制配置,但是不清空接收和发送缓冲区。 DCB dcb; ZeroMemo ̄(&dcb,sizeof(DCB)); dcb.DCBlen ̄h=sizeof(DCB); If(!=GetCommState(hComPort,&dcb)) { //出现错误,进行错误处理; } dcb.BaudRate=CBR_9600;//波特率9600; dcb.ByteSize=8; //数据位8位; dcb.Parity =FALSE; //无检验; dcb.StopBits=1; //一位停止位; dcb.minau=1;//二进制数据传输; if(!=SetCommState(hComPort,&dcb)) { //重新配置串口失败,进行错误处理 f 2.2.2流量控制设置 串口通信时,通过以下两种方法进行流量控制来防止数据接收端被发送端发送的数据流所“淹没”。 1)硬件流控。串口通信中的硬件流控有DTE/DSR方式和RTS/CTS方式,RTS/CTS线用来表明发送方 是否可以发送数据,DTE/DSR线用来表明数据接收终端是否准备好。可以通过设置DCB结构中的fOutx— CtsFlow、fOutxDsrFlow、fDtrControl、fOutX、flnX、fRtsControl成员来选择流控方式。一般建议采用标准的流控 方式。采用硬件流控时,要求串口之间和电缆支持硬件握手,在自己制作串口通信线时,有关硬件握手的线 CTS、DSR、DTR、RTS要连接正确。该方式最有效和可靠,但不能做到与硬件无关。硬件流控的代码实现: BOOL SetupHardwareHandshaking() { CDCB dcb; if(!=GetCommState(in—hComPo ̄,&dcb)) return FALSE; //输出流量控制 ・58・ 维普资讯 http://www.cqvip.com
dcb.fOutxCtsF1OW=TRUE: dcb.fOutxDsrFlow=TRUE: //输入流量控制 dcb.fDtrControl=DTR—CONTROL—HANDSHAKE; dcb.fRtsControl=RrI、S—CONTROL—HANDSHAKE; dcb.fOutX=FALSE; dcb.flnX=FALSE: //重新配置串口; return:SetCommState(m—hComPort,&dcb); } 2)软件流控。串口通信中采用特殊字符XON/XOFF来控制串口数据的收发,该方式的主要缺点是这 两个字符不能作为数据来发送。软件流控的代码实现: BOOL SetupS0f1wareHandshaking() { CDCB dcb; if(!:GetCommState(m—hComPort,&dcb)) return FALSE: //设置软件握手协议 dcb.fOutxCtsF1OW=FALSE: dcb.fOutxDsrFlow=FALSE: dcb.fDtrControl=DTR—CONTROL—DISABLE; dcb.fRtsControl=RTS—CONTROL—DISABLE; dcb.fOutX=true: dcb.flnX=true; return=SetCommState(m—hComPort,&dcb); } 无流量控制的代码实现: BOOL SetHandshakeOff() { CDCB dcb; if(!=GetCommState(m—hComPort,&dcb)) return FALSE; //不进行流量控制 dcb.fOutxCtsFlow=FALSE: dcb.fOutxDsrFlow=FALSE: dcb.fDtrControl=DTR—CONTROL—DISABLE; dcb.fOutX=FALSE: dcb.flnX=FALSE: dcb.fRtsControl=RTS—CONTROLDISABLE; —return.¨SetCommState(m—hComPort,&dcb); } 2.2.3通信超时设置 串口通信中,在数据接收过程中由于硬件或软件等原因突然中断或停止时,如果不采取超时控制,将会 使数据I/O线长期被挂起或无限阻塞。所以,对于一个健壮的应用系统而言,通信超时设置非常重要,设置 ・59・ 维普资讯 http://www.cqvip.com
步骤如下:首先调用GetCommTimeouts()得到串行设备的初始超时配置,然后赋值COMMTIMEOUTS结构的 五个成员变量,最后调用SetCommTimeouts()重新设置通信端口读写操作的超时值。源代码如下: 读串口的超时设置: 写串口的超时设置: BOOL SetupReadTimeouts(COMMrrIMEOU rS&ct0)DWORD SetupWriteTimeouts(COMMTIMEOUTS&cto) { if(!=GetCommTimeouts(m—hComPort,&cto)) return FALSE; cto.ReadIntervalTimeout=MAXDWORD; cto.ReadTotalTimeoutConstant:0; { if(!::GetCommTimeouts(m—hComPort,&cto)) return FALSE; cto.WriteTotalTimeoutMuhiplier:5; cto.WriteTotalTimeoutConstant=500; cto.ReadTotalTimeoutMuhiplier=0; if(!::SetCommTimeouts(m—hComPort,&cto)) return FALSE; if(!=SetCommTimeouts(m—hComPort,&cto)) return FALSE; return TRUE; return TRUE; 2.3 读、写串口 } 串口的读写方式有两种:同步方式和异步方式。同步方式是指只有当读写操作完成后,函数才返回,在 读写期间,程序线程被读写函数挂起,如果读写期间发生错误,函数有可能无法返回,这将使线程在永远等 待,造成程序死掉;异步方式则合理的多,一旦读写未成功返回,就将读写线程挂起,函数直接返回,而线程可 以继续执行。(代码部分省略) 2.4 关闭串口 串口作为一种系统资源,使用完后,要及时关闭,释放所占用的资源。关闭串口比较简单,只要调用 CloshHandle()并传递串口句柄作为参数即可。唯一需要注意的是在关闭串口前,一定要确保读写串口的线 程已经退出。可采用事件驱动机制,即线程执行前创建一事件,关闭串口时,置该事件为有信号状态,通知并 等待读写线程的退出,然后调用API关闭串口。 3结论 以上代码是实现串口通信的核心部分,经过笔者在多个系统开发中的应用,具有较强的实用价值。读者 可以根据上面的论述,将读写操作放在单独的线程中执行,提高程序的健壮性和响应的及时性,或者将以上 代码封装在动态链接库中,提高代码的可重用性。 参考文献: [1]潘新民,王燕芳.微型计算机控制技术[M].北京:人民邮电出版社,1999. [2]陈坚,孙志月.MODEM通信编程技术[M].西安:西安电子科技大学出版社,1998. [3]赵辉,叶子青.Visual C++系统开发实例精粹[M].北京:人民邮电出版社,2005. [4]邓素萍.串行通信RS232/RS485转换器[J].国外电子元器件,2001(7):62—63. [5]姚传利,唐华.基于RS232通信接口的DNC方案[J].CAD/CAM与制造业信息化,2003(12):77—78. [责任编辑:卢蕊] Serial port communication applying to control system ZHONG Zhi—yan,ZHANG Wen (Electron&Information Department,Zhenjiang College,Zhenjiang 212003,China) Abstract:Windows asynchronous transmission with other equipment using Win32 API through the RS一232 serial mouth and the programming mentality are elaborated.In the part of opening,allocation reading,writing and closing the serial port,this article provides the realization of correspondence source code. Key words:Win32 API;serial port communication;control system ・60・
因篇幅问题不能全部显示,请点此查看更多更全内容