API串口通信实例_第1页
API串口通信实例_第2页
API串口通信实例_第3页
API串口通信实例_第4页
API串口通信实例_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、作。常用函数及作用下:函数名CreateFileGetCommStateSetCommStateBuilderCommDCBGetCommTimeoutsSetCommTimeoutsSetCommMaskWaitCommEventWaitForMultipleObjectsWriteFileReadFileGetOverlappedResultPurgeCommClearCommErrorCloseHandle第一节实现串口通讯的函数及串口编程简介API函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操作用打开串口检测串口设置设置串口用字符串中的值来填

2、充设备控制块检测通信超时设置设置通信超时参数设定被监控事件等待被监控事件发生等待多个被监测对象的结果发送数据接收数据返回最后重叠(异步)操作结果清空串口缓冲区,退出所有相关操作更新串口状态结构体,并清除所有串口硬件错误关闭串行口用Windows API编写串口程序本身是有巨大优点的,因为控制能力会更强,效率也会更 高。API编写串口,过程一般是这样的:1、 创建串口句柄,用 CreateFile ;2、对串口的参数进行设置,其中比较重要的是波特率( BaudRate),数据宽度(BytesBits ),奇偶 校验(Parity ),停止位(StopBits ),当然,重要的还有端口号( Por

3、t );3、 然后对串口进行相应的读写操作,这时候用到ReadFile和WriteFile 函数;4、 读写结束后,要关闭串口句柄,用 CloseFile 。下面依次讲述各个步骤的过程。第二节创建串口句柄打开串口从字面上去理解,大家也可以发现CreateFile 实际上表明 Windows是把串口当作一个文件来处理的,所以它也有文件那样的缓冲区、句柄、读写错误等,不同的是,这个文件名字只有固定的几个(一般为四个),而且始终存在(EXSITING),而且在调用 CreateFile的时候请注意它的参数。CreateFile 函数原型如下:HANDLE CreateFile(LPCTSTR IpF

4、ileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES IpSecurityAttributes,DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );lpFileName :指向一个以 NULL结束的字符串,该串指定了要创建、打开或截断的文件、管道、通信源、磁盘设备或控制台的名字。当用CreateFile 打开串口时,这个参数可用“ COM1指定串口1,用“COM2指定串口 2,依此类推。dwDesire

5、Access :指定对文件访问的类型,该参数可以为GENERIC_READg定对该文件的读访问权)或GENERIC_WRITE指定该文件的写访问权)两个值之一或同时为为这两个值。用ENERIC_READ|GENERIC_WRITE则指定可对串口进行读写;dwShareMode:指定此文件可以怎样被共享。因为串行口不支持任何共享模式,所以dwShareMode必须设为lpSecurityAttributes定义安全属性,一般不用,可设为 NULL Win 9x下该参数被忽略;dwCreationDistribution定义文件创建方式,对串口必须设为 OPEN_EXISTING表示打开已经存在的

6、文件;dwFlagsAndAttributes 为该文件指定定义文件属性和标志,这个程序中设为FILE_FLAG_OVERLAPPE昧示异步通信方式;hTemplateFile指向一个模板文件的句柄,串口无模板可言,设为 NULL在 Windows 9x下该参数必须为 NULL串口被成功打开时,返回其句柄,否则返回INVALID_HANDLE_value(0XFFFFFFFF)。上面说到了异步,那什么是异步呢?异步是相对同步这个概念而言的。异步,就是说,在进行串口读写操作时,不用等到 I/O操作完成后函数才返回,也就是说,异步可以更快得 响应用户操作;同步,相反,响应的 I/O操作必须完成后函

7、数才返回,否则阻塞线程。对于一些很简单的通讯程序来说,可以选择同步,这样可以省去很多错误检查,但是对于复杂一点的应用程序, 异步是最佳选择。实例1:/*example1.cpp */* lishaoan 2009-06-29 */ /* */ #include <windows.h>#include <stdio.h>打开串口#include <stdlib.h> bool openport(char *portname)/HANDLE hComm;hComm = CreateFile(portname, / 串口号GENERIC_READ | GENERI

8、C_WRITE, / 允许读写0, / 通讯设备必须以独占方式打开0, / 无安全属性OPEN_EXISTING, /通讯设备已存在FILE_FLAG_OVERLAPPED,/异步 I/O0); /通讯设备不能用模板打开if (hComm = INVALID_HANDLE_VALUE)CloseHandle(hComm);return FALSE;elsereturn true; void main()bool open;open=openport("com2");if(open)printf("open comport success");system

