You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
4.7 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "qt_serial_datachannel.hpp"
  2. //
  3. #include <QtSerialPort/QSerialPort>
  4. #include <QtSerialPort/QSerialPortInfo>
  5. #pragma comment(lib, "ws2_32.lib")
  6. #include "zqui/base/logger.hpp"
  7. using namespace iflytop;
  8. using namespace std;
  9. #define TAG "QTDataChannel"
  10. void QTSerialChannel::init() {
  11. m_thread.reset(new thread([this]() {
  12. while (true) {
  13. if (m_isOpen) {
  14. uint8_t rx[1024] = {0};
  15. int rx_cnt = com_receive(rx, 1024);
  16. if (rx_cnt != 0) {
  17. // ZLOGI(TAG, "rx %d bytes", rx_cnt);
  18. if (m_rxcb) m_rxcb(rx, rx_cnt);
  19. }
  20. this_thread::sleep_for(chrono::microseconds(100));
  21. } else {
  22. this_thread::sleep_for(chrono::microseconds(10000));
  23. }
  24. }
  25. }));
  26. }
  27. bool QTSerialChannel::open() {
  28. char portnamebuf[256] = {0};
  29. sprintf(portnamebuf, "\\\\.\\%s", m_name.c_str());
  30. m_CommHandler = CreateFileA(portnamebuf, // port name
  31. GENERIC_READ | GENERIC_WRITE, // Read/Write
  32. 0, // No Sharing
  33. NULL, // No Security
  34. OPEN_EXISTING, // Open existing port only
  35. 0, // Non Overlapped I/O
  36. NULL); // Null for Comm Devices
  37. if (m_CommHandler == INVALID_HANDLE_VALUE) {
  38. ZLOGI(TAG, "Error in opening serial port");
  39. return false;
  40. }
  41. DCB p;
  42. memset(&p, 0, sizeof(p));
  43. p.DCBlength = sizeof(p);
  44. p.BaudRate = m_baudRate; // 波特率
  45. switch (m_dataBits) {
  46. case QSerialPort::Data5:
  47. p.ByteSize = 5;
  48. break;
  49. case QSerialPort::Data6:
  50. p.ByteSize = 6;
  51. break;
  52. case QSerialPort::Data7:
  53. p.ByteSize = 7;
  54. break;
  55. case QSerialPort::Data8:
  56. p.ByteSize = 8;
  57. break;
  58. default:
  59. p.ByteSize = 8;
  60. break;
  61. }
  62. // QSerialPort::NoParity = 0,
  63. // QSerialPort::EvenParity = 2,
  64. // QSerialPort::OddParity = 3,
  65. // QSerialPort::SpaceParity = 4,
  66. // QSerialPort::MarkParity = 5,
  67. // QSerialPort::UnknownParity = -1
  68. switch (m_parity) // 校验位
  69. {
  70. case QSerialPort::NoParity:
  71. p.Parity = NOPARITY; // 无校验
  72. break;
  73. case QSerialPort::EvenParity:
  74. p.Parity = EVENPARITY; // 奇校验
  75. break;
  76. case QSerialPort::OddParity:
  77. p.Parity = ODDPARITY; // 偶校验
  78. break;
  79. case QSerialPort::MarkParity:
  80. p.Parity = MARKPARITY; // 标记校验
  81. break;
  82. default:
  83. p.Parity = NOPARITY; // 无校验
  84. }
  85. switch (m_stopBits) // 停止位
  86. {
  87. case QSerialPort::OneStop:
  88. p.StopBits = ONESTOPBIT; // 1位停止位
  89. break;
  90. case QSerialPort::OneAndHalfStop:
  91. p.StopBits = TWOSTOPBITS; // 2位停止位
  92. break;
  93. case QSerialPort::TwoStop:
  94. p.StopBits = ONE5STOPBITS; // 1.5位停止位
  95. break;
  96. default:
  97. p.StopBits = ONESTOPBIT; // 无校验
  98. }
  99. if (!SetCommState(m_CommHandler, &p)) {
  100. // 设置参数失败
  101. CloseHandle(m_CommHandler);
  102. return false;
  103. }
  104. m_isOpen = true;
  105. return true;
  106. }
  107. void QTSerialChannel::close() {
  108. CloseHandle(m_CommHandler);
  109. m_isOpen = false;
  110. }
  111. bool QTSerialChannel::isOpen() { return m_isOpen; }
  112. bool QTSerialChannel::send(const uint8_t *data, size_t len) {
  113. DWORD dwBytesWrite = len;
  114. BOOL bWriteStat = WriteFile(m_CommHandler, // 串口句柄
  115. (char *)data, // 数据首地址
  116. dwBytesWrite, // 要发送的数据字节数
  117. &dwBytesWrite, // DWORD*,用来接收返回成功发送的数据字节数
  118. NULL); // NULL为同步发送,OVERLAPPED*为异步发送
  119. return dwBytesWrite == len;
  120. }
  121. void QTSerialChannel::regRxListener(function<void(uint8_t *data, size_t len)> cb) { m_rxcb = cb; }
  122. int QTSerialChannel::com_receive(uint8_t *rxbuf, int rxbufsize) {
  123. COMMTIMEOUTS TimeOuts;
  124. GetCommTimeouts(m_CommHandler, &TimeOuts);
  125. TimeOuts.ReadIntervalTimeout = 0; // 读间隔超时
  126. TimeOuts.ReadTotalTimeoutMultiplier = 0; // 读时间系数
  127. TimeOuts.ReadTotalTimeoutConstant = 1; // 读时间常量
  128. SetCommTimeouts(m_CommHandler, &TimeOuts);
  129. // PurgeComm(m_CommHandler, PURGE_RXCLEAR);
  130. DWORD wCount = rxbufsize; // 成功读取的数据字节数
  131. BOOL bReadStat = ReadFile(m_CommHandler, // 串口句柄
  132. rxbuf, // 数据首地址
  133. wCount, // 要读取的数据最大字节数
  134. &wCount, // DWORD*,用来接收返回成功读取的数据字节数
  135. NULL);
  136. return wCount;
  137. }