SynSerial.cpp 8.8 KB

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