9、("pause");/* program end*/实例2:I*example2.cpp*/* lishaoan 2009-06-29 */ /* * #include <windows.h>#include<stdio.h>#include<stdlib.h>bool openport(char *portname)/HANDLE hComm;打开串口hComm = CreateFile(portname, / 串口号GENERIC_READ | GENERIC_WRITE, / 允许读写0, / 通讯设备必须以独占方式打开0, / 无

10、安全属性OPEN_EXISTING, /通讯设备已存在0,/ 同步 I/O0); /通讯设备不能用模板打开if (hComm = INVALID_HANDLE_VALUE)CloseHandle(hComm);return FALSE;elsereturn true; void main() bool open;open=openport("com2");if(open)printf("open comport success");system("pause");/* program end*/第三节设置串口在打开通信设备句柄后,常常

11、需要对串行口进行一些初始化工作。这需要通过一个DC隹吉构来进行。DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。在查询或配置串口的属性时,都要用DC隹吉构来作为缓冲区。第一次打开串口时,串口设置为系统默认值,函数 GetCommState和SetCommState可用于检索和设定端口设置的DCB假备控制块)结构,该结构中BaudRate、ByteSize、StopBits和Parity 字段含有串口波特率、数 据位数、停止位和奇偶校验控制等信息。程序中用DCB进行串口设置时,应先调用 API函数GetCommState,来获得串口的设置信息:GetCommState(

12、)用途:取得串口当前状态 原型:BOOL GetCommState(HANDLE hFile, LPDCB lpDCB);参数说明:-hFile :串口句柄-lpDCB:设备控制块(Device Control Block) 结构地址。此结构中含有和设备相关的参数。此处是与串口相 关的参数。由于参数非常多,当需要设置串口参数时,通常是先取得串口的参数结构,修改部分参数后再将 参数结构写入。然后在需要设置的地方对dcb进行设置。串口有很多的属性,上面也已经介绍了一些最重要的参数。这里介绍数据结构DCBtypedef struct _DCB / dcbDWORD DCBlength;/DCB 结构

13、体大小DWORD BaudRate;/ 波特率DWORD fBinary: 1;/是否是二进制,一般设置为 TRUEDWORD fParity: 1;/是否进行奇偶校验DWORD fOutxCtsFlow:1; /CTS线上的硬件握手DWORD fOutxDsrFlow:1; /DSR线上的硬件握手DWORD fDtrControl:2; /DTR 控制DWORD fDsrSensitivity:1;DWORD fTXContinueOnXoff:1;DWORD fOutX: 1;DWORD fInX: 1;/是否使用XON/XOF勒议/是否使用XON/XOFFB议DWORD fErrorCh

14、ar: 1;/发送错误协议DWORD fNull: 1;DWORD fRtsControl:2;DWORD fAbortOnError:1;DWORD fDummy2:17;WORD wReserved;WORD XonLim; /设置在XO”符发送之前inbuf中允许的最少字节数WORD XoffLim; /在发送XOFF字符之前outbuf中允许的最多字节数BYTE ByteSize; / 数据宽度,一般为 8,有时候为7BYTE Parity; / 奇偶校验BYTE StopBits; / 停止位数char XonChar; /设置表示XON?符的字符,一般是采用0x11这个数值char

15、 XoffChar; /设置表示XOFF字符的字符,一般是采用0x13这个数值char ErrorChar;char EofChar;char EvtChar;WORD wReserved1; DCB;我们真正在串口编程中用到的数据成员没有几个,在此仅介绍少数的几个常用的参数:DWORD BaudRate 串口波特率DWORD fParity :为1的话激活奇偶校验检查DWORD Parity :校验方式,值 04分别对应无校验、奇校验、偶校验、校验置位、校验清零DWORD ByteSize: 一个字节的数据位个数,范围是 58DWORD StopBits :停止位个数,02分别对应1位、1.

16、5位、2位停止位然后再末尾调用 SetCommState就可以了,还是比较方便的。这样可不必构造一个完整的DC隹吉构SetCommState()用途:设置串口状态,包括常用的更改串口号、波特率、奇偶校验方式、数据位数等原型:BOOL SetCommState(HANDLE hFile, LPDCB lpDCB);参数说明:-hFile: 串口句柄-lpDCB:设备控制块(Device Control Block)结构地址。要更改的串口参数包含在此结构中。然后调用SetCommMask用来指定程序接收特定的串口事件,调用SetupComm函数,设置串口缓冲区大小:SetCommMask()说明:

