Serial.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. // 获得串口参数 DCB
  42. DCB *GetState();
  43. // 设置串口参数 DCB
  44. bool SetState(DCB *pdcb = NULL);
  45. // 设置串口参数:波特率,停止位,等 支持设置字符串 "9600, 8, n, 1"
  46. bool SetState(TCHAR *lpszSetStr = _T("baud=115200 parity=N data=8 stop=1"));
  47. // 设置串口参数:波特率,停止位,等
  48. bool SetState(DWORD dwBaudRate, DWORD dwByteSize = 8, DWORD dwParity = NOPARITY, DWORD dwStopBits = ONESTOPBIT);
  49. // 获得超时结构
  50. LPCOMMTIMEOUTS GetTimeouts(void);
  51. // 设置超时
  52. bool SetTimeouts(
  53. DWORD ReadIntervalTimeout = 5,
  54. DWORD ReadTotalTimeoutMultiplier = 10,
  55. DWORD ReadTotalTimeoutConstant = 1500,
  56. DWORD WriteTotalTimeoutMultiplier = 10,
  57. DWORD WriteTotalTimeoutConstant = 1500);
  58. bool SetTimeouts(LPCOMMTIMEOUTS lpCO);
  59. // 设置串口的I/O缓冲区大小
  60. bool SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize);
  61. // 关联消息的窗口句柄
  62. inline void SetWnd(HWND hWnd)
  63. {
  64. assert(::IsWindow(hWnd));
  65. _hNotifyWnd = hWnd;
  66. }
  67. // 设定发送通知, 接受字符最小值
  68. inline void SetNotifyNum(DWORD dwNum) { _dwNotifyNum = dwNum; }
  69. // 设置要监视的事件, 打开前设置有效
  70. void SetMaskEvent(DWORD dwEvent = DEFAULT_COM_MASK_EVENT);
  71. // 获得读缓冲区的字符数
  72. int GetInputSize();
  73. // 打开串口 缺省 9600, 8, n, 1
  74. bool Open(DWORD dwPort);
  75. // 打开串口 缺省 baud_rate, 8, n, 1
  76. bool Open(DWORD dwPort, DWORD dwBaudRate);
  77. // 打开串口, 使用类似"9600, 8, n, 1"的设置字符串设置串口
  78. bool Open(DWORD dwPort, TCHAR *lpszSetStr = _T("baud=115200 parity=N data=8 stop=1") );
  79. // 读取串口 dwBufferLength个字符到 Buffer 返回实际读到的字符数 可读任意数据
  80. DWORD Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 100);
  81. // 读取串口 dwBufferLength - 1 个字符到 szBuffer 返回ANSI C 模式字符串指针 适合一般字符通讯
  82. char *ReadString(char *szBuffer, DWORD dwBufferLength, DWORD dwWaitTime = 20);
  83. // 写串口 可写任意数据 "abcd" or "\x0\x1\x2"
  84. DWORD Write(LPVOID Buffer, DWORD dwBufferLength);
  85. // 写串口 写ANSI C 模式字符串指针
  86. DWORD Write(const TCHAR *szBuffer);
  87. // 读串口 同步应用
  88. DWORD ReadSync(LPVOID Buffer, DWORD dwBufferLength);
  89. // 写串口 同步应用
  90. DWORD WriteSync(LPVOID Buffer, DWORD dwBufferLength);
  91. // 写串口 szBuffer 可以输出格式字符串 包含缓冲区长度
  92. DWORD Write(TCHAR *szBuffer, DWORD dwBufferLength, TCHAR *szFormat, ...);
  93. // 写串口 szBuffer 可以输出格式字符串 不检查缓冲区长度 小心溢出
  94. DWORD Write(TCHAR *szBuffer, TCHAR *szFormat, ...);
  95. // 关闭串口 同时也关闭关联线程
  96. virtual void Close();
  97. // DTR 电平控制
  98. bool SetDTR(bool OnOrOff);
  99. // RTS 电平控制
  100. bool SetRTS(bool OnOrOff);
  101. // 设置信号状态为中断;
  102. bool SetBreak(bool OnOrOff);
  103. // 清除缓存;
  104. void ClearCommBuffer() {
  105. ClearCommError(_hCommHandle, NULL, NULL);
  106. ::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
  107. }
  108. protected:
  109. volatile DWORD _dwPort; // 串口号
  110. volatile HANDLE _hCommHandle; // 串口句柄
  111. TCHAR _szCommStr[20]; // 保存COM1类似的字符串
  112. DCB _DCB; // 波特率,停止位,等
  113. COMMTIMEOUTS _CO; // 超时结构
  114. DWORD _dwIOMode; // 0 同步 默认 FILE_FLAG_OVERLAPPED重叠I/O异步
  115. OVERLAPPED _ReadOverlapped, _WriteOverlapped; // 重叠I/O
  116. volatile HWND _hNotifyWnd; // 通知窗口
  117. volatile DWORD _dwNotifyNum; // 接受多少字节(>=_dwNotifyNum)发送通知消息
  118. volatile DWORD _dwMaskEvent; // 监视的事件
  119. OVERLAPPED _WaitOverlapped; // WaitCommEvent use
  120. // 初始化
  121. void Init();
  122. // 析构
  123. void UnInit();
  124. // 绑定串口
  125. void BindCommPort(DWORD dwPort);
  126. // 打开串口
  127. virtual bool OpenCommPort();
  128. // 设置串口
  129. virtual bool SetupPort();
  130. private:
  131. CBaseSerial(const CBaseSerial &);
  132. CBaseSerial &operator=(const CBaseSerial &);
  133. };