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.
 
 
 

201 lines
5.6 KiB

  1. /*******************************
  2. * Copyright (C) 2025-.
  3. *
  4. * File Name: serialcommunicator.h
  5. * Description: 串口通信管理类,封装串口操作、数据收发和超时处理
  6. * Others:
  7. * Version: 1.0
  8. * Author: lipengpeng
  9. * Date: 2025-7-23
  10. *******************************/
  11. #ifndef SERIALCOMMUNICATOR_H
  12. #define SERIALCOMMUNICATOR_H
  13. #include <QObject>
  14. #include <QSerialPort>
  15. #include <QTimer>
  16. #include <QByteArray>
  17. /**
  18. * @brief 串口通信管理类
  19. * @class SerialCommunicator
  20. *
  21. * @details 此类封装了串口通信的核心功能,包括:
  22. * 1. 串口参数配置与开关控制
  23. * 2. 数据发送与自动重发机制
  24. * 3. 数据接收与完整性判断
  25. * 4. 超时处理与状态通知
  26. *
  27. * @note 使用流程:
  28. * 1. 设置串口参数(setPortParams)
  29. * 2. 打开串口(open)
  30. * 3. 发送数据(sendData)
  31. * 4. 接收数据(通过dataReceived信号)
  32. * 5. 关闭串口(close)
  33. */
  34. class SerialCommunicator : public QObject
  35. {
  36. Q_OBJECT
  37. public:
  38. /**
  39. * @brief 构造函数
  40. * @param parent 父对象指针
  41. */
  42. SerialCommunicator(QObject *parent = nullptr);
  43. /**
  44. * @brief 析构函数
  45. * @note 自动关闭串口并释放资源
  46. */
  47. ~SerialCommunicator();
  48. // ====================== 串口配置 ====================== //
  49. /**
  50. * @brief 设置串口参数
  51. * @param portName 串口号(如"COM1"或"/dev/ttyS0")
  52. * @param baudRate 波特率(如9600, 115200)
  53. * @param dataBits 数据位(通常为QSerialPort::Data8)
  54. * @param parity 校验位(无校验/奇校验/偶校验)
  55. * @param stopBits 停止位(通常为QSerialPort::OneStop)
  56. * @note 此方法应在打开串口前调用
  57. */
  58. void setPortParams(QString portName_, qint32 baudRate_,
  59. QSerialPort::DataBits dataBits_,
  60. QSerialPort::Parity parity_,
  61. QSerialPort::StopBits stopBits_);
  62. /**
  63. * @brief 打开串口
  64. * @return true-打开成功, false-打开失败
  65. * @note 成功打开后会发出statusChanged信号
  66. */
  67. bool open();
  68. /**
  69. * @brief 关闭串口
  70. * @note 关闭后会发出statusChanged信号
  71. */
  72. void close();
  73. // ====================== 数据操作 ====================== //
  74. /**
  75. * @brief 发送数据并启动超时重发机制
  76. * @param data 待发送的数据
  77. * @note 数据发送后启动重发定时器,如达到最大重发次数仍未收到响应,
  78. * 将发出timeoutOccurred信号
  79. */
  80. void sendData(const QByteArray &data);
  81. // ====================== 超时配置 ====================== //
  82. /**
  83. * @brief 设置最大重发次数
  84. * @param count 重发次数(默认3次)
  85. */
  86. void setMaxRetry(int count);
  87. /**
  88. * @brief 设置接收完成超时时间
  89. * @param ms 超时时间(毫秒,默认50ms)
  90. * @note 当串口持续ms毫秒无新数据时,认为接收完成
  91. */
  92. void setRecvTimeout(int ms);
  93. /**
  94. * @brief 设置重发间隔时间
  95. * @param ms 重发间隔(毫秒,默认1000ms)
  96. */
  97. void setResendTimeout(int ms);
  98. // ====================== 状态查询 ====================== //
  99. /**
  100. * @brief 检查串口是否打开
  101. * @return true-已打开, false-已关闭
  102. */
  103. bool isOpen() const;
  104. void setCheckMsg(QByteArray msg);
  105. signals:
  106. /**
  107. * @brief 接收到完整数据信号
  108. * @param data 接收到的完整数据包
  109. */
  110. void dataReceived(const QByteArray &data);
  111. /**
  112. * @brief 状态变化信号
  113. * @param status 状态描述文本
  114. * @note 可能的状态: "已连接", "已断开", "接收超时"等
  115. */
  116. void statusChanged(const QString &status);
  117. /**
  118. * @brief 通信超时信号
  119. * @note 当达到最大重发次数仍未收到响应时触发
  120. */
  121. void timeoutOccurred();
  122. /**
  123. * @brief 串口错误信号
  124. * @note 当串口发生异常错误时触发
  125. */
  126. void physicalDisconnected();
  127. void stationConnect(bool online);
  128. private slots:
  129. /**
  130. * @brief 串口数据到达处理
  131. * @note 当串口有数据可读时触发,数据存入缓冲区并启动接收超时定时器
  132. */
  133. void onReadyRead();
  134. /**
  135. * @brief 接收完成超时处理
  136. * @note 当recvTimer超时,认为数据接收完成,发出dataReceived信号
  137. */
  138. void onRecvTimeout();
  139. /**
  140. * @brief 重发超时处理
  141. * @note 当resendTimer超时,检查重发次数并决定是否重发数据
  142. */
  143. void onResendTimeout();
  144. /**
  145. * @brief 处理串口错误
  146. * @param error 串口错误代码
  147. */
  148. void handleSerialError(QSerialPort::SerialPortError error);
  149. void stationCheck();
  150. void checkTimeOut();
  151. private:
  152. QSerialPort *serialPort_; // 串口对象
  153. QTimer *recvTimer_; // 接收完成判断定时器
  154. QTimer *resendTimer_; // 超时重发定时器
  155. QTimer *stationCheck_; // 检测是否连接到从站
  156. QTimer *checkTimeOut_;
  157. QByteArray recvBuffer_; // 接收缓冲区
  158. QByteArray currentData_; // 当前待重发数据
  159. int comCount_; // 重发计数器
  160. int maxRetry_; // 最大重发次数
  161. int recvTimeout_; // 接收超时时间(ms)
  162. int resendTimeout_; // 重发间隔(ms)
  163. QByteArray test_;
  164. // 串口参数
  165. QString portName_;
  166. qint32 baudRate_;
  167. QSerialPort::DataBits dataBits_;
  168. QSerialPort::Parity parity_;
  169. QSerialPort::StopBits stopBits_;
  170. };
  171. #endif // SERIALCOMMUNICATOR_H