关于串口编程的读书笔记

WIN95界面下的VC++串口通讯程序在WIN32下是不建议对端口进行操作的,在WIN32中所有的设备都被看成是文件,串行口也不例外也是作为文件来进行处理的。这是我的一份关于串口编程的读书笔记,对于使   用VC进行编程的同行应该有一定的帮助。      
   
  1.打开串口:      
   
       在Window   95下串行口作为文件处理,使用文件操作对串行口进行处理。使用CreateFile()打开串口,CreateFile()将返回串口的句柄。      
       HANDLE   CreateFile(      
       LPCTSTR   lpFileName,   //   pointer   to   name   of   the   file      
       DWORD   dwDesiredAccess,   //   access   (read-write)   mode      
       DWORD   dwShareMode,   //   share   mode      
       LPSECURITY_ATTRIBUTES   lpSecurityAttributes,   //   pointer   to   security   attributes      
       DWORD   dwCreationDistribution,   //   how   to   create      
       DWORD   dwFlagsAndAttributes,   //   file   attributes      
       HANDLE   hTemplateFile   //   handle   to   file   with   attributes   to   copy      
       );      
       lpFileName:   指明串口制备,例:COM1,COM2      
       dwDesiredAccess:   指明串口存取方式,例:GENERIC_READ|GENERIC_WRITE      
       dwShareMode:   指明串口共享方式      
       lpSecurityAttributes:   指明串口的安全属性结构,NULL为缺省安全属性      
       dwCreateionDistribution:   必须为OPEN_EXISTIN      
       dwFlagAndAttributes:   对串口唯一有意义的是FILE_FLAG_OVERLAPPED      
       hTemplateFile:   必须为NULL      
   
  2.关闭串口:      
   
       CloseHandle(hCommDev);      
   
  3.设置缓冲区长度:      
   
       BOOL   SetupComm(      
       HANDLE   hFile,   //   handle   of   communications   device      
       DWORD   dwInQueue,   //   size   of   input   buffer      
       DWORD   dwOutQueue   //   size   of   output   buffer      
       );      
   
  4.COMMPROP结构:      
   
       可使用GetCommProperties()取得COMMPROP结构,COMMPROP结构中记载了系统支持的各项设置。      
       typedef   struct   _COMMPROP   {   //   cmmp      
       WORD   wPacketLength;   //   packet   size,   in   bytes      
       WORD   wPacketVersion;   //   packet   version      
       DWORD   dwServiceMask;   //   services   implemented      
       DWORD   dwReserved1;   //   reserved      
       DWORD   dwMaxTxQueue;   //   max   Tx   bufsize,   in   bytes      
       DWORD   dwMaxRxQueue;   //   max   Rx   bufsize,   in   bytes      
       DWORD   dwMaxBaud;   //   max   baud   rate,   in   bps      
       DWORD   dwProvSubType;   //   specific   provider   type      
       DWORD   dwProvCapabilities;   //   capabilities   supported      
       DWORD   dwSettableParams;   //   changeable   parameters      
       DWORD   dwSettableBaud;   //   allowable   baud   rates      
       WORD   wSettableData;   //   allowable   byte   sizes      
       WORD   wSettableStopParity;   //   stop   bits/parity   allowed      
       DWORD   dwCurrentTxQueue;   //   Tx   buffer   size,   in   bytes      
       DWORD   dwCurrentRxQueue;   //   Rx   buffer   size,   in   bytes      
       DWORD   dwProvSpec1;   //   provider-specific   data      
       DWORD   dwProvSpec2;   //   provider-specific   data      
       WCHAR   wcProvChar[1];   //   provider-specific   data      
       }   COMMPROP;      
       dwMaxBaud:      
       BAUD_075   75   bps      
       BAUD_110   110   bps      
       BAUD_134_5   134.5   bps      
       BAUD_150   150   bps      
       BAUD_300   300   bps      
       BAUD_600   600   bps      
       BAUD_1200   1200   bps      
       BAUD_1800   1800   bps      
       BAUD_2400   2400   bps      
       BAUD_4800   4800   bps      
       BAUD_7200   7200   bps      
       BAUD_9600   9600   bps      
       BAUD_14400   14400   bps      
       BAUD_19200   19200   bps      
       BAUD_38400   38400   bps      
       BAUD_56K   56K   bps      
       BAUD_57600   57600   bps      
       BAUD_115200   115200   bps      
       BAUD_128K   128K   bps      
       BAUD_USER   Programmable   baud   rates   available      
       dwProvSubType:      
       PST_FAX   传真设备      
       PST_LAT   LAT协议      
       PST_MODEM   调制解调器设备      
       PST_NETWORK_BRIDGE   未指定的网桥      
       PST_PARALLELPORT   并口      
       PST_RS232   RS-232口      
       PST_RS422   RS-422口      
       PST_RS423   RS-432口      
       PST_RS449   RS-449口      
       PST_SCANNER   扫描仪设备      
       PST_TCPIP_TELNET   TCP/IP   Telnet协议      
       PST_UNSPECIFIED   未指定      
       PST_X25   X.25标准      
       dwProvCapabilities      
       PCF_16BITMODE   支持特殊的16位模式      
       PCF_DTRDSR   支持DTR(数据终端就绪)/DSR(数据设备就绪)      
       PCF_INTTIMEOUTS   支持区间超时      
       PCF_PARITY_CHECK   支持奇偶校验      
       PCF_RLSD   支持RLSD(接收线信号检测)      
       PCF_RTSCTS   支持RTS(请求发送)/CTS(清除发送)      
       PCF_SETXCHAR   支持可设置的XON/XOFF      
       PCF_SPECIALCHARS   支持特殊字符      
       PCF_TOTALTIMEOUTS   支持总(占用时间)超时      
       PCF_XONXOFF   支持XON/XOFF流控制      
       标准RS-232和WINDOW支持除PCF_16BITMODE和PCF_SPECIALCHAR外的所有功能      
       dwSettableParams      
       SP_BAUD   可配置波特率      
       SP_DATABITS   可配置数据位个数      
       SP_HANDSHAKING   可配置握手(流控制)      
       SP_PARITY   可配置奇偶校验模式      
       SP_PARITY_CHECK   可配置奇偶校验允许/禁止      
       SP_RLSD   可配置RLSD(接收信号检测)      
       SP_STOPBITS   可配置停止位个数      
       标准RS-232和WINDOW支持以上所有功能      
       wSettableData      
       DATABITS_5   5个数据位      
       DATABITS_6   6个数据位      
       DATABITS_7   7个数据位      
       DATABITS_8   8个数据位      
       DATABITS_16   16个数据位      
       DATABITS_16X   通过串行硬件线路的特殊宽度路径      
       WINDOWS   95支持16的所有设置      

