Serial.h 5.8 KB

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