SynSerial.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include "StdAfx.h"
  2. #include "SynSerial.h"
  3. CSynSerial::CSynSerial(void) :m_hSerialPort(NULL)
  4. , m_dwInQueue(1024)
  5. , m_dwOutQueue(1024)
  6. {
  7. memset(&m_dcb, 0, sizeof(DCB));
  8. memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
  9. memset(&m_szSerialPort, 0, sizeof(TCHAR)*MAX_PORT_LEN);
  10. // 初始化重叠对象;
  11. ZeroMemory(&m_wrOverlapped,sizeof(m_wrOverlapped));
  12. if (m_wrOverlapped.hEvent != NULL) {
  13. ResetEvent(m_wrOverlapped.hEvent);
  14. m_wrOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  15. }
  16. }
  17. CSynSerial::~CSynSerial(void)
  18. {
  19. CloseSerialPort();
  20. }
  21. BOOL CSynSerial::OpenSerialPort(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)
  22. {
  23. ASSERT(byCommPort);
  24. CloseSerialPort();
  25. _stprintf_s(m_szSerialPort, _T("\\\\.\\com%d"), (int)byCommPort);
  26. m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  27. if (m_hSerialPort == INVALID_HANDLE_VALUE)
  28. {
  29. // 打开串口失败;
  30. DWORD dwError = GetLastError();
  31. return FALSE;
  32. }
  33. BOOL bResult = FALSE;
  34. // SetupComm设置缓冲区大小;
  35. bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
  36. if (!bResult)
  37. {
  38. CloseHandle(m_hSerialPort);
  39. m_hSerialPort = INVALID_HANDLE_VALUE;
  40. DWORD dwError = GetLastError();
  41. return FALSE;
  42. }
  43. // 在串口读写之前,清除缓冲区;
  44. bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
  45. if (!bResult)
  46. {
  47. CloseHandle(m_hSerialPort);
  48. m_hSerialPort = INVALID_HANDLE_VALUE;
  49. DWORD dwError = GetLastError();
  50. return FALSE;
  51. }
  52. // GetCommState获取设备控制块状态;
  53. memset(&m_dcb, 0, sizeof(DCB));
  54. bResult = GetCommState(m_hSerialPort, &m_dcb);
  55. if (!bResult)
  56. {
  57. CloseHandle(m_hSerialPort);
  58. m_hSerialPort = INVALID_HANDLE_VALUE;
  59. DWORD dwError = GetLastError();
  60. return FALSE;
  61. }
  62. m_dcb.Parity = byParity;
  63. if (m_dcb.Parity == NOPARITY)
  64. m_dcb.fParity = FALSE;
  65. else
  66. m_dcb.fParity = TRUE;
  67. m_dcb.BaudRate = dwBaudRate;
  68. m_dcb.ByteSize = bySize;
  69. m_dcb.StopBits = byStopBits;
  70. if (m_dcb.ByteSize == 8)
  71. m_dcb.StopBits = ONESTOPBIT;
  72. // SetCommState设置设备的控制块状态;
  73. memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
  74. bResult = SetCommState(m_hSerialPort, &m_dcb);
  75. if (!bResult)
  76. {
  77. CloseHandle(m_hSerialPort);
  78. m_hSerialPort = INVALID_HANDLE_VALUE;
  79. DWORD dwError = GetLastError();
  80. return FALSE;
  81. }
  82. // 获取设备的超时值;
  83. bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
  84. if (!bResult)
  85. {
  86. CloseHandle(m_hSerialPort);
  87. m_hSerialPort = INVALID_HANDLE_VALUE;
  88. DWORD dwError = GetLastError();
  89. return FALSE;
  90. }
  91. // 两字符之间最大的延时,设置0表示参数不起作用;
  92. m_cts.ReadIntervalTimeout = 50;
  93. m_cts.ReadTotalTimeoutMultiplier = 100;
  94. m_cts.ReadTotalTimeoutConstant = 8000;
  95. m_cts.WriteTotalTimeoutMultiplier = 100;
  96. m_cts.WriteTotalTimeoutConstant = 5000;
  97. // 设置设备的超时值;
  98. bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
  99. if (!bResult)
  100. {
  101. CloseHandle(m_hSerialPort);
  102. m_hSerialPort = INVALID_HANDLE_VALUE;
  103. DWORD dwError = GetLastError();
  104. return FALSE;
  105. }
  106. return TRUE;
  107. }
  108. BOOL CSynSerial::ReOpenSerialPort()
  109. {
  110. ASSERT(_tcslen(m_szSerialPort));
  111. CloseSerialPort();
  112. m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  113. if (m_hSerialPort == INVALID_HANDLE_VALUE)
  114. {
  115. // 打开串口失败;
  116. DWORD dwError = GetLastError();
  117. return FALSE;
  118. }
  119. BOOL bResult = FALSE;
  120. // SetupComm设置缓冲区大小;
  121. bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
  122. if (!bResult)
  123. {
  124. CloseHandle(m_hSerialPort);
  125. m_hSerialPort = INVALID_HANDLE_VALUE;
  126. DWORD dwError = GetLastError();
  127. return FALSE;
  128. }
  129. // 在串口读写之前,清除缓冲区;
  130. bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
  131. if (!bResult)
  132. {
  133. CloseHandle(m_hSerialPort);
  134. m_hSerialPort = INVALID_HANDLE_VALUE;
  135. DWORD dwError = GetLastError();
  136. return FALSE;
  137. }
  138. // SetCommState设置设备的控制块状态;
  139. memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
  140. bResult = SetCommState(m_hSerialPort, &m_dcb);
  141. if (!bResult)
  142. {
  143. CloseHandle(m_hSerialPort);
  144. m_hSerialPort = INVALID_HANDLE_VALUE;
  145. DWORD dwError = GetLastError();
  146. return FALSE;
  147. }
  148. // 设置设备的超时值;
  149. bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
  150. if (!bResult)
  151. {
  152. CloseHandle(m_hSerialPort);
  153. m_hSerialPort = INVALID_HANDLE_VALUE;
  154. DWORD dwError = GetLastError();
  155. return FALSE;
  156. }
  157. return TRUE;
  158. }
  159. void CSynSerial::CloseSerialPort()
  160. {
  161. if (m_hSerialPort != NULL && m_hSerialPort != INVALID_HANDLE_VALUE)
  162. CloseHandle(m_hSerialPort);
  163. m_hSerialPort = INVALID_HANDLE_VALUE;
  164. }
  165. BOOL CSynSerial::SetSerialPort(IN CONST DWORD & dwBaudRate, IN CONST BYTE & byByteSize, IN CONST BYTE & byParity, IN CONST BYTE & byStopBits, IN CONST BYTE & byStartAddr, IN CONST DWORD & dwInQueue, IN CONST DWORD & dwOutQueue)
  166. {
  167. if (!IsOpen())
  168. return FALSE;
  169. BOOL bResult = FALSE;
  170. // GetCommState获取设备控制块状态;
  171. memset(&m_dcb, 0, sizeof(DCB));
  172. bResult = GetCommState(m_hSerialPort, &m_dcb);
  173. if (!bResult)
  174. {
  175. DWORD dwError = GetLastError();
  176. return FALSE;
  177. }
  178. m_dcb.Parity = byParity;
  179. if (m_dcb.Parity == NOPARITY)
  180. m_dcb.fParity = FALSE;
  181. else
  182. m_dcb.fParity = TRUE;
  183. m_dcb.BaudRate = dwBaudRate;
  184. m_dcb.ByteSize = byByteSize;
  185. m_dcb.StopBits = byStopBits;
  186. if (m_dcb.ByteSize == 8)
  187. m_dcb.StopBits = ONESTOPBIT;
  188. // SetCommState设置设备的控制块状态;
  189. memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
  190. bResult = SetCommState(m_hSerialPort, &m_dcb);
  191. if (!bResult)
  192. {
  193. DWORD dwError = GetLastError();
  194. return FALSE;
  195. }
  196. // 获取设备的超时值;
  197. bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
  198. if (!bResult)
  199. {
  200. DWORD dwError = GetLastError();
  201. return FALSE;
  202. }
  203. // 两字符之间最大的延时,设置0表示参数不起作用;
  204. m_cts.ReadIntervalTimeout = 50;
  205. m_cts.ReadTotalTimeoutMultiplier = 100;
  206. m_cts.ReadTotalTimeoutConstant = 8000;
  207. m_cts.WriteTotalTimeoutMultiplier = 100;
  208. m_cts.WriteTotalTimeoutConstant = 3000;
  209. // 设置设备的超时值;
  210. bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
  211. if (!bResult)
  212. {
  213. DWORD dwError = GetLastError();
  214. return FALSE;
  215. }
  216. return TRUE;
  217. }
  218. void CSynSerial::SetSerialDCB(IN CONST DCB & dcb)
  219. {
  220. }
  221. void CSynSerial::SetSerialCommTimeouts(IN CONST COMMTIMEOUTS & commTimeouts)
  222. {
  223. }
  224. DWORD CSynSerial::WriteComm(IN BYTE * pWirteBuf, IN CONST INT32 nWriteSize)
  225. {
  226. if (!IsOpen())
  227. return 0;
  228. if (pWirteBuf == NULL || !::AfxIsValidAddress(pWirteBuf, nWriteSize, FALSE))
  229. {
  230. return 0;
  231. }
  232. DWORD dwErrorFlags;
  233. DWORD dwBytesWritten = 0; // 实际写入的字节数;
  234. // 写前, 清除错误;
  235. COMSTAT ComStat;
  236. ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);
  237. // 写前,清空缓存区;
  238. PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
  239. if ( !WriteFile(m_hSerialPort, pWirteBuf, nWriteSize, &dwBytesWritten, &m_wrOverlapped) )
  240. {
  241. DWORD dwError = GetLastError();
  242. if ( ERROR_IO_PENDING == GetLastError() )
  243. {
  244. while(!GetOverlappedResult(m_hSerialPort, &m_wrOverlapped, &dwBytesWritten, FALSE)){
  245. dwError = GetLastError();
  246. if ( ERROR_IO_PENDING == dwError || dwError == ERROR_IO_INCOMPLETE ) {
  247. continue;
  248. }
  249. else {
  250. ClearCommError(m_hSerialPort, &dwError, NULL);
  251. break;
  252. }
  253. }
  254. }
  255. }
  256. // 返回写入字节数;
  257. return dwBytesWritten;
  258. }
  259. DWORD CSynSerial::ReadComm(IN BYTE *pReadBuf, IN CONST DWORD& dwReadSize, WORD timeout /* = 300 */)
  260. {
  261. if (!IsOpen())
  262. return 0;
  263. if (pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, dwReadSize, FALSE))
  264. {
  265. return 0;
  266. }
  267. DWORD dwError = 0;
  268. DWORD dwRealRead;
  269. if ( !ClearCommError(m_hSerialPort, &dwError, NULL) ) {
  270. PurgeComm(m_hSerialPort, PURGE_TXABORT|PURGE_TXCLEAR);
  271. }
  272. if ( !ReadFile(m_hSerialPort, pReadBuf, dwReadSize, &dwRealRead, &m_wrOverlapped) ) {
  273. if ( GetLastError() == ERROR_IO_PENDING ) {
  274. while(!GetOverlappedResult(m_hSerialPort, &m_wrOverlapped, &dwRealRead, FALSE)){
  275. dwError = GetLastError();
  276. printf("\t 码值=%d, 长度=%d, 内容=%s \n\n", dwError, dwRealRead, pReadBuf);
  277. }
  278. }
  279. }
  280. return dwRealRead;
  281. }