17、用途:设置串口通信事件。原型:BOOL SetCommMask(HANDLE hFile,DWORD dwEvtMask);参数说明:-hFile :串口句柄-dwEvtMask :准备监视的串口事件掩码该参数有如下信息掩码位值:EV_BREAK收到 BREAK言号EV_CTS:CTS(clear to send)线路发生变化EV_DSR:DST(Data Set Ready)线路发生变化EV ERR线路状态错误,包括了 CE FRAMECE OVERRUNCE RXPARITY3昔误。EV_RING:检测到振铃信号。EV_RLSD:CD(Carrier Detect)线路信号发生变化。EV_

18、RXCHARt入缓冲区中已收至ij数据。EV_RXFLAG#用SetCommState()函数设置的 DCB吉构中的等待字符已被传入输入缓冲区中。EV_TXEMPT输出缓冲区中的数据已被完全送出。还有,串口因为是I/O操作,可能会产生错误,这时候需要用 SetCommTimeouts ()设置超时限制,以避免阻塞现象。设置超时设置需要一个结构体COMMTIMEOUTSSetCommTimeouts ()BOOL SetCommTimeouts( hCommDev, lpctmo );Lpctmo指向包含新的超时参数的COMMTIMEOUTS构。COMMTIMEOUTS勾定义如下: typede

19、f struct _ COMMTIMEOUTSDWORD ReadIntervalTimeout;DWORD ReadTotalTimeoutMultiplier;DWORD ReadTotalTimeoutconstant;DWORD WriteTotalTimeoutMultiplier;DWORD WriteTotalTimeoutconstant;COMMTIMEOUT S LPCOMMTIMEOUTS;ReadIntervalTimeout :以毫秒为单位指定通信线上两个字符到达之间的最大时间。在ReadFile操作其间,收到第一个字符时开始计算时间。若任意两个字符到达之间的间隔超过

20、这个最大值,ReadFile操作完成,返回缓冲数据。0值表示不用间隔限时。若该成员为MAXDWORD! ReadTotalTimeoutconstant和 ReadTotalTimeoutMultiplier成员为零,则指出读操作要立即返回已接收到的字符,即使未收到字符,读操作也要返回。ReadTotalTimeoutMultiplier :以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间。每个读 操作的总限时时间等于读操作所需的字节数与该值的乘积。ReadTotalTimeoutConstant :以毫秒为单位指定一个常数,用于计算读操作的总限时时间。每个操作的总限时时间等于Rea

21、dTotalTimeoutMultiplier成员乘以读操作所需字节数再加上该值的和ReadTotalTimeoutMultiplier WriteTotalTimeoutMultiplier ReadTotalTimeoutMultiplier 举例:COMMTIMEOUTS timeouts;和 ReadTotalTimeoutConstant和 WriteTotalTimeoutconstant和 ReadTotalTimeoutConstant成员的值为0表示读操作不使用限时时间。的意义和作用分别与相似,不再重复。timeouts.ReadIntervalTimeout=MAXDWOR

22、D;timeouts.ReadTotalTimeoutConstant=0;timeouts.ReadTotalTimeoutMultiplier=0;timeouts.WriteTotalTimeoutConstant=50;timeouts.WriteTotalTimeoutMultiplier=2000;SetCommTimeouts(m_hCom, &timeouts);这里将 ReadIntervalTimeout设置为最大字节数,.ReadTotalTimeoutConstant 和ReadTotalTimeoutMultiplier都设置为0,表示不设置读操作超时,也就是

23、说读操作瞬间完成,不进行等待。调用PurgeCommg数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容。PurgeComm()说明:功能:终止目前正在进行的读或写的动作函数原型:BOOL PurgeComm(HANDLE hFile, / handle of communications resourceDWORD dwFlags / action to perform);参数说明:HANDLE hFile,/ 串口名称字符串dwFlags 共有四种 flags:PURGE_TXABO颈止目前正在进行的(背景)写入动作PURGE_RXABORT正目前正在进行的(背景)读取动