5.DCB结构:      
   
       typedef   struct   _DCB   {//   dcb      
       DWORD   DCBlength;   //   sizeof(DCB)      
       DWORD   BaudRate;   //   current   baud   rate      
       指定当前的波特率      
       DWORD   fBinary:   1;   //   binary   mode,   no   EOF   check      
       指定是否允许二进制模式,      
       WINDOWS   95中必须为TRUE      
       DWORD   fParity:   1;   //   enable   parity   checking      
       指定奇偶校验是否允许      
       DWORD   fOutxCtsFlow:1;   //   CTS   output   flow   control      
       指定CTS是否用于检测发送控制。      
       当为TRUE是CTS为OFF,发送将被挂起。      
       DWORD   fOutxDsrFlow:1;   //   DSR   output   flow   control      
       指定CTS是否用于检测发送控制。      
       当为TRUE是CTS为OFF,发送将被挂起。      
       DWORD   fDtrControl:2;   //   DTR   flow   control   type      
       DTR_CONTROL_DISABLE值将DTR置为OFF,   DTR_CONTROL_ENABLE值将DTR置为ON,   DTR_CONTROL_HANDSHAKE允许DTR"握手",DWORD   fDsrSensitivity:1;   //   DSR   sensitivity   当该值为TRUE时DSR为OFF时接收的字节被忽略      
       DWORD   fTXContinueOnXoff:1;   //   XOFF   continues   Tx      
       指定当接收缓冲区已满,并且驱动程序已经发      
       送出XoffChar字符时发送是否停止。      
       TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。      
       FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。      
       DWORD   fOutX:   1;   //   XON/XOFF   out   flow   control      
       TRUE时,接收到XoffChar之后便停止发送      
       接收到XonChar之后将重新开始      
       DWORD   fInX:   1;   //   XON/XOFF   in   flow   control      
       TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去      
       接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去      
       DWORD   fErrorChar:   1;   //   enable   error   replacement      
       该值为TRUE且fParity为TRUE时,用ErrorChar   成员指定的字符代替奇偶校验错误的接收字符      
       DWORD   fNull:   1;   //   enable   null   stripping      
       TRUE时,接收时去掉空(0值)字节      
       DWORD   fRtsControl:2;   //   RTS   flow   control      
       RTS_CONTROL_DISABLE时,RTS置为OFF      
       RTS_CONTROL_ENABLE时,   RTS置为ON      
       RTS_CONTROL_HANDSHAKE时,      
       当接收缓冲区小于半满时RTS为ON      
       当接收缓冲区超过四分之三满时RTS为OFF      
       RTS_CONTROL_TOGGLE时,      
       当接收缓冲区仍有剩余字节时RTS为ON   ,否则缺省为OFF      
       DWORD   fAbortOnError:1;   //   abort   reads/writes   on   error      
       TRUE时,有错误发生时中止读和写操作      
       DWORD   fDummy2:17;   //   reserved      
       未使用      
       WORD   wReserved;   //   not   currently   used      
       未使用,必须为0      
       WORD   XonLim;   //   transmit   XON   threshold      
       指定在XON字符发送这前接收缓冲区中可允许的最小字节数      
       WORD   XoffLim;   //   transmit   XOFF   threshold      
       指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数      
       BYTE   ByteSize;   //   number   of   bits/byte,   4-8      
       指定端口当前使用的数据位      
       BYTE   Parity;   //   0-4=no,odd,even,mark,space      
       指定端口当前使用的奇偶校验方法,可能为:      
       EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY      
       BYTE   StopBits;   //   0,1,2   =   1,   1.5,   2      
       指定端口当前使用的停止位数,可能为:      
       ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS      
       char   XonChar;   //   Tx   and   Rx   XON   character      
       指定用于发送和接收字符XON的值      
       char   XoffChar;   //   Tx   and   Rx   XOFF   character      
       指定用于发送和接收字符XOFF值      
       char   ErrorChar;   //   error   replacement   character      
       本字符用来代替接收到的奇偶校验发生错误时的值      
       char   EofChar;   //   end   of   input   character      
       当没有使用二进制模式时,本字符可用来指示数据的结束      
       char   EvtChar;   //   received   event   character      
       当接收到此字符时,会产生一个事件      
       WORD   wReserved1;   //   reserved;   do   not   use   未使用      
       }   DCB;      
   
  6.改变端口设置      
   
       使用如下的两个方法      
       BOOL   GetCommState(hComm,&dcb);      
       BOOL   SetCommState(hComm,&dcb);      
   
  7.改变普通设置      
   
       BuildCommDCB(szSettings,&DCB);      
       szSettings的格式:baud   parity   data   stop      
       例:   "baud=96   parity=n   data=8   stop=1"      
       简写:"96,N,8,1"      
       szSettings   的有效值      
       baud:      
       11   or   110   =   110   bps      
       15   or   150   =   150   bps      
       30   or   300   =   300   bps      
       60   or   600   =   600   bps      
       12   or   1200   =   1200   bps      
       24   or   2400   =   2400   bps      
       48   or   4800   =   4800   bps      
       96   or   9600   =   9600   bps      
       19   or   19200=   19200bps      
       parity:      
       n=none      
       e=even      
       o=odd      
       m=mark      
       s=space      
       data:      
       5,6,7,8      
       StopBit      
       1,1.5,2      
   
  8.COMMCONFIG结构:      
   
       typedef   struct   _COMM_CONFIG   {      
       DWORD   dwSize;      
       WORD   wVersion;      
       WORD   wReserved;      
       DCB   dcb;      
       DWORD   dwProviderSubType;      
       DWORD   dwProviderOffset;      
       DWORD   dwProviderSize;      
       WCHAR   wcProviderData[1];      
       }   COMMCONFIG,   *LPCOMMCONFIG;      
       可方便的使用BOOL   CommConfigDialog(      
       LPTSTR   lpszName,      
       HWND   hWnd,      
       LPCOMMCONFIG   lpCC);      
       来设置串行口。      
   
  9.超时设置:      
   
       可通过COMMTIMEOUTS结构设置超时,      
       typedef   struct   _COMMTIMEOUTS   {      
       DWORD   ReadIntervalTimeout;      
       DWORD   ReadTotalTimeoutMultiplier;      
       DWORD   ReadTotalTimeoutConstant;      
       DWORD   WriteTotalTimeoutMultiplier;      
       DWORD   WriteTotalTimeoutConstant;      
       }   COMMTIMEOUTS,*LPCOMMTIMEOUTS;      
       区间超时:(仅对从端口中读取数据有用)它指定在读取两个字符之间要经历的时间      
       总超时:   当读或写特定的字节数需要的总时间超过某一阈值时,超时触发.      
       超时公式:      
       ReadTotalTimeout   =   (ReadTotalTimeoutMultiplier   *   bytes_to_read)      
       +   ReadToTaltimeoutConstant      
       WriteTotalTimeout   =   (WriteTotalTimeoutMuliplier   *   bytes_to_write)      
       +   WritetoTotalTimeoutConstant      
       NOTE:在设置超时时参数0为无限等待,既无超时      
       参数MAXDWORD为立即返回      
       超时设置:      
       GetCommTimeouts(hComm,&timeouts);      
       SetCommTimeouts(hComm,&timeouts);  

 

