开始QT编程后,由于自己本身基础较差,需要经常查询一些简单无聊的问题,有些时候好多知识点只有个印象,记不太清楚导致下不去手写代码,都需要上网搜一搜,现在记录一下自己思路或者一些常用的知识点,这样以后自己忘记了可以很快查找翻阅一下,可以当个备忘录。同时如果这些东西对其他人有帮助的话,也是特别好的,也会让自己有成就感,给自己更多的前进动力。
由于工作需要接触串口通信。在网上查了很多资料,现在做个总结。
关于串口的通信
1、串口通信需要的主要参数:波特率、校验位、数据位、停止位、控制流
2、这里,将通信参数写死,并通过定时器,实现串口自动连接,判断串口断开,发送和接收串口的信息 【后续可能会考虑使用线程来完成串口自动连接,断开判断等操作】
查看了很多CSDN上的很多关于QT串口通信的文章:文章1,文章2,文章3等
文章来源地址https://uudwc.com/A/z38Da
备注:
2023/03/20 14:40懒得在修改这个文章了,后续遇到的问题都会写我的笔记进里
第一步、添加相关头文件,模块
在.pro的文件里添加模块 QT += serialport
在.cpp里添加串口通信头文件
#include <QSerialPort>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
第二步、在头文件中定义全局的对象
private:
QSerialPort* serial;//全局的串口对象
QTimer* timer;//全局的定时器对象
第三步、参数设置,在头文件中定义初始化参数的函数和参数变量名,在.cpp文件中实现函数
main()
{
timer = new QTimer;
timer->start(1000);
timer->setSingleShot(false);//设置周期触发的定时器
connect(timer,SIGNAL(timeout()),this,SLOT(setinit()));//周期性触发初始化的操作
}
void MainWindow::setinit()//设置串口初始化
{
QSerialPortInfo com_info;
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) //循环遍历获得可用的串口号
{
if(info.serialNumber() == "")
{
com_info = info;
break;
}
}
serial->setPort(com_info);//将获得到得串口号设置为需要打开的串口号
if(serial->open(QIODevice::ReadWrite))
{
timer->stop();//如果串口打开了,就停止定时器
serial->setBaudRate(QSerialPort::Baud115200);//设置波特率:115200
qDebug()<< "波特率设置:" << serial->setBaudRate(QSerialPort::Baud115200);
serial->setParity(QSerialPort::NoParity);//设置校验位:no
qDebug()<< "校验位设置:" << serial->setParity(QSerialPort::NoParity);
serial->setDataBits(QSerialPort::Data8);//设置数据位:8位
qDebug()<< "数据位设置:" << serial->setDataBits(QSerialPort::Data8);
serial->setStopBits(QSerialPort::OneStop);//设置停止位:1位
qDebug()<< "停止位设置:" << serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);//设置无流控制
qDebug()<< "流控制设置:" << serial->setFlowControl(QSerialPort::NoFlowControl);
connect(serial,SIGNAL(readyRead()),this,SLOT(receiveMessage()),Qt::UniqueConnection);//串口连接槽函数
// Qt::UniqueConnection 虽然我不知道为什么这样管用,但它却是修复了串口断开会重复弹窗的问题
connect(serial,SIGNAL(error(QSerialPort::SerialPortError)),
this,SLOT(showValidPort(QSerialPort::SerialPortError)),Qt::UniqueConnection);//判断串口连接状态
//同上,不知道为什么,确实修复了重复提示弹窗问题
}
else
{
qDebug() << "串口没有打开";
}
}
第四步、判断串口连接的状态
private slots:
void showValidPort(QSerialPort::SerialPortError error);//检测串口的连接状态
void MainWindow::showValidPort(QSerialPort::SerialPortError error)//检测串口的连接状态
{
if(error == QSerialPort::ResourceError || error == QSerialPort::PermissionError)
{
QMessageBox::critical(this, "警告","串口连接中断!请检查串口是否正确连接!");
// serial->clear();
serial->close();
timer->start(500);
}
}
第五步、串口信息的发送和信息的接收(计划是可以实现中文,16进制发送和接收)//这里暂时只实现了16进制的数据发送和接收
private slots:
void receiveMessage();//接收串口通信设备发送的信息
void btn1_send();//按钮1发送数据
void MainWindow::receiveMessage()//接收从串口通信设备中接收到得信息
{
QString buffer_1;//从缓冲区中读取数据
QByteArray buffer = serial->readAll();
if(!buffer.isEmpty())//如果非空说明有数据接收
{
QString str=buffer.toHex().data();//转换成16进制大写
str=str.toUpper();
for(int i=0;i<str.length();i+=2)//一个16进制占4位,8位为一字节,所以每两位16进制空一格
{
QString str_1 = str.mid (i,2);
buffer_1 += str_1;
buffer_1 += " ";
}
}
qDebug() <<"接收到的信息是:"<< buffer_1;
buffer.clear();
}
void MainWindow::btn1_send()//点击按钮1发送数据
{
QByteArray Data_1;
QString Data = "A1";
Data_1 = QByteArray::fromHex (Data.toLatin1().data());//这里使用16进制发送数据
serial->write(Data_1);
qDebug() <<"发送的信息是:"<< Data;
}
第六步、实现自动刷新当前时间
private:
QTimer* timer2;//全局的定时器对象
private slots:
void timeread();//获取当前时间
main()
{
timer2 = new QTimer;
timer2->start(1000);
timer2->setSingleShot(false);//设置周期触发的定时器
connect(timer2,SIGNAL(timeout()),this,SLOT(timeread()));//周期性触发读取当前时间的操作
}
void MainWindow::timeread()//获取当前时间
{
QDateTime tim = QDateTime::currentDateTime();
QString datetime = tim.toString("yyyy - MM - dd hh:mm:ss");
ui->timelabel->setText(datetime);
}
后续遇到的问题:
参考他人的无边框窗口完成了自己的无边框窗口,但仍存在改进空间
自定义无边框窗口+标题栏
遇到了Qdebug和Qlabel显示中文文字乱码的问题(已解决)
在头文件中添加
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
#endif
2023/03/17 17:31 QByteArray, 提示 .isEmpty失败,但是头文件信息都有写,不知道问题是啥文章来源:https://uudwc.com/A/z38Da