SynSerial.cpp 7.8 KB

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