1.设计如图

实现串口的接收发送
使用UI界面设计
目前只能发送字符串,不能发送中文
串口只设置了9600和115200其它的都可以自己的UI界面添加
模拟串口:https://blog.csdn.net/qq_34202873/article/details/88391265
运行结果:
2.代码如下
(1)widget.h
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>/*-------------user-------------------*//*---port--*/#include <QSerialPort>#include <QSerialPortInfo>/*---QString--*/#include <QString>/*---QDateTime--*/#include <QDateTime>/*---QTimer--*/#include <QTimer>/*---QDebug--*/#include <QDebug>#define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"/* -----------------------------------*/namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTsignals:void my_send_signals(bool);public:explicit Widget(QWidget *parent = 0);~Widget();private slots://检测通讯端口槽函数void btn_serial_check(bool);//打开选择端口槽函数void btn_open_port(bool);//关闭选择端口槽函数void btn_close_port(bool);//发送数据槽函数void btn_send_data(bool);//接收数据槽函数void receive_data(void);//清空接收槽函数void btn_clear_rev(bool);//自动发送复选框槽函数void on_checkAutoSend_stateChanged(int arg1);private:Ui::Widget *ui;/*--------funtion---------------------*///用户系统初始化void system_init();//字符串转16进制QByteArray QString2Hex(QString str);//字符转16进制char ConvertHexChar(char ch);/*--------variable--------------------*///串口全局类声明QSerialPort global_port;//自动发送定时器声明QTimer *timer;};#endif // WIDGET_H
(2)widget.cpp
#include "widget.h"#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);/*----------user-----------*///init 用户系统初始化system_init();}Widget::~Widget(){delete ui;}//初始化函数void Widget::system_init(){//port conifgui->boxPortName->clear();//通过QSerialPortInfo查找可用串口foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){//将可用串口添加到端口显示框ui->boxPortName->addItem(info.portName());}//设置串口状态标签为红色 表示未连接状态ui->status->setStyleSheet("color:red");//timer 自动发送timer = new QTimer(this);connect(timer, &QTimer::timeout, [=](){emit my_send_signals(true); //触发发送信号});//connect//check port 检测通讯端口connect(ui->btnSerialCheck, &QPushButton::clicked ,this, &Widget::btn_serial_check);//open port 打开选择端口connect(ui->btnOpen, &QPushButton::clicked, this, &Widget::btn_open_port);//close port 关闭选择端口connect(ui->btnClose, &QPushButton::clicked, this, &Widget::btn_close_port);//send data 发送按钮 触发发送信号connect(ui->btnSend,&QPushButton::clicked,[=](){emit my_send_signals(true);});//发送信号 发送槽函数connect(this, &Widget::my_send_signals, this, &Widget::btn_send_data);//receive data 串口数据接收完触发更新添加显示接收文本框connect(&global_port, &QSerialPort::readyRead, this, &Widget::receive_data);//clear recevie 清除接收文本框的内容connect(ui->btnClear,&QPushButton::clicked, this, &Widget::btn_clear_rev);}QByteArray Widget::QString2Hex(QString str){//初始化byte数字QByteArray senddata;//保存高位和低位int hexdata, lowhexdata;//长度int hexdatalen = 0;//字符串长度 一个字符串需要半个字节int len = str.length();senddata.resize(len/2);char lstr,hstr;for (int i=0; i<len; ) {hstr = str[i].toLatin1();if(hstr == ' '){i++;continue;}i++;if(i >= len)break;//转为ASIIlstr = str[i].toLatin1();hexdata = ConvertHexChar(hstr);lowhexdata = ConvertHexChar(lstr);if((hexdata == 16) || (lowhexdata == 16))break;elsehexdata = hexdata * 16 + lowhexdata;i++;senddata[hexdatalen] = (char)hexdata;hexdatalen++;}senddata.resize(hexdatalen);return senddata;}//字符转化为16进制char Widget::ConvertHexChar(char ch){// ‘0'~'9' -> 0 ~ 9if((ch >= '0') && (ch <= '9'))return ch - 0x30;else if((ch >= 'A') && (ch <= 'F'))return ch - 'A' + 10;else if((ch >= 'a') && (ch <= 'f'))return ch - 'a' + 10;else return (-1);}/*---------------------------------------------------------------------* 槽函数* --------------------------------------------------------------------*///检测通讯端口槽函数void Widget::btn_serial_check(bool){//清空当前的串口boxui->boxPortName->clear();//通过QSerialProtInfo查找可用串口//foreach (var, container)//QSerialPortInfo::availablePorts() 返回的是串口列表foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {ui->boxPortName->addItem(info.portName());}}//打开选择端口槽函数void Widget::btn_open_port(bool){//获取当前的串口号 善水项目可以设置默认的USB端口,直接连接global_port.setPortName(ui->boxPortName->currentText());//获取波特率global_port.setBaudRate(ui->boxBaudRate->currentText().toInt());//设置校验位switch (ui->boxParity->currentIndex()) {case 0: //无校验global_port.setParity(QSerialPort::NoParity);break;case 1: //偶校验global_port.setParity(QSerialPort::EvenParity);break;default: //奇校验global_port.setParity(QSerialPort::OddParity);break;}//设置数据位switch (ui->boxDataBits->currentText().toInt()) {case 8:global_port.setDataBits(QSerialPort::Data8);break;case 7:global_port.setDataBits(QSerialPort::Data7);case 6:global_port.setDataBits(QSerialPort::Data6);default:global_port.setDataBits(QSerialPort::Data5);break;}//设置停止位switch (ui->boxStopBits->currentIndex()) {case 0:global_port.setStopBits(QSerialPort::OneStop);break;case 1:global_port.setStopBits(QSerialPort::OneAndHalfStop);break;default:global_port.setStopBits(QSerialPort::TwoStop);break;}//打开选择端口,并且为可读可写bool ret = global_port.open(QIODevice::ReadWrite);//如果打开成功if (ret) {//设置为打开状态ui->status->setText("Connected");//设置串口标签为绿色ui->status->setStyleSheet("color:green");}}//关闭选择端口槽函数void Widget::btn_close_port(bool){global_port.close();//关闭端口后显示状态ui->status->setText("DisConnected");ui->status->setStyleSheet("color:red");}//发送数据槽函数void Widget::btn_send_data(bool){QString data = ui->textTransmite->toPlainText();QByteArray array;//Hex复选框if(ui->checkSendHex->checkState() == Qt::Checked){array = QString2Hex(data); //HEX 16进制}else{array = data.toLatin1(); //ASCII}global_port.write(array); //发送数据}//接收数据void Widget::receive_data(void){QByteArray array = global_port.readAll();QString str_rev;if (ui->checkReceiveHex->checkState() == Qt::Checked) { //HEX 16进制if (ui->checkLine->checkState() == Qt::Checked) { //自动换行if (ui->checkTime->checkState() == Qt::Checked) { //显示时间//获取当前系统时间QDateTime nowtime = QDateTime::currentDateTime();//时间转换为字符串格式str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";//加上接收数据 转换为16进制并空格分开 接收数据换行//toHex(' ') 是接收内部空格append是两个之间加空格str_rev += QString(array.toHex(' ').toUpper().append(' ')).append("\r\n");} else {str_rev = QString(array.toHex(' ').toUpper().append(' ')).append("\r\n");}} else {str_rev = QString(array.toHex(' ').toUpper().append(' '));}} else {if (ui->checkLine->checkState() == Qt::Checked) {if (ui->checkTime->checkState() == Qt::Checked) {QDateTime nowtime = QDateTime::currentDateTime();str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";str_rev += QString(array).append("\r\n");} else {str_rev = QString(array).append("\r\n");}} else {str_rev = QString(array);}}//写到文本中ui->textReceive->insertPlainText(str_rev);}//清空接收文本框槽函数void Widget::btn_clear_rev(bool){ui->textReceive->clear();}//自动触发复选框 启动定时器和停止定时器void Widget::on_checkAutoSend_stateChanged(int arg1){if(arg1){timer->start(ui->spinTime->value()); //启动定时器}else{timer->stop(); //停止定时器}}
(3)main.c
#include "widget.h"#include <QApplication>int main(int argc, char *argv[]){QApplication a(argc, argv);Widget w;w.show();return a.exec();}
