前言
该篇介绍 Qt
串口相关类 - QSerialPort
& QSerialPortInfo
。
主要参考自 Qt
的官方文档,边学习边梳理,记录一下自己的思考及想法,仅此而已。
如有错漏,望不吝指教。
QSerialPortInfo
该类在 Qt5.1
中首次引入;作为串口辅助类,主要是提供系统已存在串口的信息(端口号,端口类型,系统位置,厂商信息等)。
上述信息可通过静态函数 availablePorts()
获取。这也是该类中最为重要的一个函数。
QSerialPortInfo
类也可以被用于 QSerialPort::setPort()
方法的输入参数。
及 QSerialPort构造函数参数
。
通常我们先使用该类检测可用端口,再创建 QSerialPort对象
。
此外该类中还有另一静态方法,可返回目标平台支持的可用标准波特率。
下面看一下demo
void MainWindow::on_pushButton_clicked()
{
// QList<QSerialPortInfo> qlist = QSerialPortInfo::availablePorts();
foreach (const QSerialPortInfo &port, QSerialPortInfo::availablePorts()){
ui->textBrowser->append("名称:" + port.portName());
ui->textBrowser->append("产品编码:" + port.productIdentifier());
ui->textBrowser->append("系统位置:" + port.systemLocation());
ui->textBrowser->append("序列号字符串:" + port.serialNumber());
ui->textBrowser->append("描述字符串:" + port.description());
ui->textBrowser->append("制造商:" + port.manufacturer());
ui->textBrowser->append("供应商编码:" + port.vendorIdentifier());
}
}
void MainWindow::on_pushButton_2_clicked(){
// QList<qint32> qlist = QSerialPortInfo::standardBaudRates();
foreach (const qint32 &baudrate, QSerialPortInfo::standardBaudRates()) {
ui->textBrowser_2->append("BaudRates:" + QString::number(baudrate));
}
}
效果
QSerialPort
学习 QSerialPort
,个人建议先到 Qt
的 Class
文档中将其属性、方法、信号等过一遍。这样对类内容有个大致了解。同时根据文档也能梳理出大致的使用流程。
下面是我个人梳理的部分内容,如有错误还望指正。
枚举类型
- BaudPate(波特率)
- DataBits(数据位数)
- Directions(数据传输方向)
- FlowControl(流控)
- Parity(奇偶校验)
- PinoutSignal(可能存在的RS232的引脚分配)
- SerialPortError(错误类型)
- StopBits(停止位)
属性
- baudRalt
波特率
设置成功/在打开串口前设置则返回true
设置方法:setBaudRate(波特率,传播方向)
通知信号:baudRaltChanged
注意:在Windows
上仅支持双向 - breakEnabled
该属性使传输线处于中断状态
注意:在尝试设置或获取该属性之前,必须先打开串行端口
该属性是通过内核和硬件的交互未设置的
set方法
+Changed信号
- dataBits
数据位
设置成功/在打开串口前设置则返回true
set方法
+Changed信号
- dataTerminalReady
保留线路信号DTR
的状态
在尝试设置或获取此属性前,应先打开端口
set方法
+Changed信号
- error
保留串行端口的错误状态
相关方法:error()
、clearError()
- flowControl
保存流控模式
设置成功/在打开串口前设置则返回true
默认状态为无流控NoFlowControl
set方法
+Changed信号
- parity
保存奇偶校验模式
设置成功/在打开串口前设置则返回true
默认无校验NoParity
set方法
+Changed信号
- requestToSend
保存线路信号RTS
状态
设置/获取此属性前,必须打开端口
注意:在硬件流控模式下尝试控制RTS
信号的尝试将失败,该信号由驱动程序自动控制
set方法
+Changed信号
- stopBits
保存停止数数量
设置成功/在打开串口前设置则返回true
默认一个停止位OneStop
set方法
+Changed信号
方法
- SerialPort()
QSerialPort
提供了以下构造方法,可以发现我们可以通过QSerialPortInfo
去创建,也可以通过端口名去设置,亦可不要参数,后面通过setPortName
进行端口绑定。QSerialPort(const QSerialPortInfo&serialPortInfo,QObject * parent = nullptr)
QSerialPort(const QString&name,QObject * parent = nullptr)
QSerialPort(QObject * parent = nullptr)
- atEnd()
判断当前有无更多数据可读
在循环读取中常用此功能 - byteAvailable()
返回待读取字节数 - byteToWrite()
返回待写入字节数
当控制权返回事件循环/调用flush()
方法时,将写入字节 - canReadLine()
检测是否可从串行端口读取一行数据 - clear()
根据给定的方向清空输入/输出缓冲区
包括内部类缓冲区及UART驱动程序缓冲区
同时终止挂起的读写操作 - close()
关闭串行端口 - flush()
调用该方法可将缓冲区的数据立刻发送到串行端口
成功写入的字节数取决于操作系统
大多数情况下不须调用此函数
一但控制权返回事件循环,QSerialPort类
将自动开始发送;
若无事件循环应使用waitForByteWritten()
- handle()
返回本机串行端口的句柄
官方建议:新手慎用!
此外,该功能在较小的Qt版本中无兼容性保证。 - isSequential()
总返回ture
串行端口是顺序设备 - open()
打开串口,支持的模式有:只读、只写、可读写 - pinoutSignals()
以位图格式返回线路信号状态
注意:此方法执行系统调用,从而确保正常返回线路信号状态,当操作系统无法提供有效更改的适当通知时,这是必须的。
该方法必须在打开串口后使用 - portName()
返回由setPort()
设置或传递给QSerialPort
构造函数的名称。该名称很短,即从设备的内部变量系统位置提取并转换,转换算法有别于平台。
例如:Windows
:删除前缀\\. \ // /.
Unix
,BSD
:删除前缀/dev
- readBufferSize()
返回内部读取缓冲区大小,这限制了客户端调用read()
、readAll()
方法前可接收的数据量
默认大小为0
,表示缓冲区没有大小限制 - readData()
重新实现的方法 - readLineData()
重新实现的方法 - sendBreak()
若终端使用异步串行数据,则在指定的持续时间内发送连续的零位流
若持续时间为0
,则零位传输0.25-0.5s
若持续时间不为0
,则根据实现方式在某个时间端内传输零位 - sendPort()
设置存储在串行端口信息实例SerialPortInfo
中的端口 - setPortName()
设置端口名称 - sendReadBufferSize()
设置内部读取缓冲区大小,0
意味着大小不受限制 - waitForReadyRead()
阻塞,直到可以可以读取新数据并发出readyRead()
信号为止
超时时间默认300ms
,若msecs
设置为-1
,则该功能不会超时 - writeData()
将数据按最大字节maxsize
写入设备
返回值为写入的x字节数
,发送错误返回-1
信号
除 errorOccurred
外,其他都是改变端口属性时触发的信号
使用流程
- 创建QSerialPort对象
mSerial = new QSerialPort();
mSerial->setPortName(mPortName);
- 设置串口参数
mSerial->setBaudRate(mBaudRate);
mSerial->setDataBits(mDataBits);
mSerial->setFlowControl(mFlowControl);
mSerial->setParity(mParity);
mSerial->setStopBits(mStopBits);
- open()
if(mSerial->open((QIODevice::ReadWrite))){
//打开成功则绑定readyRead()信号,在slot_uartReadData()读取
connect(mSerial,SIGNAL(readyRead()),this,SLOT(slot_uartReadData()));
connect(mSerial,SIGNAL(errorOccurred(QSerialPort::SerialPortError)),
this,SLOT(slot_uartError(QSerialPort::SerialPortError)));
}
else{
//xxx
}
- R/W
//W
mSerial->write(ui->textEdit_output->toPlainText().toLocal8Bit().data());
//R
QByteArray bytearray = mSerial->readAll();
- close()
mSerial->close();
续
可以看到使用非常简单,下一篇将是我利用QSerialPort
及QSerilalPortInfo
实现的调试助手UHelp
有时间我会打包发布出来,既然选择Qt,当然要试试它的跨平台
先放个丑照~