1. 串口基本开发流程

USART串口是一种两线的通讯协议(TX线:数据传输, RX线:数据接收)
一个串口主要有以下几种参数:

BaudRate(波特率) 代表数据传输的速率
DataBits(数据长度) 每个数据包长度是8位还是16位
Parity(校验位) 是否使用奇偶校验位
StopBits(停止位) 代表停止位的长度
FlowControl(流控制) 指定流控制方式

完整的串口程序需要指定以上这些参数。基本串口程序开发的流程如下:


2. Qt 的串口相关类

在 Qt 中与串口相关的类主要有2个:

  • QSerialPortInfo
  • QSerialPort

    2.1 QSerialPortInfo

    2.1.1 获取可用串口设备

    这个类主要用于获取当前设备的串口信息,并且提供了一个静态函数 availablePorts() ,直接返回当前电脑上的所有设备串口信息对象(QSerialPortInfo 对象)。而 QSerialPortInfo 对象主要有以下的接口可用:

  • portName() : 获取该串口信息的串口名(下图中的 COM5

  • description() :获该串口信息的类型(下图中的 USB-SERIAL CH340

image.png

availablePorts() 返回的对象格式是 QList<QSerialPortInfo> ,是C++中的容器对象,可以用for循环来遍历,以下代码是常见的获取当前设备串口设备信息的组合:

  1. #include <QSerialPortInfo>
  2. //...
  3. for(QSerialPortInfo info : QSerialPortInfo::availablePorts()) {
  4. qDebug() << info.portName() + ": " + info.description() ;
  5. }

2.1.2 获取可用波特率

此外, QSerialPortInfo 还提供了一个静态函数 standardBaudRates() , 获取当前平台支持的波特率。常用方法如下:

  1. for(int baud : QSerialPortInfo::standardBaudRates()){
  2. qDebug() << baud;
  3. }

2.2 QSerialPort

在通过 QSerialPortInfo 中选择对应的串口信息后,可以通过PortName来指定打开某个串口。打开串口需要新建QSerialPort对象,执行以下流程

2.2.1 串口参数设置

a. 校验位参数

通过 **setParity(QSerialPort::Parity)** 来设置是否使用校验位。可填入的参数如下:

QSerialPort::NoParity 0 不进行校验,也是串口类的默认值
QSerialPort::EvenParity 2 偶校验
QSerialPort::OddParity 3 奇校验
QSerialPort::SpaceParity 4 校验位恒为0
QSerialPort::MarkParity 5 校验位恒为1
QSerialPort::UnknownParity -1 未知校验方式

常用的是无校验、奇校验,偶校验这3种

  1. serial_port->setParity(QSerialPort::Parity::NoParity); //不校验 值为0
  2. serial_port->setParity(QSerialPort::Parity::EvenParity); //偶校验 值为2
  3. serial_port->setParity(QSerialPort::Parity::OddParity); //奇校验 值为3

b. 波特率参数

通过**setBaudRate(qint32 baudRate)** 来设置波特率

  1. serial_port->setBaudRate(115200);

c. 数据长度参数

通过 **setDataBits(QSerialPort::DataBits dataBits)** 来指定数据位的长度。默认值为QSerialPort::Data8

Constant Value
QSerialPort::Data5 5
QSerialPort::Data6 6
QSerialPort::Data7 7
QSerialPort::Data8 8
QSerialPort::UnknownDataBits -1
  1. serial_port->setDataBits(QSerialPort::DataBits::Data8);

d.停止位参数

通过 **setStopBits**``(QSerialPort::StopBits ``_stopBits_``) 设置停止位。默认值QSerialPort::OneStop

Constant Value Description
QSerialPort::OneStop 1 1 位
QSerialPort::OneAndHalfStop 3 1.5 位(只在windows可用)
QSerialPort::TwoStop 2 2 位
QSerialPort::UnknownStopBits -1 未知位数
  1. serial_port->setStopBits(QSerialPort::StopBits::OneStop);

e. 流控制位设置

流控可以使数据接收设备在不能接收数据时通知数据发送设备,使其停止发送。
通过 **setFlowControl**``**(QSerialPort::FlowControl flowControl)**,默认值是 NoFlowControl

Constant Value Description
QSerialPort::NoFlowControl 0 无流控制
QSerialPort::HardwareControl 1 硬件流控制
QSerialPort::SoftwareControl 2 软件流控制
QSerialPort::UnknownFlowControl -1 未知流控制
  1. serial_port->setFlowControl(QSerialPort::FlowControl::NoFlowControl);

f. 常用默认设置
  1. serial_port->setBaudRate(115200);
  2. serial_port->setParity(QSerialPort::Parity::EvenParity);
  3. serial_port->setDataBits(QSerialPort::DataBits::Data8);
  4. serial_port->setStopBits(QSerialPort::StopBits::OneStop);
  5. serial_port->setFlowControl(QSerialPort::FlowControl::NoFlowControl);

2.2.2. 串口基本操作

在完成串口的基本配置,可以对串口执行以下操作:

a. 串口指定

可以通过 setPortsetPortName指定打开的串口

  1. serial_port->setPortName("COM5");

b. 串口打开

使用 open(QIODevice::OpenMode mode) 函数来打开串口。在打开串口的时候需要传入读写的模式类型(QIODevice 类中定义),支持传入的类型有以下:

Constant Value Description
QIODevice::ReadOnly 0x0001 只读模式
QIODevice::WriteOnly 0x0002 只写模式
QIODevice::ReadWrite `ReadOnly WriteOnly` 读写模式
  1. serial_port->open(QIODevice::ReadWrite);

一般在open之前,会检查以下当前串口是不是被其他设备打开

  1. if(!serial_port->isOpen()) {
  2. serial_port->open(QIODevice::ReadWrite);
  3. }

c. 串口关闭
  1. if(serial_port->isOpen()) {
  2. serial_port->close;
  3. }

2.2.3 监听串口信息

要监听串口数据的到来,借助readReady() 信号,可以知道当前串口有数据接收到:

  1. connect(serial_port,SIGNAL(readyRead()),this,SLOT(receiveData()));
  2. void receiveData(){
  3. QByteArray data = serial_port->readAll();
  4. qDebug() << data.toString();
  5. }

2.2.4 发送串口数据

  1. serial_port->write("hello");