⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vc实现串口通信例程.txt

📁 用VC 6.O实现的一个串口通信例程,希望能对初学者有所帮助.
💻 TXT
📖 第 1 页 / 共 2 页
字号:

 例程:  
   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;  
   }  

12.异步I/O读写数据  

   当CreateFile()中的fdwAttrsAndFlags参数为FILE_FLAG_OVERLAPPEN时, 端口是为异步I/O打开的,此时可以在ReadFile的最后一个参数中指定一个OVERLAPPED结构,使数据的读操作在后台进行。WINDOWS 95包括了异步I/O的许多变种。  
   typedef struct _OVERLAPPED {  
   DWORD Internal;  
   DWORD InternalHigh;  
   DWORD Offset;  
   DWORD OffsetHigh;  
   HANDLE hEvent;  
   } OVERLAPPED;  
   对于串行口仅hEvent成员有效,其于成员必须为0。  
   例程:  
   COMMTIMEOUTS to;  
   ...  
   DWORD ReadThread((LPDWORD lpdwParam)  
   {  
   BYTE inbuff[100];  
   DWORD nRytesRead,endtime,lrc;  
   static OVERLAPPED o;  
   if(!cp.dwProvCapabilities & PCF_TOTALTIMEOUTS)  
   return 1L;  
   memset(&to,0,sizeof(to));  
   to.ReadTotalTimeoutMultiplier = 5;  
   to.ReadTotalTimeoutConstant = 1000;  
   SetCommTimeouts(hComm,&to);  
   o.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);  
   while(bReading)  
   {  
   if(!ReadFile(hComm,inbuff,10,&nBytesRead,&o))  
   {  
   nBytesRead = 0;  
   if(lrc=GetLastError() == ERROR_IO_PENDING)  
   {  
   endtime = GetTickCount() + 1000;  
   while(!GetOverlappedResult(hComm,&o,&nBytesRead,FALSE))  
   if(GetTickCount() > endtime) break;  
   }  
   if(nBytesRead) locProcessBytes(inbuff,nBytesRead);  
   }  
   else  
   {  
   if(nBytesRead) locProcessBytes(inbuff,nBytesRead);  
   ResetEvent(o.hEvent);  
   }  
   }  
   PurgeComm(hComm,PURGE_RXCLEAR);  
   return 0L;  
   }  
   这一例程是对一开始读缓冲区就读到所需的字节时的处理:  
   while(bReading)  
   {  
   if(!ReadFile(hComm,inbuff,10,&nBytesRead,&o))  
   {  
   if((lrc=GetLastError()) ==ERROR_IO_PENDING)  
   {  
   if(GetOverlappedResult(hComm,&o,&nBytesRead,TRUE))  
   {  
   if(nBytesRead)  
   locProcessBytesa(inbuff,nBytesRead);  
   }  
   else  
   locProcessCommError(GetLastError());  
   }  
   else  
   locProcessCommError(GetLastError));  
   }  
   else  
   if(nBytesRead) locProcessBytes(inbuff,nBytesRead);  
   ResetEvent(o.hEvent);  
   }  

