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_OBJECT
signals:
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 conifg
ui->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;
//转为ASII
lstr = str[i].toLatin1();
hexdata = ConvertHexChar(hstr);
lowhexdata = ConvertHexChar(lstr);
if((hexdata == 16) || (lowhexdata == 16))
break;
else
hexdata = hexdata * 16 + lowhexdata;
i++;
senddata[hexdatalen] = (char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
return senddata;
}
//字符转化为16进制
char Widget::ConvertHexChar(char ch)
{
// ‘0'~'9' -> 0 ~ 9
if((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)
{
//清空当前的串口box
ui->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();
}