串口程序中函数使用WaitCommEvent、ClearCommError、GetcommMask

来源:互联网 发布:mac下载的软件在哪里 编辑:程序博客网 时间:2024/05/16 08:31

在串口程序中的几个函数的联合使用

一、首先是利用WaitCommEvent来等待串口事件的被触发,这些事件是指在该函数被调用前,我们自己设置好的能触发串口线程的有效事件。

主要包括3类事件:

  1.函数SetCommMask (ceSeries->m_hComm, EV_RXCHAR |EV_CTS | EV_DSR )设置的数据接收中断

  2.用户中断线程的操作。

  3.用户发送数据所产生的中断。

该函数相当于利用事件来同步,实际函数也是这么设计的。但没有有效中断触发,线程会一直在这里等待。

一旦被触发,程序才能继续往下执行。

 

二、函数WaitCommEvent执行完成后,他的返回值若为零,说明有错误,这时候用GetLastError来查询错误类型。

 

三、函数WaitCommEvent执行返回值若为1则用ClearCommError来清除错误,并查询串口的状态,得到comstat的值。

 

四、检查ClearCommError所查询的串口状态comstat.cbInQue的值,若不大于0,说明错误。继续等待事件的触发

 

五、若omstat.cbInQue大于0,说明buffer里面有字符。在使用WaitForMultipleObjects函数确认事件,并执行对应的操作。

 

//WaitCommEvent函数为指定的通信资源监听一系列的Event,这些Event可以由 SetcommMask GetcommMask函数来设置和查询。

 

 

例子:

 

bResult =WaitCommEvent(port->m_hComm, &Event, &port->m_ov);

   
     if (!bResult)  
   
     
   
         // If WaitCommEvent() returns FALSE,process the last error to determin
   
         switch (dwError =GetLastError()) 
   
         
   
         case ERROR_IO_PENDING:    
   
             
   
                 break;
   
             }
   
         case 87:
   
             {
   
                 break;
   
             }
   
         default:
   
             {
   
                 port->ProcessErrorMessage("WaitCommEvent()");
   
                 break;
   
             }
   
         }
   
     }
   
     else
   
     {
    
     
   
         bResult =ClearCommError(port->m_hComm, &dwError, &comstat);

   
         if (comstat.cbInQue == 0)
   
             continue;
   
     }    // end if bResult

   
         //m_hEventArray[0] =m_hShutdownEvent;    // highest priority
   
         //m_hEventArray[1] = m_ov.hEvent;
   
         //m_hEventArray[2] = m_hWriteEvent;
   
     Event = WaitForMultipleObjects(3,port->m_hEventArray, FALSE, INFINITE);

   
     switch (Event)
   
     {
   
     case 0:
   
         {
   
             // Shutdown event.  This is event zero so it will be// thehigest priority and be serviced first.                
   
             CloseHandle(port->m_hComm);
   
             port->m_hComm=NULL;
   
             port->m_bThreadAlive =FALSE;                
   
             // Kill this thread.  break is not needed, but makes me feelbetter.
   
             AfxEndThread(100);

   
             break;
   
         }
   
     case 1:    // read event
   
         {
   
             GetCommMask(port->m_hComm,&CommEvent);
   
             if (CommEvent & EV_RXCHAR)
   
                 // Receive character event from port.
   
                 ReceiveChar(port, comstat);
   
             if (CommEvent & EV_CTS)
   
                 ::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
   
             if (CommEvent & EV_BREAK)
   
                 ::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
   
             if (CommEvent & EV_ERR)
   
                 ::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
   
             if (CommEvent & EV_RING)
   
                 ::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
   
             
   
             if (CommEvent & EV_RXFLAG)
   
                 ::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
   
                 
   
             break;
   
         }  
   
     case 2: // write event
   
         {
   
             // Write character event from port
   
             WriteChar(port);
   
             break;
   
         }

   
     } // end switch

   
 } // closeforever loop

 

阅读全文
0 0
原创粉丝点击