13.事件驱I/O读写:  

   GetCommMask(hComm,&dwMask)  
   Windows 95报告给应用程序的事件由此方法返回。  
   SetCommMasl(hComm,&dwMask)  
   添加或修改Windows 95所报告的事件列表。  
   事件掩码如下:  
   EV_BREAK 检测到输入为止  
   EV_CTS CTS(清除发送)信号改变状态  
   EV_DSR DSR(数据设置就绪)信号改变状态  
   EV_ERR 发生了线路状态错误.  
   线路状态错误为:  
   CE_FRAME(帧错误)  
   CE_OVERRUN(接收缓冲区超限)  
   CE_RXPARITY(奇偶校验错误)  
   EV_RING 检测到振铃  
   EV_RLSD RLSD(接收线路信号检测)信号改变状态  
   EV_EXCHAR 接收到一个字符,并放入输入缓冲区  
   EV_RXFLAG 接收到事件字符(DCB成员的EvtChar成员),度放入输入缓冲区  
   EV_TXEMPTY 输出缓冲区中最后一个字符发送出去  
   在用SetCommMask指定了有用的事件后,应用程序可调用WaitCommEvent()来等待事件发生.  
   BOOL WaitCommEvent(  
   HANDLE hFile, // handle of communications device  
   LPDWORD lpEvtMask, // address of variable for event that occurred  
   LPOVERLAPPED lpOverlapped, // address of overlapped structure  
   );  
   此方法可以以同步或异步方式操作  
   例程:  
   COMMTIMEOUTS to;  
   ...  
   DWORD ReadTherad(LPDWORD lpdwParam)  
   {  
   BYTE binbuff[100];  
   DWORD nBytesRead,dwEvent,dwError;  
   COMSTAT cs;  
   SetCommMask(hComm,EV_RXHAR);  
   while(bReading)  
   {  
   if(WaitCommEvent(hComm,&dwEvent,NULL))  
   {  
   ClearCommError(hComm,&dwError,&cs);  
   if((dwEvent&EV_RXCHAR)&&cs.cbInQue)  
   {  
   if(!ReadFile(hComm,inbuff,cs.cbInQue,&nBytesRead,NULL)  
   locProcessCommError(GetLastError());  
   }  
   else  
   {  
   if(nByteRead)  
   locProcessBytes(inbuff,nBytesRead);  
   }  
   else  
   locProcessCommError(GetLastError());  
   }  
   PurgeComm(hComm,PURGE_RXCLEAR);  
   return 0L;  
   }  
   NOTE: SetCommMask(hComm,0)可使WaitCommEvent()中止.  
   可使用GetCommmodemStatus()方法,例程:  
   if(cp.dwProvCapabilities&PCF_RTSCTS)  
   {  
   SetCommMask(hComm,EV_CTS);  
   WaitCommEvent(hComm,&dwMask,NULL);  
   if(dwMask&EV_CTS)  
   {  
   GetCommModemStatus(hComm,&dwStatus)  
   if(dwStatus&MS_CTS_ON) /* CTS stransition OFF-ON */  
   else /* CTS stransition ON-OFF */  
   }  
   }  
   MS_CTS_ON CTS为ON  
   MS_DSR_ON DSR为ON  
   MS_RING_ON RING为ON  
   MS_ELSD_ON RLSD为ON  

14.错误  

   当发生错误时应用方法ClearCommError(hComm,&dwErrorMask,&constat)得到错误掩码。  
   CE_BREAK 中止条件  
   CE_FRAME 帧错误  
   CW_IOE 一般I/O错误,常伴有更为详细的错误标志  
   CE_MODE 不支持请求的模式  
   CE_OVERRUN 缓冲区超限下一个字符将丢失  
   CE_RXOVER 接收缓冲区超限  
   CE_RXPARITY 奇偶校验错误  
   CE_TXFULL 发送缓冲区满  
   CE_DNS 没有选择并行设备  
   CE_PTO 并行设备发生超时  
   CE_OOP 并行设备缺纸  

15.控制命令  

   EscapeCommFunction()可将硬件信号置ON或OFF,模拟XON或XOFF  

  BOOL EscapeCommFunction(  
   HANDLE hFile, // handle to communications device  
   DWORD dwFunc // extended function to perform  
   );  
   dwFunc的有效值(可用’|’同时使用多个值)  
   CLRDTR DTR置OFF  
   CLRRTS RTS置OFF  
   SETDTR STR置ON  
   SETRTS TRS置ON  
   SETXOFF 模拟XOFF字符的接收  
   SETXON 模拟XON字符的接收  
   SETBREAK 在发送中产生一个中止  
   CLRBREAK 在发送中清除中止  
  




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -