Serial.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #pragma once
  2. #pragma warning(disable : 4530)
  3. #pragma warning(disable : 4786)
  4. #pragma warning(disable : 4800)
  5. #pragma warning(disable: 4996)
  6. #include <assert.h>
  7. #include <stdio.h>
  8. #include <windows.h>
  9. //送到窗口的消息 WPARAM 端口号
  10. #define ON_COM_RECEIVE WM_USER + 618
  11. #define ON_COM_CTS WM_USER + 619 //LPARAM 1 valid
  12. #define ON_COM_DSR WM_USER + 621 //LPARAM 1 valid
  13. #define ON_COM_RING WM_USER + 623
  14. #define ON_COM_RLSD WM_USER + 624
  15. #define ON_COM_BREAK WM_USER + 625
  16. #define ON_COM_TXEMPTY WM_USER + 626
  17. #define ON_COM_ERROR WM_USER + 627 //LPARAM save Error ID
  18. #define DEFAULT_COM_MASK_EVENT EV_RXCHAR | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD
  19. class CBaseSerial
  20. {
  21. public:
  22. // 参数为IO方式 阻塞方式(0)/ 异步重叠方式(默认)
  23. CBaseSerial(DWORD dwIOMode = FILE_FLAG_OVERLAPPED) : _dwIOMode(dwIOMode)
  24. {
  25. Init();
  26. }
  27. virtual ~CBaseSerial()
  28. {
  29. Close();
  30. UnInit();
  31. }
  32. public:
  33. // 判断串口是否打开
  34. inline bool IsOpen() { return _hCommHandle != INVALID_HANDLE_VALUE; }
  35. // 判断串口是否打开
  36. operator bool() { return _hCommHandle != INVALID_HANDLE_VALUE; }
  37. // 获得串口句炳
  38. inline HANDLE GetHandle() { return _hCommHandle; }
  39. // 获得串口句炳
  40. operator HANDLE() { return _hCommHandle; }
  41. // 设置IO模式:同步(TRUE)或异步(FALSE);
  42. inline void SetIOMode(BOOL bSync=TRUE){ _dwIOMode = bSync ? 0 : FILE_FLAG_OVERLAPPED; };
  43. // 获得串口参数 DCB
  44. DCB *GetState();
  45. // 设置串口参数 DCB
  46. bool SetState(DCB *pdcb = NULL);
  47. // 设置串口参数:波特率,停止位,等 支持设置字符串 "9600, 8, n, 1"
  48. bool SetState(TCHAR *lpszSetStr = _T("baud=115200 parity=N data=8 stop=1"));
  49. // 设置串口参数:波特率,停止位,等
  50. bool SetState(DWORD dwBaudRate, DWORD dwByteSize = 8, DWORD dwParity = NOPARITY, DWORD dwStopBits = ONESTOPBIT);
  51. // 获得超时结构
  52. LPCOMMTIMEOUTS GetTimeouts(void);
  53. // 设置超时
  54. bool SetTimeouts(
  55. DWORD ReadIntervalTimeout = 5,
  56. DWORD ReadTotalTimeoutMultiplier = 10,
  57. DWORD ReadTotalTimeoutConstant = 1500,
  58. DWORD WriteTotalTimeoutMultiplier = 10,
  59. DWORD WriteTotalTimeoutConstant = 1500);
  60. bool SetTimeouts(LPCOMMTIMEOUTS lpCO);
  61. // 设置串口的I/O缓冲区大小
  62. bool SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize);
  63. // 关联消息的窗口句柄
  64. inline void SetWnd(HWND hWnd)
  65. {
  66. assert(::IsWindow(hWnd));
  67. _hNotifyWnd = hWnd;
  68. }
  69. // 设定发送通知, 接受字符最小值
  70. inline void SetNotifyNum(DWORD dwNum) { _dwNotifyNum = dwNum; }
  71. // 设置要监视的事件, 打开前设置有效
  72. void SetMaskEvent(DWORD dwEvent = DEFAULT_COM_MASK_EVENT);
  73. // 获得读缓冲区的字符数
  74. int GetInputSize();
  75. // 打开串口 缺省 9600, 8, n, 1
  76. bool Open(DWORD dwPort);
  77. // 打开串口 缺省 baud_rate, 8, n, 1
  78. bool Open(DWORD dwPort, DWORD dwBaudRate);
  79. // 打开串口, 使用类似"9600, 8, n, 1"的设置字符串设置串口
  80. bool Open(DWORD dwPort, TCHAR *lpszSetStr = _T("baud=115200 parity=N data=8 stop=1") );
  81. // 读取串口 dwBufferLength个字符到 Buffer 返回实际读到的字符数 可读任意数据
  82. DWORD Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 100);
  83. // 读取串口 dwBufferLength - 1 个字符到 szBuffer 返回ANSI C 模式字符串指针 适合一般字符通讯
  84. char *ReadString(char *szBuffer, DWORD dwBufferLength, DWORD dwWaitTime = 20);
  85. // 写串口 可写任意数据 "abcd" or "\x0\x1\x2"
  86. DWORD Write(LPVOID Buffer, DWORD dwBufferLength);
  87. // 写串口 写ANSI C 模式字符串指针
  88. DWORD Write(const TCHAR *szBuffer);
  89. // 读串口 同步应用
  90. DWORD ReadSync(LPVOID Buffer, DWORD dwBufferLength);
  91. // 写串口 同步应用
  92. DWORD WriteSync(LPVOID Buffer, DWORD dwBufferLength);
  93. // 写串口 szBuffer 可以输出格式字符串 包含缓冲区长度
  94. DWORD Write(TCHAR *szBuffer, DWORD dwBufferLength, TCHAR *szFormat, ...);
  95. // 写串口 szBuffer 可以输出格式字符串 不检查缓冲区长度 小心溢出
  96. DWORD Write(TCHAR *szBuffer, TCHAR *szFormat, ...);
  97. // 关闭串口 同时也关闭关联线程
  98. virtual void Close();
  99. // DTR 电平控制
  100. bool SetDTR(bool OnOrOff);
  101. // RTS 电平控制
  102. bool SetRTS(bool OnOrOff);
  103. // 设置信号状态为中断;
  104. bool SetBreak(bool OnOrOff);
  105. // 清除缓存;
  106. void ClearCommBuffer() {
  107. ClearCommError(_hCommHandle, NULL, NULL);
  108. ::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
  109. }
  110. protected:
  111. volatile DWORD _dwPort; // 串口号
  112. volatile HANDLE _hCommHandle; // 串口句柄
  113. TCHAR _szCommStr[20]; // 保存COM1类似的字符串
  114. DCB _DCB; // 波特率,停止位,等
  115. COMMTIMEOUTS _CO; // 超时结构
  116. DWORD _dwIOMode; // 0 同步 默认 FILE_FLAG_OVERLAPPED重叠I/O异步
  117. OVERLAPPED _ReadOverlapped, _WriteOverlapped; // 重叠I/O
  118. volatile HWND _hNotifyWnd; // 通知窗口
  119. volatile DWORD _dwNotifyNum; // 接受多少字节(>=_dwNotifyNum)发送通知消息
  120. volatile DWORD _dwMaskEvent; // 监视的事件
  121. OVERLAPPED _WaitOverlapped; // WaitCommEvent use
  122. // 初始化
  123. void Init();
  124. // 析构
  125. void UnInit();
  126. // 绑定串口
  127. void BindCommPort(DWORD dwPort);
  128. // 打开串口
  129. virtual bool OpenCommPort();
  130. // 设置串口
  131. virtual bool SetupPort();
  132. private:
  133. CBaseSerial(const CBaseSerial &);
  134. CBaseSerial &operator=(const CBaseSerial &);
  135. };