24、作PURGE_TXCLEAR: flush 写入的 bufferPURGE_TXCLEAR: flush 读取的 buffer实例3:/*example3.cpp*/* lishaoan 2009-06-29 */ /* */ #include <windows.h>#include<stdio.h>#include<stdlib.h>打开串口bool openport(char *portname)/HANDLE hComm;串口号hComm = CreateFile(portname, /GENERIC_READ | GENERIC_WRITE, / 允

25、许读写0, /通讯设备必须以独占方式打开0, /无安全属性OPEN_EXISTING, /通讯设备已存在0,/ 同步 I/O0); /通讯设备不能用模板打开if (hComm = INVALID_HANDLE_VALUE)CloseHandle(hComm);return FALSE;elsereturn true;bool setupdcb(int rate_arg)/设置 DCBDCB dcb;int rate= rate_arg;memset(&dcb,0,sizeof(dcb);if(!GetCommState(hComm,&dcb)/获取当前 DCB配置return

26、FALSE;/ set DCB to configure the serial port dcb.DCBlength= sizeof(dcb);/*Serial Port Config*/dcb.BaudRatedcb.Paritydcb.fParity dcb.StopBits dcb.ByteSize dcb.fOutxCtsFlow dcb.fOutxDsrFlow dcb.fDtrControldcb.fDsrSensitivity = 0;dcb.fRtsControldcb.fOutXdcb.fInX/*misc parameters */dcb.fErrorChardcb.fBi

27、nary=rate;=NOPARITY;=0;=ONESTOPBIT;=8;=0;=0;=DTR_CONTROL_DISABLE;=RTS_CONTROL_DISABLE;=0;=0;=0;=1;=0;dcb.fNull dcb.fAbortOnError = 0;dcb.wReserved= 0;dcb.XonLim= 2;dcb.XoffLim= 4;dcb.XonChar= 0x13;dcb.XoffChar= 0x19;dcb.EvtChar= 0;/ set DCBif(!SetCommState(hComm,&dcb)return false;elsereturn true

28、;bool setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORDWriteTotalMultiplier,DWORD WriteTotalconstant)COMMTIMEOUTS timeouts;timeouts.ReadIntervalTimeout=ReadInterval;timeouts.ReadTotalTimeoutConstant=ReadTotalconstant;timeouts.ReadTotalTimeoutMultiplier=ReadTotal

29、Multiplier;timeouts.WriteTotalTimeoutConstant=WriteTotalconstant;timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier;if(!SetCommTimeouts(hComm, &timeouts)return false;elsereturn true;void main()bool open;open=openport("com2");if(open)printf("open comport success");if(se

30、tupdcb(9600)printf("setupDCB success'n");if(setuptimeout(0,0,0,0,0)printf("setuptimeout successn");SetCommMask(hComm, EV_RXCHAR);/当有字符在inbuf中时产生这个事件清除串口的所有操作PurgeComm(hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);system("pause"); /* program end*/第四节

31、 读写串口数据及关闭串口Win32API函数ReadFile和 WriteFile 支持对串行口的读写操作。在调用 ReadFile和WriteFile 之前,线程应该调用ClearCommError函数清除错误标志。该函数负责报告指定的错误和设备的当前状态。ClearCommError()用途:清除串口错误或者读取串口现在的状态原型:BOOL ClearCommError(HANDLE hFile,LPDWORD lpErrors,LPCOMATAT lpStat);参数说明:-hFile: 串口句柄-lpErrors :返回错误数值,错误常数如下:1-CE_BREAK:检测到中断信号。意思

32、是说检测到某个字节数据缺少合法的停止位。2-CE_FRAME硬件检测到帧错误。3-CE_IOE:通信设备发生输入/输出错误。4-CE_MODE设置模式错误,或是 hFile值错误。5-CE_OVERRUN出错误,缓冲区容量不足,数据将丢失。6-CE_RXOVE畸出错误。7-CE_RXPARITY:硬件检查到校验位错误。8-CE_TXFULL:发送缓冲区已满。-lpStat:指向通信端口状态的结构变量,原型如下:typedef struct _COMSTATDWORD cbInQue;/输入缓冲区中的字节数DWORD cbOutQue;/输出缓冲区中的字节数COMSTAT,*LPCOMSTAT;

33、该结构中对我们很重要的只有上面两个参数,其他的我们可以不用管。假如当前串口中有5个字节数据的话,那么执行完 ClearCommError()函数后,ComStat结构中的ComStat.cbInQue将被填充为5,此值在ReadFile函数中可被直接利用。例如:COMSTAT ComStat;DWORD dwError=0;ClearCommError(hComm,&dwError,&ComStat);上式执行完后,ComStat.cbInQue就是串口中当前含有的数据字节个数,我们利用此数值就可以用 ReadFile()函数去读串口中的数据了。函数ReadFile和Write

34、File的行为还受是否使用异步I/O (Overlapped )及通信超时设置的影响。串行口读写的同步、异步方式是在打开端口的同时给dwGlagsAndAttributes参数传入适当的值而设定的。WriteFile()用途:向串口写数据原型:BOOL WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped);参数说明:-hFile :串口句柄-lpBuffer :待写入数据的首地址-nNumberOf

35、BytesToWrite :待写入数据的字节数长度-lpNumberOfBytesWritten :函数返回的实际写入串口的数据个数的地址,利用此变量可判断实际写入的字 节数和准备写入的字节数是否相同。-lpOverlapped: 重叠I/O结构的指针ReadFile()用途:读串口数据原型:BOOL ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,lpNumberOfBytesRead,lpOverlapped);参数说明:-hFile :串口句柄-IpBuffer :存储被读出数据的首地址-nNumberOf

36、BytesToRead :准备读出的字节个数-NumberOfBytesRead :实际读出的字节个数-IpOverlapped :异步 I/O 结构在同步方式下,调用 ReadFile或WriteFile 后,当实际读写操作完成或发生超时时才返回调用程序。而异步方式函数在启动接收或发送过程后立即返回,程序继续向下执行,程序在调用ReadFile和WriteFile时必须提供一个 Overlapped数据结构指针,该结构中包含一个手动事件同步对象,其后的程序必须借助于 该事件同步对象,完成数据的接收和发送过程。通信端口的超时设置对读写的处理方式也会产生影响,如果调用读写函数时发生端口超时,则读

37、写函数立即返回并返回已传输的数据字节数。ReadFile函数只要在串行口输入缓冲区中读入指定数量的字符,就算完成操作。而WriteFile 函数不但要把指定数量的字符拷入到输出缓冲中,而且要等这些字符从串行口送出去后才算完成操作。如果不再使用某一端口,须将该端口关闭,以便其他程序可以使用该端口。如果不显式关闭某端口,当程序退出时打开的端口也将被自动关闭。但为了安全起见,最好是显式的关闭它。关闭串口的语句为 CloseHandle()。CloseHandle()用途:关闭串口原型:BOOL CloseHandle(HANDLE hObjedt)说明:-hObjedt :串 口句柄操作说明:成功关

38、I串口时返回true,否则返回false当ReadFile和WriteFile 返回FALSE时,不一定就是操作失败,线程应该调用 GetLastError 函数分析返回的结果。例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError 函数返回ERROR_IO_PENDING如果GetLastError 函数返回ERROR_IO_PENDING11说明重叠操作还未完成,线 程可以等待操作完成。有两种等待办法:一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED构的hEvent成员,可以规定等待的时间,在等待函数

39、返回后,调用 GetOverlappedResult 。另一种办法是调用 GetOverlappedResult 函数等待,如果指定该函数的bWait参数为TRUE那么该函数将等待OVERLAPPED构的hEvent事件。GetOverlappedResult 可以返回一个 OVERLAPPED构来报告包括实际传 输字节在内的重叠操作结果。如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的。因此,在超时发生后,WaitForSingleObject 和 GetOverlappedResult 都会结束等待。WaitForSingleObject 的 dwMilli

40、seconds 参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值。注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去GetOverlappedResult 函数调用方法如下:BOOL GetOverlappedResult(HANDLE hFile , /用CreateFile 获得的文件句柄LPOVERLAPPED Overlapped , /指向一个在启动重叠操作时指定的OVERLAPPE躇构(即/读写函数中指定的 OverLapped结构)LPDWORD lpNumberOfBytesTransferred,/实际传输的字节数BOOL bWait,/是否等待悬挂的重叠操作完成,若为 TRUE则此函数直到操作完成后才/返回。);OVERLAPPE躇构定义如下:typedef struct _OVERLAPPED DWORD Internal;DWORD InternalHigh;DWORD Offset;DWORD OffsetHigh;HANDLE hEvent; OVERLAPPED;如果采用异步方式

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论