1.设计如图

image.png
实现串口的接收发送
使用UI界面设计
目前只能发送字符串,不能发送中文

串口只设置了9600和115200其它的都可以自己的UI界面添加

模拟串口:https://blog.csdn.net/qq_34202873/article/details/88391265
运行结果:
image.png

2.代码如下

应该设置为serial 忘记改了

(1)widget.h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. /*-------------user-------------------*/
  5. /*---port--*/
  6. #include <QSerialPort>
  7. #include <QSerialPortInfo>
  8. /*---QString--*/
  9. #include <QString>
  10. /*---QDateTime--*/
  11. #include <QDateTime>
  12. /*---QTimer--*/
  13. #include <QTimer>
  14. /*---QDebug--*/
  15. #include <QDebug>
  16. #define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"
  17. /* -----------------------------------*/
  18. namespace Ui {
  19. class Widget;
  20. }
  21. class Widget : public QWidget
  22. {
  23. Q_OBJECT
  24. signals:
  25. void my_send_signals(bool);
  26. public:
  27. explicit Widget(QWidget *parent = 0);
  28. ~Widget();
  29. private slots:
  30. //检测通讯端口槽函数
  31. void btn_serial_check(bool);
  32. //打开选择端口槽函数
  33. void btn_open_port(bool);
  34. //关闭选择端口槽函数
  35. void btn_close_port(bool);
  36. //发送数据槽函数
  37. void btn_send_data(bool);
  38. //接收数据槽函数
  39. void receive_data(void);
  40. //清空接收槽函数
  41. void btn_clear_rev(bool);
  42. //自动发送复选框槽函数
  43. void on_checkAutoSend_stateChanged(int arg1);
  44. private:
  45. Ui::Widget *ui;
  46. /*--------funtion---------------------*/
  47. //用户系统初始化
  48. void system_init();
  49. //字符串转16进制
  50. QByteArray QString2Hex(QString str);
  51. //字符转16进制
  52. char ConvertHexChar(char ch);
  53. /*--------variable--------------------*/
  54. //串口全局类声明
  55. QSerialPort global_port;
  56. //自动发送定时器声明
  57. QTimer *timer;
  58. };
  59. #endif // WIDGET_H

