CommRS232.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include "StdAfx.h"
  2. #include "CommRS232.h"
  3. CCommRS232::CCommRS232(void)
  4. {
  5. m_hComm = NULL;
  6. m_bOpened = FALSE;
  7. m_byCommPort = 1;
  8. m_dwBaudRate = BAUD_9600;
  9. m_bySize = 8;
  10. m_byParity = 0;
  11. m_byStopBits = 1;
  12. m_byStartAddr = 1;
  13. m_nInterval = 1000;
  14. }
  15. CCommRS232::~CCommRS232(void)
  16. {
  17. if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE )
  18. CloseHandle(m_hComm);
  19. m_hComm = NULL;
  20. m_bOpened = FALSE;
  21. }
  22. BOOL CCommRS232::InitComm( IN CONST BYTE& byCommPort, IN CONST DWORD& dwBaudRate, IN CONST BYTE& bySize, IN CONST BYTE& byParity, IN CONST BYTE& byStopBits, IN CONST BYTE& byStartAddr, IN CONST INT& nInterval )
  23. {
  24. ASSERT(byCommPort);
  25. m_byCommPort = byCommPort;
  26. m_dwBaudRate = dwBaudRate;
  27. m_bySize = bySize;
  28. m_byParity = byParity;
  29. m_byStopBits = byStopBits;
  30. m_byStartAddr = byStartAddr;
  31. m_nInterval = nInterval;
  32. // 关闭串口句柄;
  33. m_bOpened = FALSE;
  34. if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE )
  35. {
  36. CloseHandle(m_hComm);
  37. }
  38. m_hComm = NULL;
  39. DCB dcb;
  40. COMMTIMEOUTS timeout;
  41. BOOL bResult = FALSE;
  42. TCHAR szTmp[MAX_PATH] = _T("\\\\.\\com");
  43. TCHAR szPort[5] = {0};
  44. _ltot_s(byCommPort, szPort, 10);
  45. _tcscat_s(szTmp, szPort);
  46. // 以独占方式打开串口;
  47. m_hComm = CreateFile(szTmp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL , NULL);
  48. if( m_hComm == INVALID_HANDLE_VALUE)
  49. {
  50. LOG4C_NO_FILENUM((LOG_NOTICE,"打开串口失败:%s",szTmp));
  51. return FALSE;
  52. }
  53. // SetupComm设置缓冲区大小;
  54. bResult = SetupComm(m_hComm, 1024, 1024);
  55. ASSERT(bResult);
  56. if( !bResult )
  57. return FALSE;
  58. // 在串口读写之前,清除缓冲区;
  59. bResult = PurgeComm(m_hComm, PURGE_TXCLEAR|PURGE_RXCLEAR);
  60. ASSERT(bResult);
  61. if(!bResult)
  62. return FALSE;
  63. //////////////////////////////////////////////////////////////////////////
  64. // GetCommState获取设备控制块状态;
  65. bResult = GetCommState(m_hComm, &dcb);
  66. ASSERT(bResult);
  67. if(!bResult)
  68. return FALSE;
  69. dcb.Parity = byParity;
  70. if(dcb.Parity == NOPARITY)
  71. dcb.fParity = FALSE;
  72. else
  73. dcb.fParity = TRUE;
  74. dcb.BaudRate = dwBaudRate;
  75. dcb.ByteSize = bySize;
  76. dcb.StopBits = byStopBits;
  77. if(dcb.ByteSize == 8)
  78. dcb.StopBits = ONESTOPBIT;
  79. // SetCommState设置设备的控制块状态;
  80. bResult = SetCommState(m_hComm, &dcb);
  81. ASSERT(bResult);
  82. if(!bResult)
  83. return FALSE;
  84. //////////////////////////////////////////////////////////////////////////
  85. // 获取设备的超时值;
  86. bResult = GetCommTimeouts(m_hComm, &timeout);
  87. ASSERT(bResult);
  88. if(!bResult)
  89. return FALSE;
  90. timeout.ReadIntervalTimeout = MAXDWORD;
  91. timeout.ReadTotalTimeoutMultiplier = 0;
  92. timeout.ReadTotalTimeoutConstant = 0;
  93. timeout.WriteTotalTimeoutMultiplier = 0;
  94. timeout.WriteTotalTimeoutConstant = 0;
  95. // 设置设备的超时值;
  96. bResult = SetCommTimeouts(m_hComm,&timeout);
  97. ASSERT(bResult);
  98. if(!bResult)
  99. return FALSE;
  100. m_bOpened = TRUE;
  101. return TRUE;
  102. }
  103. BOOL CCommRS232::CloseComm()
  104. {
  105. BOOL bRet = FALSE;
  106. if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE )
  107. bRet = CloseHandle(m_hComm);
  108. if ( bRet == FALSE )
  109. return FALSE;
  110. m_hComm = NULL;
  111. m_bOpened = FALSE;
  112. return TRUE;
  113. }
  114. INT CCommRS232::Write(IN BYTE *pWirteBuf, IN CONST INT& nWriteSize)
  115. {
  116. if ( !m_bOpened ) return 0;
  117. if ( m_hComm == NULL || m_hComm == INVALID_HANDLE_VALUE )
  118. return 0;
  119. DWORD dwBytesWritten = 0; // 实际写入的字节数;
  120. if ( WriteFile( m_hComm, pWirteBuf, nWriteSize, &dwBytesWritten, NULL) )
  121. {
  122. return dwBytesWritten;
  123. }
  124. return 0;
  125. }
  126. INT CCommRS232::Read(IN BYTE *pReadBuf, IN CONST INT& nReadSize)
  127. {
  128. if ( m_hComm == NULL || m_hComm == INVALID_HANDLE_VALUE )
  129. {
  130. LOG4C_NO_FILENUM((LOG_NOTICE,"串口句柄空"));
  131. return 0;
  132. }
  133. if ( pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, nReadSize, FALSE) )
  134. {
  135. LOG4C_NO_FILENUM((LOG_NOTICE,"缓冲区指针无效"));
  136. return 0;
  137. }
  138. if ( !m_bOpened )
  139. {
  140. LOG4C_NO_FILENUM((LOG_NOTICE,"串口状态无效"));
  141. return 0;
  142. }
  143. BOOL bResult = FALSE;
  144. DWORD dwBytesRead = 0;
  145. DWORD dwErrorFlags = 0;
  146. // ReadFile前,使用ClearCommError清除错误;
  147. COMSTAT ComStat;
  148. ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
  149. DWORD dwTick = GetTickCount();
  150. while ( ComStat.cbInQue <= 0 )
  151. {// cbInQue表示输入缓冲区的字节数;
  152. if ( GetTickCount() - dwTick > 3000)
  153. break;
  154. ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
  155. Sleep(100);
  156. }
  157. if ( ComStat.cbInQue <= 0 )
  158. {
  159. LOG4C_NO_FILENUM((LOG_NOTICE,"串口无返回"));
  160. return 0;
  161. }
  162. dwBytesRead = (DWORD) ComStat.cbInQue;
  163. if ( nReadSize < (INT)dwBytesRead )
  164. {
  165. dwBytesRead = (DWORD)nReadSize;
  166. }
  167. if ( ReadFile(m_hComm, pReadBuf, dwBytesRead, &dwBytesRead, NULL) )
  168. {
  169. LOG4C_NO_FILENUM((LOG_NOTICE,"读:%s,%d", pReadBuf, dwBytesRead));
  170. return (INT)dwBytesRead;
  171. }
  172. DWORD dwError;
  173. dwError = GetLastError();
  174. CString strMsg;
  175. strMsg.Format("ReadFile Error! ErrorCode = %d", dwError);
  176. LOG4C_NO_FILENUM((LOG_NOTICE,"串口读失败:%s",strMsg));
  177. return 0;
  178. }