网站建设进度规划,网站建设几点关门,开发建设网站需要什么人才,wordpress怎么进主页最近在学习qt#xff0c;于是打算搞一个串口调试助手#xff0c;初学C和QT#xff0c;有理解错误希望能给出意见。 总结归纳
2023.09.22#xff1a;能够显示串口数据
2023.09.25#xff1a;增加按钮打开以及之前没注意到的异常处理
2023.09.27#xff1a;知识补充串口…最近在学习qt于是打算搞一个串口调试助手初学C和QT有理解错误希望能给出意见。 总结归纳
2023.09.22能够显示串口数据
2023.09.25增加按钮打开以及之前没注意到的异常处理
2023.09.27知识补充串口编程Qt Serial Port
2023.09.27通过所学修改波特率和com口
2023.09.28增加发送串口数据 1、显示串口数据
创建qt widget工程ui界面就一个控件QTextEdit名称为Serial_Display 因为功能比较简单只需要显示串口数据即可。首先肯定是整体的初始化需要在.pro文件中添加QT serialport。包含两个头文件QtSerialPort/QSerialPort和QtSerialPort/QSerialPortInfo。接下来就是串口初始化配置
QSerialPort *serialPort new QSerialPort(this);serialPort-setPortName(COM6); // 替换为你的串口名称
serialPort-setBaudRate(QSerialPort::Baud115200);
serialPort-setParity(QSerialPort::NoParity);
serialPort-setDataBits(QSerialPort::Data8);
serialPort-setStopBits(QSerialPort::OneStop);
serialPort-setFlowControl(QSerialPort::NoFlowControl);
serialPort-open(QIODevice::ReadOnly); // 仅读
这一步有点像单片机的配置模块嫌麻烦所以直接在widget中的共有变量中声明了QSerialPort。然后是读取数据函数
void Widget::readSerialData()
{QByteArray data serialPort-readAll(); // 读取串口数据ui-Serial_Display-append(QString::fromUtf8(data)); // 在QTextEdit控件中显示数据
}
这里有一个问题就是readSerialData定义成了槽函数而串口读取就相当于一个信号信号与槽好像是qt的核心。我的理解就是信号是触发槽函数是一个动作所以读串口触发了文本写入也就是readSerialData函数。
connect(serialPort, QSerialPort::readyRead, this, Widget::readSerialData);
所以整体的代码为
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);///连接信号与槽connect(serialPort, QSerialPort::readyRead, this, Widget::readSerialData);///端口处理serialPort-setPortName(COM6); // 替换为你的串口名称serialPort-setBaudRate(QSerialPort::Baud115200);serialPort-setParity(QSerialPort::NoParity);serialPort-setDataBits(QSerialPort::Data8);serialPort-setStopBits(QSerialPort::OneStop);serialPort-setFlowControl(QSerialPort::NoFlowControl);serialPort-open(QIODevice::ReadOnly); // 仅读
}void Widget::readSerialData()
{QByteArray data serialPort-readAll(); // 读取串口数据ui-Serial_Display-append(QString::fromUtf8(data)); // 在QTextEdit控件中显示数据
}
这里有个问题串口确实接收到了数据但是都是乱码,QByteArray读取的是串口字节而ui-Serial_Display-append是QString类型所以可以将data转换成十六进制。
void Widget::readSerialData()
{QByteArray data 0;QString hexString 0;data serialPort-readAll(); // 读取串口字节hexString data.toHex(); // 将字节数组转换为十六进制字符串ui-Serial_Display-append(hexString); // 在QTextEdit控件中显示数据
} 2、增加按钮打开以及之前没注意到的异常处理
在ui界面增加一个QComboBox界面也就是下拉框用来扫描所有端口然后增加两个QPushButton一个用来打开串口另一个用来关闭串口。 这里有一点就是波特率需要能够自主选择这里可以双击波特率的下拉框然后在编辑组合框中添加需要的串口波特率。 接下来就是端口扫描 // 端口扫描
#if Serial_Scanforeach (const QSerialPortInfo inf0, QSerialPortInfo::availablePorts()){serialNamePort inf0.portName(); // 端口名称}ui-serialBox-addItems(serialNamePort); // 把扫描到的端口放入BOX中
#endif
这里的ui-serialBox表示选中了画的ui界面中的serialBox之前的串口下拉框的名称就是这个这个可以自己定义。
这段代码的解释这段代码是用C编写的。其中foreach是一个循环结构用于遍历集合中的每个元素。QSerialPortInfo::availablePorts()是Qt框架中QSerialPortInfo类的一个静态方法它返回一个包含所有可用串口信息的QList对象。inf0是遍历过程中每个QSerialPortInfo对象的引用。portName()方法返回串口的名称。serialNamePort可能是一个QStringList对象用于存储所有可用串口的名称。最后ui-serialBox-addItems(serialNamePort)将所有可用的串口名称添加到名为serialBox的QComboBox控件中。没错是搜的文心一言的解释
那么串口的设置尤其是串口号和串口波特率就需要进行相关的更改 /* 串口设置 */
#if Serial_Setserialport-setPortName(ui-serialBox-currentText()); // 串口下拉框当前数据serialport-setBaudRate(ui-baudrateBox-currentText().toInt()); // 设置为波特率下拉框中的当前数据serialport-setDataBits(QSerialPort::Data8); // 默认8位数据serialport-setStopBits(QSerialPort::OneStop); // 默认一位停止位serialport-setParity(QSerialPort::NoParity); // 默认没有奇偶校验位serialport-setFlowControl(QSerialPort::NoFlowControl); // 没有流控制
#endif
接着就是串口打开操作在打开串口的槽函数中(右击打开串口转到槽选中clicked()) 打开串口有两个注意点一个是就是普通的打开串口第二是如果已经打开串口就需要提示串口已打开。
void Widget::on_openButton_clicked(void)
{// 串口打开提示
#if Serial_Warningif (serialport-open(QIODevice::ReadWrite)) // 打开串口{// information函数表示普通的提示功能QMessageBox::information(this, 提示, 串口打开成功);}else{#if ERROR// critical函数表示警告QMessageBox::critical(this, 提示, 串口已打开);#endif}
#endif
}
而关闭串口只要直接关闭就行了
void Widget::on_closeButton_clicked()
{
#if Serial_Closed_Button// 关闭槽函数serialport-close();// 关闭串口提示QMessageBox::information(this, 提示, 关闭串口);
#endif
}
有一处改动将串口设置放到打开串口的槽函数中。发现如果在Widget::Widget函数中先扫描然后初始化串口会导致程序异常我也不知道为什么 3、知识补充串口编程Qt Serial Port
Qt Serial Port模块这个模块用于串口通信编程Qt Serial Port有两个类QSerialPortInfo和QSerialPort。
QSerialPortInfo类里面有两个函数我的理解是就是用来获取数据的 QSerialPortInfo::availablePorts() //获取串口列表 QSerialPortInfo::standardBaudRates() // 获取串口支持波特率列表
返回值获取串口列表QListQSerialPortInfo获取波特率的返回值是QListqint32。那接下来就有个问题怎么使用这两个函数
1QSerialPortInfo::availablePorts() - 这个函数返回的类型是QStringList表示一个列表看名字也看得出来。可以通过遍历这个列表获取系统所有的可用串口。
#include QSerialPortInfo
#include QDebug int main() { // 获取所有可用的串口 QListQSerialPortInfo ports QSerialPortInfo::availablePorts(); // 遍历并打印串口名称 for(const QSerialPortInfo port : ports) { qDebug() Port Name: port.portName(); } return 0;
} 2、QSerialPortInfo::standardBaudRates() - 这个函数返回一个包含所有标准波特率的QListqint32。这些波特率是串口通信中常用的标准波特率。
// 获取标准波特率列表 QListqint32 baudRates QSerialPortInfo::standardBaudRates(); // 遍历并打印波特率 for(qint32 baudRate : baudRates) { qDebug() Baud Rate: baudRate; } 4、通过所学修改波特率和com口的获取方法
根据之前学的qseriportinfo中的操作就可以修改波特率为所有波特率
#if Read_Serial// 获取波特率QString Baud_String;QStringList Baud_StringList;QListqint32 baudRates QSerialPortInfo::standardBaudRates(); // 获取标准波特率列表for(const qint32 baudRate : baudRates) // 遍历全部波特率列表{Baud_String QString::number(baudRate); // 将qint32转换成qStringBaud_StringList.append(Baud_String); // 添加到QString_List}// 把标准波特率添加到ui界面ui-baudrateBox-addItems(Baud_StringList);
#endif
同样的获取端口列表修改
#if Serial_Scan// 获取COM口QString COM_String;QStringList COM_StringList;QListQSerialPortInfo COM_Ports QSerialPortInfo::availablePorts();for(const QSerialPortInfo port : COM_Ports) // 遍历全部端口列表{COM_String port.portName(); // qstring保存端口名称COM_StringList.append(COM_String); // 添加到COM_string列表}ui-serialBox-addItems(COM_StringList); // 把扫描到的端口放入BOX中
#endif 接下来是QSerialPort类学习这个的时候有一个概念叫继承与重载之前学习C只学了个皮毛所以打算记录一下。
继承和重载面向对象的一个概念类和对象之间的一种关系。回顾继承和重载之前有一个概念是类和对象。
什么是类和对象
虽然之前已经接触过类和对象但还是只停留在似懂非懂的层面。类英文名叫class对象的英文名叫object。类就是有相同的属性和方法的东西而对象就是具体的东西。举个例子比如说人就是一类这个类里面有很多属性比如说身高体重。而具体的人就是对象比如说张三他的身高160体重50kg。转换成计算机语言就是先声明一个类比如class person{身高,体重}。接着用这个类再声明一个叫张三的人person 张三。然后再赋值属性比如张三-身高150,张三-体重-50kg。不知道对不对先暂时这么理解。
什么是继承和重载
接下来就可以学习继承和重载了。继承:一种类与类之间的关系它表示一个类称为子类可以继承另一个类称为父类的属性和方法继承允许我们在不重复编写代码的情况下扩展和定制现有代码的基础。
重载重载是指在同一类中可以定义多个具有相同名称但参数列表不同的方法。这些方法可以有不同的返回类型但关键是参数列表必须不同。 QSerialPort类中有以下一些重要的函数
1、open(OpenMode mode)这是QIODevice::open()的继承和重载。这个函数的功能是用“OpenMode”模式打开串口如果打开成功就返回true否则就返回false并且会报错错误码可以通过调用“erro()”函数来查看。
2、readData(char * data, qint64 maxSize)这是QIODevice::readData()的继承和重载用于从串口读取数据。
3、readLineData(char * data, qint64 maxSize)这是QIODevice::readLineData()的继承和重载用于从串口读取数据直到遇到换行符。
可以看出QSerialPort本质是对QIQDevice进行了一些处理和扩展使得满足串口的应用场景。 5、增加发送串口数据
在ui界面添加一个发送文本SendData和发送按钮。在发送的clicked()槽函数中做这么几件事首先是获取发送文本的数据因为是第一次添加发送数据所以按照一个byte去发后面要多组数据的话再想办法改进。
先要获取发送的数据DataToSend ui-SendData-toPlainText()接下来就是转换成字节然后使用serialport的成员函数write把数据发送出去
#if Serial_Send
// 串口发送
QByteArray Data;
QString DataToSend;
QByteArray DataByte;DataToSend ui-SendData-toPlainText(); // 获取发送中的数据
DataByte DataToSend.toUtf8(); // 转换成字节数组适应串口发送
serialport-write(DataByte); // 发送数据
#endif
实际的效果 0、发布程序
使用windeployqt首先是qt creator界面选择release运行程序在输出目录找到.exe文件 是以管理员身份运行qt里面的命令行程序(安装完qt自带的)然后跳转到.exe所在的目录命令
cd /d 后面再跟着目录cd /d C:\Users\dell\Desktop\qt project\exe
然后输入windeployqtexe的名称windeployqt untitled.exe。