设为首页 加入收藏

TOP

13.6.4 串口线程函数的实现
2013-10-07 14:36:13 来源: 作者: 【 】 浏览:52
Tags:13.6.4 串口 线程 函数 实现

13.6.4  串口线程函数的实现

串口线程处理函数CommThread()实现监控串口事件的功能,根据串口事件进行相应的处理,实现如下:

  1. 01  UINT CMySerial::CommThread(LPVOID pParam)  
  2. 02  {  
  3. 03      CMySerial *port = (CMySerial*)pParam;           //串口类指针  
  4. 04      //串口线程活动标识  
  5. 05      port->m_bThreadAlive = TRUE;  
  6. 06      //串口信息变量  
  7. 07      DWORD BytesTransfered = 0;   
  8. 08      DWORD Event = 0;  
  9. 09      DWORD CommEvent = 0;  
  10. 10      DWORD dwError = 0;  
  11. 11      COMSTAT comstat;  
  12. 12      BOOL  bResult = TRUE;  
  13. 13      //强制关闭串口  
  14. 14      if (port->m_hComm)    
  15. 15      {//清空串口缓冲  
  16. 16          PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR |   
  17. 17                      PURGE_RXABORT | PURGE_TXABORT);  
  18. 18      }  
  19. 19    
  20. 20      //线程的循环体  
  21. 21      for (;;)   
  22. 22      {   
  23. 23          bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);  
  24. 24          //读取失败处理  
  25. 25          if (!bResult)    
  26. 26          {   
  27. 27              switch (dwError = GetLastError())   
  28. 28              {   
  29. 29              case ERROR_IO_PENDING:    
  30. 30                  {   //读取串口为空   
  31. 31                      break;  
  32. 32                  }  
  33. 33              case 87:  
  34. 34                  {  
  35. 35                      break;  
  36. 36                  }  
  37. 37              default:  
  38. 38                  {   //错误处理  
  39. 39                      port->ProcessErrorMessage("WaitCommEvent()");  
  40. 40                      break;  
  41. 41                  }  
  42. 42              }  
  43. 43          }  
  44. 44          else  
  45. 45          {  
  46. 46              //清空串口错误  
  47. 47              bResult = ClearCommError(port->m_hComm, &dwError, &comstat);  
  48. 48              if (comstat.cbInQue == 0)  
  49. 49                  continue;  
  50. 50          }  
  51. 51          //获取串口事件并进行相应处理  
  52. 52          Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE,           INFINITE);  
  53. 53          switch (Event)  
  54. 54          {  
  55. 55          case 0: //关闭串口  
  56. 56                  CloseHandle(port->m_hComm);  
  57. 57                  port->m_hComm=NULL;  
  58. 58                  port->m_bThreadAlive = FALSE;  
  59. 59                  AfxEndThread(100);  
  60. 60                  break;  
  61. 61          case 1: //读串口  
  62. 62                  GetCommMask(port->m_hComm, &CommEvent);  
  63. 63                  if (CommEvent & EV_RXCHAR)  
  64. 64                      ReceiveChar(port, comstat);  
  65. 65                  break;  
  66. 66          case 2: //写串口  
  67. 67                  WriteChar(port);  
  68. 68                  break;  
  69. 69          }  
  70. 70      }  
  71. 71      return 0;  
  72. 72  } 

【代码解析】

第3行获保存串口类指针,第5行将串口线程活动标识置为真。第14~18行判断串口是否已经打开,如是则清空串口缓冲。第21~70行是串口线程的主循环体。第23行等待串口的异步通信事件,如果等待失败则在第25~43行进行处理,否则在第47行获取串口中尚未读取的字节数,第48行判断接收到的字节数是否为空,如是则在第49行跳出本次循环。第52行等待串口的3个事件,第53行判断接收到的串口事件类型。第55~60行处理关闭串口事件,第62~64行处理读串口事件,第67、68行处理写串口事件。

第23行的WaitCommEvent()为一个特指的通信设备等待一个事件发生,该函数所监控的事件是与该设备句柄相关联的一系列事件。

  1. BOOL WINAPI WaitCommEvent(   
  2.     HANDLE hFile,               //指向通信设备的一个句柄  
  3.     LPDWORD lpEvtMask,          //一个指向DWORD的指针  
  4.     LPOVERLAPPED lpOverlapped   //指向OVERLAPPED结构体的一个指针  
  5. ); 

参数lpOverlapped指向OVERLAPPED结构体的一个指针。如果hFile是用异步方式打开的(在CreateFile()函数中,该参数设置为FILE_FLAG_OVERLAPPED)。该参数不能指向一个空OVERLAPPED结构体,而是与Readfile()和WreteFile()中的OVERLAPPED参数为同一个参数。如果hFile是用异步方式打开的,而lpOverlapped 指向一个空的OVERLAPPED结构体,那么函数会错误地报告,等待的操作已经完成(而此时等待的操作可能还没有完成)。

第52行的WaitForMultipleObjects()函数可以等待Windows中的所有内核对象,函数原型如下:

  1. DWORD WaitForMultipleObjects(     
  2.     DWORD nCount,               //指定等待事件对象的数量  
  3.     const HANDLE* lpHandles,    //是等待事件数组  
  4.     BOOL bWaitAll,              //是否等待所有事件对象  
  5.     DWORD dwMilliseconds        //等待事件对象的超时时间  
  6. ); 


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇13.6.1 构造及析构函数的实现 下一篇13.6.3 ProcessErrorMessage()函..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: