SynSerial.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. #ifdef __CONSOLE__
  32. printf("CreateFile Error=%d\n", dwError);
  33. #endif
  34. return FALSE;
  35. }
  36. BOOL bResult = FALSE;
  37. // SetupComm设置缓冲区大小;
  38. bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
  39. if (!bResult)
  40. {
  41. CloseHandle(m_hSerialPort);
  42. m_hSerialPort = INVALID_HANDLE_VALUE;
  43. DWORD dwError = GetLastError();
  44. #ifdef __CONSOLE__
  45. printf("SetupComm Error=%d\n", dwError);
  46. #endif
  47. return FALSE;
  48. }
  49. // 在串口读写之前,清除缓冲区;
  50. bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
  51. if (!bResult)
  52. {
  53. CloseHandle(m_hSerialPort);
  54. m_hSerialPort = INVALID_HANDLE_VALUE;
  55. DWORD dwError = GetLastError();
  56. #ifdef __CONSOLE__
  57. printf("PurgeComm Error=%d\n", dwError);
  58. #endif
  59. return FALSE;
  60. }
  61. // GetCommState获取设备控制块状态;
  62. memset(&m_dcb, 0, sizeof(DCB));
  63. bResult = GetCommState(m_hSerialPort, &m_dcb);
  64. if (!bResult)
  65. {
  66. CloseHandle(m_hSerialPort);
  67. m_hSerialPort = INVALID_HANDLE_VALUE;
  68. DWORD dwError = GetLastError();
  69. #ifdef __CONSOLE__
  70. printf("GetCommState Error=%d\n", dwError);
  71. #endif
  72. return FALSE;
  73. }
  74. m_dcb.Parity = byParity;
  75. if (m_dcb.Parity == NOPARITY)
  76. m_dcb.fParity = FALSE;
  77. else
  78. m_dcb.fParity = TRUE;
  79. m_dcb.BaudRate = dwBaudRate;
  80. m_dcb.ByteSize = bySize;
  81. m_dcb.StopBits = byStopBits;
  82. if (m_dcb.ByteSize == 8)
  83. m_dcb.StopBits = ONESTOPBIT;
  84. // SetCommState设置设备的控制块状态;
  85. memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
  86. bResult = SetCommState(m_hSerialPort, &m_dcb);
  87. if (!bResult)
  88. {
  89. CloseHandle(m_hSerialPort);
  90. m_hSerialPort = INVALID_HANDLE_VALUE;
  91. DWORD dwError = GetLastError();
  92. #ifdef __CONSOLE__
  93. printf("SetCommState Error=%d\n", dwError);
  94. #endif
  95. return FALSE;
  96. }
  97. // 获取设备的超时值;
  98. bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
  99. if (!bResult)
  100. {
  101. CloseHandle(m_hSerialPort);
  102. m_hSerialPort = INVALID_HANDLE_VALUE;
  103. DWORD dwError = GetLastError();
  104. #ifdef __CONSOLE__
  105. printf("GetCommTimeouts Error=%d\n", dwError);
  106. #endif
  107. return FALSE;
  108. }
  109. // 两字符之间最大的延时,设置0表示参数不起作用;
  110. m_cts.ReadIntervalTimeout = 50;
  111. m_cts.ReadTotalTimeoutMultiplier = 100;
  112. m_cts.ReadTotalTimeoutConstant = 8000;
  113. m_cts.WriteTotalTimeoutMultiplier = 100;
  114. m_cts.WriteTotalTimeoutConstant = 5000;
  115. // 设置设备的超时值;
  116. bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
  117. if (!bResult)
  118. {
  119. CloseHandle(m_hSerialPort);
  120. m_hSerialPort = INVALID_HANDLE_VALUE;
  121. DWORD dwError = GetLastError();
  122. #ifdef __CONSOLE__
  123. printf("SetCommTimeouts Error=%d\n", dwError);
  124. #endif
  125. return FALSE;
  126. }
  127. return TRUE;
  128. }
  129. BOOL CSynSerial::ReOpenSerialPort()
  130. {
  131. ASSERT(_tcslen(m_szSerialPort));
  132. CloseSerialPort();
  133. m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  134. if (m_hSerialPort == INVALID_HANDLE_VALUE)
  135. {
  136. // 打开串口失败;
  137. DWORD dwError = GetLastError();
  138. return FALSE;
  139. }
  140. BOOL bResult = FALSE;
  141. // SetupComm设置缓冲区大小;
  142. bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
  143. if (!bResult)
  144. {
  145. CloseHandle(m_hSerialPort);
  146. m_hSerialPort = INVALID_HANDLE_VALUE;
  147. DWORD dwError = GetLastError();
  148. return FALSE;
  149. }
  150. // 在串口读写之前,清除缓冲区;
  151. bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
  152. if (!bResult)
  153. {
  154. CloseHandle(m_hSerialPort);
  155. m_hSerialPort = INVALID_HANDLE_VALUE;
  156. DWORD dwError = GetLastError();
  157. return FALSE;
  158. }
  159. // SetCommState设置设备的控制块状态;
  160. memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
  161. bResult = SetCommState(m_hSerialPort, &m_dcb);
  162. if (!bResult)
  163. {
  164. CloseHandle(m_hSerialPort);
  165. m_hSerialPort = INVALID_HANDLE_VALUE;
  166. DWORD dwError = GetLastError();
  167. return FALSE;
  168. }
  169. // 设置设备的超时值;
  170. bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
  171. if (!bResult)
  172. {
  173. CloseHandle(m_hSerialPort);
  174. m_hSerialPort = INVALID_HANDLE_VALUE;
  175. DWORD dwError = GetLastError();
  176. return FALSE;
  177. }
  178. return TRUE;
  179. }
  180. void CSynSerial::CloseSerialPort()
  181. {
  182. if (m_hSerialPort != NULL && m_hSerialPort != INVALID_HANDLE_VALUE)
  183. CloseHandle(m_hSerialPort);
  184. m_hSerialPort = INVALID_HANDLE_VALUE;
  185. }
  186. 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)
  187. {
  188. if (!IsOpen())
  189. return FALSE;
  190. BOOL bResult = FALSE;
  191. // GetCommState获取设备控制块状态;
  192. memset(&m_dcb, 0, sizeof(DCB));
  193. bResult = GetCommState(m_hSerialPort, &m_dcb);
  194. if (!bResult)
  195. {
  196. DWORD dwError = GetLastError();
  197. return FALSE;
  198. }
  199. m_dcb.Parity = byParity;
  200. if (m_dcb.Parity == NOPARITY)
  201. m_dcb.fParity = FALSE;
  202. else
  203. m_dcb.fParity = TRUE;
  204. m_dcb.BaudRate = dwBaudRate;
  205. m_dcb.ByteSize = byByteSize;
  206. m_dcb.StopBits = byStopBits;
  207. if (m_dcb.ByteSize == 8)
  208. m_dcb.StopBits = ONESTOPBIT;
  209. // SetCommState设置设备的控制块状态;
  210. memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
  211. bResult = SetCommState(m_hSerialPort, &m_dcb);
  212. if (!bResult)
  213. {
  214. DWORD dwError = GetLastError();
  215. return FALSE;
  216. }
  217. // 获取设备的超时值;
  218. bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
  219. if (!bResult)
  220. {
  221. DWORD dwError = GetLastError();
  222. return FALSE;
  223. }
  224. // 两字符之间最大的延时,设置0表示参数不起作用;
  225. m_cts.ReadIntervalTimeout = 50;
  226. m_cts.ReadTotalTimeoutMultiplier = 100;
  227. m_cts.ReadTotalTimeoutConstant = 8000;
  228. m_cts.WriteTotalTimeoutMultiplier = 100;
  229. m_cts.WriteTotalTimeoutConstant = 3000;
  230. // 设置设备的超时值;
  231. bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
  232. if (!bResult)
  233. {
  234. DWORD dwError = GetLastError();
  235. return FALSE;
  236. }
  237. return TRUE;
  238. }
  239. void CSynSerial::SetSerialDCB(IN CONST DCB & dcb)
  240. {
  241. }
  242. void CSynSerial::SetSerialCommTimeouts(IN CONST COMMTIMEOUTS & commTimeouts)
  243. {
  244. }
  245. DWORD CSynSerial::WriteComm(IN BYTE * pWirteBuf, IN CONST INT32 nWriteSize)
  246. {
  247. if (!IsOpen())
  248. return 0;
  249. if (pWirteBuf == NULL || !::AfxIsValidAddress(pWirteBuf, nWriteSize, FALSE))
  250. {
  251. #ifdef __CONSOLE__
  252. printf("WriteComm Error=AfxIsValidAddress\n");
  253. #endif
  254. return 0;
  255. }
  256. #ifdef __CONSOLE__
  257. printf("WriteFile Len=%d, Buffer=%s\n", nWriteSize, pWirteBuf);
  258. #endif
  259. DWORD dwErrorFlags;
  260. DWORD dwBytesWritten = 0; // 实际写入的字节数;
  261. // 写前, 清除错误;
  262. COMSTAT ComStat;
  263. ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);
  264. // 写前,清空缓存区;
  265. PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
  266. if ( !WriteFile(m_hSerialPort, pWirteBuf, nWriteSize, &dwBytesWritten, &m_wrOverlapped) )
  267. {
  268. DWORD dwError = GetLastError();
  269. if ( ERROR_IO_PENDING == GetLastError() )
  270. {
  271. while(!GetOverlappedResult(m_hSerialPort, &m_wrOverlapped, &dwBytesWritten, FALSE))
  272. {
  273. dwError = GetLastError();
  274. if ( ERROR_IO_PENDING == dwError || dwError == ERROR_IO_INCOMPLETE ) {
  275. continue;
  276. }
  277. else
  278. {
  279. #ifdef __CONSOLE__
  280. printf("GetOverlappedResult Error=%d\n", dwError);
  281. #endif
  282. ClearCommError(m_hSerialPort, &dwError, NULL);
  283. break;
  284. }
  285. }
  286. }
  287. else
  288. {
  289. #ifdef __CONSOLE__
  290. printf("WriteFile Error=%d\n", dwError);
  291. #endif
  292. }
  293. }
  294. // 返回写入字节数;
  295. return dwBytesWritten;
  296. }
  297. DWORD CSynSerial::ReadComm(IN BYTE *pReadBuf, IN CONST DWORD& dwReadSize, WORD timeout /* = 300 */)
  298. {
  299. if (!IsOpen())
  300. return 0;
  301. if (pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, dwReadSize, FALSE))
  302. {
  303. #ifdef __CONSOLE__
  304. printf("ReadComm Error=AfxIsValidAddress\n");
  305. #endif
  306. return 0;
  307. }
  308. DWORD dwError = 0;
  309. DWORD dwRealRead;
  310. if ( !ClearCommError(m_hSerialPort, &dwError, NULL) ) {
  311. PurgeComm(m_hSerialPort, PURGE_TXABORT|PURGE_TXCLEAR);
  312. }
  313. memset(pReadBuf, 0, dwReadSize);
  314. if ( !ReadFile(m_hSerialPort, pReadBuf, dwReadSize, &dwRealRead, &m_wrOverlapped) ) {
  315. if ( GetLastError() == ERROR_IO_PENDING ) {
  316. while(!GetOverlappedResult(m_hSerialPort, &m_wrOverlapped, &dwRealRead, FALSE)){
  317. dwError = GetLastError();
  318. #ifdef __CONSOLE__
  319. if ( dwError != ERROR_IO_INCOMPLETE)
  320. printf("ErroCode=%d, Len=%d, Buffer=%s \n\n", dwError, dwRealRead, pReadBuf);
  321. #endif
  322. }
  323. }
  324. }
  325. #ifdef __CONSOLE__
  326. printf("Error=%ld, ReadFile Len=%d, Buffer=%s\n", dwError, dwRealRead, pReadBuf);
  327. #endif
  328. return dwRealRead;
  329. }