设为首页 加入收藏

TOP

13.6.2 串口打开函数的实现
2013-10-07 14:36:08 来源: 作者: 【 】 浏览:52
Tags:13.6.2 串口 打开 函数 实现

13.6.2  串口打开函数的实现

打开串口函数OpenSerialPort()将根据传入的参数打开相应的串口,并设置这个串口的属性,实现如下:

  1. 01  bool CMySerial::OpenSerialPort(CWnd* pParent, UINT portnr, UINT baud,   
  2. 02                              char parity, UINT databits, UINT stopbits,   
  3. 03                              DWORD dwCommEvents, UINT writebuffersize)  
  4. 04  {  
  5. 05      assert(portnr > 0 && portnr < 5);  
  6. 06      assert(pParent != NULL);  
  7. 07      if (m_bThreadAlive)                 //如果串口监控线程活动,则关闭它  
  8. 08      {  
  9. 09          do  
  10. 10          {  
  11. 11              SetEvent(m_hShutdownEvent);  
  12. 12          } while (m_bThreadAlive);  
  13. 13          TRACE("Thread ended\n");  
  14. 14      }  
  15. 15      if (m_ov.hEvent != NULL)            //创建串口异步通信事件  
  16. 16          ResetEvent(m_ov.hEvent);   
  17. 17      else  
  18. 18          m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);   
  19. 19      if (m_hWriteEvent != NULL)          //创建发送事件  
  20. 20          ResetEvent(m_hWriteEvent);  
  21. 21      else  
  22. 22          m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  
  23. 23      if (m_hShutdownEvent != NULL)       //创建关闭串口事件  
  24. 24          ResetEvent(m_hShutdownEvent);  
  25. 25      else  
  26. 26          m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  
  27. 27      m_hEventArray[0] = m_hShutdownEvent;    //具有最高的优先级  
  28. 28      m_hEventArray[1] = m_ov.hEvent;  
  29. 29      m_hEventArray[2] = m_hWriteEvent;  
  30. 30      InitializeCriticalSection(&m_csCommunicationSync); //初始化临界资源  
  31. 31      m_pParent = pParent;                    //保存串口操作窗口指针  
  32. 32      if (m_szWriteBuffer != NULL)            //为发送缓冲申请空间  
  33. 33          delete [] m_szWriteBuffer;  
  34. 34      m_szWriteBuffer = new char[writebuffersize];   
  35. 35      m_nPortNr = portnr;                     //保存串口号  
  36. 36      m_nWriteBufferSize = writebuffersize;   //将要发送的数据     
  37. 37      m_dwCommEvents = dwCommEvents;          //串口事件  
  38. 38       BOOL bResult = FALSE;  
  39. 39      char *szPort = new char[50];            //数据缓冲区  
  40. 40      char *szBaud = new char[50];  
  41. 41      EnterCriticalSection(&m_csCommunicationSync);   //锁定临界变量  
  42. 42      if (m_hComm != NULL)                    //确保串口处于关闭状态  
  43. 43      {  
  44. 44          CloseHandle(m_hComm);  
  45. 45          m_hComm = NULL;  
  46. 46      }  
  47. 47      sprintf(szPort, "COM%d", portnr);       //串口状态信息  
  48. 48      sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d",  
  49. 49                  baud, parity, databits, stopbits);  
  50. 50      //打开串口  
  51. 51      m_hComm = CreateFile( szPort,           //串口号  
  52. 52                          GENERIC_READ |      //读模式  
  53. 53                          GENERIC_WRITE,      //写模式  
  54. 54                          0,                  //必须为0  
  55. 55                          NULL,               //安全性属性结构  
  56. 56                          OPEN_EXISTING,      //必须置为OPEN_EXISTING  
  57. 57                          FILE_FLAG_OVERLAPPED,   //使用异步的I/O  
  58. 58                          NULL);              //必须为NULL  
  59. 59      if (m_hComm == INVALID_HANDLE_VALUE)  
  60. 60      {   //打开失败  
  61. 61          delete [] szPort;  
  62. 62          delete [] szBaud;  
  63. 63          return FALSE;  
  64. 64      }  
  65. 65      //超时参数  
  66. 66      m_CommTimeouts.ReadIntervalTimeout = 1000;  
  67. 67      m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;  
  68. 68      m_CommTimeouts.ReadTotalTimeoutConstant = 1000;  
  69. 69      m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;  
  70. 70      m_CommTimeouts.WriteTotalTimeoutConstant = 1000;  
  71. 71      if (SetCommTimeouts(m_hComm, &m_CommTimeouts)) //设置串口参数  
  72. 72      {   //超时设置  
  73. 73          if (SetCommMask(m_hComm, dwCommEvents))  
  74. 74          {   //事件设置  
  75. 75              if (GetCommState(m_hComm, &m_dcb))  
  76. 76              {   //参数设置  
  77. 77                  m_dcb.EvtChar = 'q';  
  78. 78                  m_dcb.fRtsControl = RTS_CONTROL_ENABLE;   
  79. 79                  if (BuildCommDCB(szBaud, &m_dcb))  
  80. 80                  {  
  81. 81                      if (!SetCommState(m_hComm, &m_dcb))  
  82. 82                          ProcessErrorMessage("SetCommState()");  
  83. 83                  }  
  84. 84                  else    //串口参数设置失败  
  85. 85                      ProcessErrorMessage("BuildCommDCB()");  
  86. 86              }  
  87. 87              else    //串口参数获取失败  
  88. 88                  ProcessErrorMessage("GetCommState()");  
  89. 89          }  
  90. 90          else    //串口事件设置失败  
  91. 91              ProcessErrorMessage("SetCommMask()");  
  92. 92      }  
  93. 93      else    //串口超时设置失败  
  94. 94          ProcessErrorMessage("SetCommTimeouts()");  
  95. 95      delete [] szPort;                               //清空数据缓冲区  
  96. 96      delete [] szBaud;  
  97. 97      PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR |   
  98. 98                  PURGE_RXABORT | PURGE_TXABORT);  
  99. 99      LeaveCriticalSection(&m_csCommunicationSync);    //解锁临界变量  
  100. 100     return TRUE;  
  101. 101 } 

【代码解析】

OpenSerialPort()函数的第7~14行判断串口监控线程是否活动,如是则将其关闭。第15~26行创建并启动串口的3个事件。第27~29行将创建的事件句柄保存到事件数组中。第30行初始化临界资源,方便后面的使用。第32、33行申请一段发送缓冲区。第34~36行保存传入的参数。第55行锁定临界资源。第42~44行确保串口已经被关闭。第51~58行打开串口。第59~64行判断是否打开串口成功,否则释放资源后返回。第66~70行设置串口通信超时参数。第71~92行将前面准备好的串口的所有属性设置到串口上,设置失败后调用ProcessErrorMessage()函数进行失败处理。第95、96行释放资源。第97、98行清空串口的缓冲区。第99行解锁临界资源,其他线程此后便可以使用这个临界资源。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇13.6.3 ProcessErrorMessage()函.. 下一篇13.6 自定义串口类

评论

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