10.查询方式读写数据      
   
   例程:      
       COMMTIMEOUTS   to;      
       DWORD   ReadThread(LPDWORD   lpdwParam)      
       {      
       BYTE   inbuff[100];      
       DWORD   nBytesRead;      
       if(!(cp.dwProvCapabilities&PCF_INTTIMEOUTS))      
       return   1L;      
       memset(&to,0,sizeof(to));      
       to.ReadIntervalTimeout   =   MAXDWORD;      
       SetCommTimeouts(hComm,&to);      
       while(bReading)      
       {      
       if(!ReadFile(hComm,inbuff,100,&nBytesRead,NULL))      
       locProcessCommError(GetLastError());      
       else      
       if(nBytesRead)      
       locProcessBytes(inbuff,nBytesRead);      
       }      
       PurgeComm(hComm,PURGE_RXCLEAR);      
       return   0L;      
       }      
       NOTE:      
       PurgeComm()是一个清除函数,它可以中止任何未决的后台读或写,并且可以冲掉I/O缓冲区.      
       BOOL   PurgeComm(HANDLE   hFile,DWORD   dwFlags);      
       dwFlages的有效值:      
       PURGE_TXABORT:   中止后台写操作      
       PRUGE_RXABORT:   中止后台读操作      
       PRUGE_TXCLEAR:   清除发送缓冲区      
       PRUGE_RXCLEAR:   清除接收缓冲区      
    技巧:      
       可通过ClearCommError()来确定接收缓区中处于等待的字节数。      
       BOOL   ClearCommError(      
       HANDLE   hFile,   //   handle   to   communications   device      
       LPDWORD   lpErrors,   //   pointer   to   variable   to   receive   error   codes      
       LPCOMSTAT   lpStat   //   pointer   to   buffer   for   communications   status      
       );      
       ClearCommError()将返回一个COMSTAT结构:      
       typedef   struct   _COMSTAT   {   //   cst      
       DWORD   fCtsHold   :   1;   //   Tx   waiting   for   CTS   signal      
       DWORD   fDsrHold   :   1;   //   Tx   waiting   for   DSR   signal      
       DWORD   fRlsdHold   :   1;   //   Tx   waiting   for   RLSD   signal      
       DWORD   fXoffHold   :   1;   //   Tx   waiting,   XOFF   char   rec`d      
       DWORD   fXoffSent   :   1;   //   Tx   waiting,   XOFF   char   sent      
       DWORD   fEof   :   1;   //   EOF   character   sent      
       DWORD   fTxim   :   1;   //   character   waiting   for   Tx      
       DWORD   fReserved   :   25;   //   reserved      
       DWORD   cbInQue;   //   bytes   in   input   buffer      
       DWORD   cbOutQue;   //   bytes   in   output   buffer      
       }   COMSTAT,   *LPCOMSTAT;      
       其中的cbInQue和cbOutQue中即为缓冲区字节。      
   
  11.同步I/O读写数据      
   
       COMMTIOMOUTS   to;      
       DWORD   ReadThread(LPDWORD   lpdwParam)      
       {      
       BYTE   inbuff[100];      
       DWORD   nByteRead,dwErrorMask,nToRead;      
       COMSTAT   comstat;      
       if(!cp.dwProvCapabilities&PCF_TOTALTIMEOUTS)      
       return   1L;      
       memset(&to,0,sizeof(to));      
       to.ReadTotalTimeoutMultiplier   =   5;      
       to.ReadTotalTimeoutConstant   =   50;      
       SetCommTimeouts(hComm,&to);      
       while(bReading)      
       {      
       ClearCommError(hComm,&dwErrorMask,&comstat);      
       if(dwErrorMask)      
       locProcessCommError(dwErrorMask);      
       if(comstat.cbInQue   >100)      
       nToRead   =   100;      
       else      
       nToRead   =   comstat.cbInQue;      
       if(nToRead   ==   0)      
       continue;      
       if(!ReadFile(hComm,inbuff,nToRead,&nBytesRead,NULL))      
       locProcessCommError(GetLastError());      
       else      
       if(nBytesRead)      
       locProcessBytes(inbuff,nBytesRead);      
       }      
       return   0L;      
       }

阅读更多
上一篇如何在WinCE中使用超过64兆的内存
下一篇关于断言——assert
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