(2)widget.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. Widget::Widget(QWidget *parent) :
  4. QWidget(parent),
  5. ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. /*----------user-----------*/
  9. //init 用户系统初始化
  10. system_init();
  11. }
  12. Widget::~Widget()
  13. {
  14. delete ui;
  15. }
  16. //初始化函数
  17. void Widget::system_init()
  18. {
  19. //port conifg
  20. ui->boxPortName->clear();
  21. //通过QSerialPortInfo查找可用串口
  22. foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  23. {
  24. //将可用串口添加到端口显示框
  25. ui->boxPortName->addItem(info.portName());
  26. }
  27. //设置串口状态标签为红色 表示未连接状态
  28. ui->status->setStyleSheet("color:red");
  29. //timer 自动发送
  30. timer = new QTimer(this);
  31. connect(timer, &QTimer::timeout, [=](){
  32. emit my_send_signals(true); //触发发送信号
  33. });
  34. //connect
  35. //check port 检测通讯端口
  36. connect(ui->btnSerialCheck, &QPushButton::clicked ,this, &Widget::btn_serial_check);
  37. //open port 打开选择端口
  38. connect(ui->btnOpen, &QPushButton::clicked, this, &Widget::btn_open_port);
  39. //close port 关闭选择端口
  40. connect(ui->btnClose, &QPushButton::clicked, this, &Widget::btn_close_port);
  41. //send data 发送按钮 触发发送信号
  42. connect(ui->btnSend,&QPushButton::clicked,[=](){
  43. emit my_send_signals(true);
  44. });
  45. //发送信号 发送槽函数
  46. connect(this, &Widget::my_send_signals, this, &Widget::btn_send_data);
  47. //receive data 串口数据接收完触发更新添加显示接收文本框
  48. connect(&global_port, &QSerialPort::readyRead, this, &Widget::receive_data);
  49. //clear recevie 清除接收文本框的内容
  50. connect(ui->btnClear,&QPushButton::clicked, this, &Widget::btn_clear_rev);
  51. }
  52. QByteArray Widget::QString2Hex(QString str)
  53. {
  54. //初始化byte数字
  55. QByteArray senddata;
  56. //保存高位和低位
  57. int hexdata, lowhexdata;
  58. //长度
  59. int hexdatalen = 0;
  60. //字符串长度 一个字符串需要半个字节
  61. int len = str.length();
  62. senddata.resize(len/2);
  63. char lstr,hstr;
  64. for (int i=0; i<len; ) {
  65. hstr = str[i].toLatin1();
  66. if(hstr == ' ')
  67. {
  68. i++;
  69. continue;
  70. }
  71. i++;
  72. if(i >= len)
  73. break;
  74. //转为ASII
  75. lstr = str[i].toLatin1();
  76. hexdata = ConvertHexChar(hstr);
  77. lowhexdata = ConvertHexChar(lstr);
  78. if((hexdata == 16) || (lowhexdata == 16))
  79. break;
  80. else
  81. hexdata = hexdata * 16 + lowhexdata;
  82. i++;
  83. senddata[hexdatalen] = (char)hexdata;
  84. hexdatalen++;
  85. }
  86. senddata.resize(hexdatalen);
  87. return senddata;
  88. }
  89. //字符转化为16进制
  90. char Widget::ConvertHexChar(char ch)
  91. {
  92. // ‘0'~'9' -> 0 ~ 9
  93. if((ch >= '0') && (ch <= '9'))
  94. return ch - 0x30;
  95. else if((ch >= 'A') && (ch <= 'F'))
  96. return ch - 'A' + 10;
  97. else if((ch >= 'a') && (ch <= 'f'))
  98. return ch - 'a' + 10;
  99. else return (-1);
  100. }
  101. /*---------------------------------------------------------------------
  102. * 槽函数
  103. * --------------------------------------------------------------------*/
  104. //检测通讯端口槽函数
  105. void Widget::btn_serial_check(bool)
  106. {
  107. //清空当前的串口box
  108. ui->boxPortName->clear();
  109. //通过QSerialProtInfo查找可用串口
  110. //foreach (var, container)
  111. //QSerialPortInfo::availablePorts() 返回的是串口列表
  112. foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
  113. ui->boxPortName->addItem(info.portName());
  114. }
  115. }
  116. //打开选择端口槽函数
  117. void Widget::btn_open_port(bool)
  118. {
  119. //获取当前的串口号 善水项目可以设置默认的USB端口,直接连接
  120. global_port.setPortName(ui->boxPortName->currentText());
  121. //获取波特率
  122. global_port.setBaudRate(ui->boxBaudRate->currentText().toInt());
  123. //设置校验位
  124. switch (ui->boxParity->currentIndex()) {
  125. case 0: //无校验
  126. global_port.setParity(QSerialPort::NoParity);
  127. break;
  128. case 1: //偶校验
  129. global_port.setParity(QSerialPort::EvenParity);
  130. break;
  131. default: //奇校验
  132. global_port.setParity(QSerialPort::OddParity);
  133. break;
  134. }
  135. //设置数据位
  136. switch (ui->boxDataBits->currentText().toInt()) {
  137. case 8:
  138. global_port.setDataBits(QSerialPort::Data8);
  139. break;
  140. case 7:
  141. global_port.setDataBits(QSerialPort::Data7);
  142. case 6:
  143. global_port.setDataBits(QSerialPort::Data6);
  144. default:
  145. global_port.setDataBits(QSerialPort::Data5);
  146. break;
  147. }
  148. //设置停止位
  149. switch (ui->boxStopBits->currentIndex()) {
  150. case 0:
  151. global_port.setStopBits(QSerialPort::OneStop);
  152. break;
  153. case 1:
  154. global_port.setStopBits(QSerialPort::OneAndHalfStop);
  155. break;
  156. default:
  157. global_port.setStopBits(QSerialPort::TwoStop);
  158. break;
  159. }
  160. //打开选择端口,并且为可读可写
  161. bool ret = global_port.open(QIODevice::ReadWrite);
  162. //如果打开成功
  163. if (ret) {
  164. //设置为打开状态
  165. ui->status->setText("Connected");
  166. //设置串口标签为绿色
  167. ui->status->setStyleSheet("color:green");
  168. }
  169. }
  170. //关闭选择端口槽函数
  171. void Widget::btn_close_port(bool)
  172. {
  173. global_port.close();
  174. //关闭端口后显示状态
  175. ui->status->setText("DisConnected");
  176. ui->status->setStyleSheet("color:red");
  177. }
  178. //发送数据槽函数
  179. void Widget::btn_send_data(bool)
  180. {
  181. QString data = ui->textTransmite->toPlainText();
  182. QByteArray array;
  183. //Hex复选框
  184. if(ui->checkSendHex->checkState() == Qt::Checked){
  185. array = QString2Hex(data); //HEX 16进制
  186. }else{
  187. array = data.toLatin1(); //ASCII
  188. }
  189. global_port.write(array); //发送数据
  190. }
  191. //接收数据
  192. void Widget::receive_data(void)
  193. {
  194. QByteArray array = global_port.readAll();
  195. QString str_rev;
  196. if (ui->checkReceiveHex->checkState() == Qt::Checked) { //HEX 16进制
  197. if (ui->checkLine->checkState() == Qt::Checked) { //自动换行
  198. if (ui->checkTime->checkState() == Qt::Checked) { //显示时间
  199. //获取当前系统时间
  200. QDateTime nowtime = QDateTime::currentDateTime();
  201. //时间转换为字符串格式
  202. str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
  203. //加上接收数据 转换为16进制并空格分开 接收数据换行
  204. //toHex(' ') 是接收内部空格append是两个之间加空格
  205. str_rev += QString(array.toHex(' ').toUpper().append(' ')).append("\r\n");
  206. } else {
  207. str_rev = QString(array.toHex(' ').toUpper().append(' ')).append("\r\n");
  208. }
  209. } else {
  210. str_rev = QString(array.toHex(' ').toUpper().append(' '));
  211. }
  212. } else {
  213. if (ui->checkLine->checkState() == Qt::Checked) {
  214. if (ui->checkTime->checkState() == Qt::Checked) {
  215. QDateTime nowtime = QDateTime::currentDateTime();
  216. str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
  217. str_rev += QString(array).append("\r\n");
  218. } else {
  219. str_rev = QString(array).append("\r\n");
  220. }
  221. } else {
  222. str_rev = QString(array);
  223. }
  224. }
  225. //写到文本中
  226. ui->textReceive->insertPlainText(str_rev);
  227. }
  228. //清空接收文本框槽函数
  229. void Widget::btn_clear_rev(bool)
  230. {
  231. ui->textReceive->clear();
  232. }
  233. //自动触发复选框 启动定时器和停止定时器
  234. void Widget::on_checkAutoSend_stateChanged(int arg1)
  235. {
  236. if(arg1){
  237. timer->start(ui->spinTime->value()); //启动定时器
  238. }else{
  239. timer->stop(); //停止定时器
  240. }
  241. }

(3)main.c

  1. #include "widget.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. Widget w;
  7. w.show();
  8. return a.exec();
  9. }

源码:
serialPoart2.rar