天天看点

Qt串口助手相关程序含源码

        免费安装包与源码文件在文末

        Qt creater平台为我们提供了串口类,直接调用现成的类方法就可以实现串口功能。我创建了一个继承QSerialPort的子类Serial,这样方便调用串口方法。

// 引入下面两个串口相关类
#include <QSerialPort>
#include <QSerialPortInfo>

class Serial : public QSerialPort
{
public:
    explicit Serial();
};
           

现将主要程序代码介绍一下。

1.串口扫描函数

QStringList Serial::serialScan(void)
{
    QStringList serialPortList;

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        this->setPort(info);
        // 若当前串口被打开则只添加到列表不关闭 防止已打开串口时被强制关闭
        if(this->open(QIODevice::NotOpen)) {
            serialPortList.append(this->portName());
            this->close();
        } else {
            serialPortList.append(this->portName());
        }
    }
    return serialPortList;
}
           

 细心的小伙伴可能发现了上面串口扫描函数中不含有判断当前串口是否可被读写的代码↓↓↓

if(this->open(QIODevice::ReadWrite)) { xxx; }
           

将这个判断删去是因为当我们要定时刷新串口的话,此判断会使界面卡顿,所以删去

2.串口打开函数

bool Serial::serialOpen(QString serialName, int baudRate)
{
    this->setPortName(serialName);
    if(this->open(QIODevice::ReadWrite)) {
        this->setBaudRate(baudRate);
        this->setDataBits(QSerialPort::Data8); //这里是默认了数据位为8位,可改为上面传参的方式
        this->setParity(QSerialPort::NoParity); //同上
        this->setStopBits(QSerialPort::OneStop); //同上
        this->setFlowControl(QSerialPort::NoFlowControl);
        // 下位机发送数据会响应这个槽函数
        connect(this, &QSerialPort::readyRead, this, &Serial::readData);
        // 下位机发送数据会触发这个信号 给主界面处理数据使用
        connect(this, &QSerialPort::readyRead, this, &Serial::readSignal);
        return true;
    }
    return false;
}
           

3.读数据/写数据/关闭串口函数

// 读数据
void Serial::readData()
{
    dataBuf = this->readAll(); // 将读到的数据放到数据缓存区
}
// 写数据
void Serial::sendData(QByteArray sendData)
{
    this->write(sendData);
}
// 关闭串口
void Serial::serialClose()
{
    this->clear();
    this->close();
}
           

4.串口数据接收显示函数

void Page_one::receiveDate(void)
{
    // ASCII显示是否选中
    if(receive_ASCII->checkState() == Qt::Checked) {
        // 停止显示是否选中
        if(receive_stop->checkState() == Qt::Unchecked) {
            // 日志模式是否选中
            if(receive_diary->checkState() == Qt::Checked) {
                // 数据缓存区是否为空
                if(serial_main->dataBuf.isNull() == false) {
                    // 获取当前时间
                    this->getCurrentTime();
                    dateBufTemp += currentTimer;
                    // QByteArray转QString
                    dateBufTemp += tc->toUnicode(serial_main->dataBuf) + "\n";  // 转中文
                    text_receive->setText(dateBufTemp);
                }
            } else {
                dateBufTemp += tc->toUnicode(serial_main->dataBuf);  // 转中文
                text_receive->setText(dateBufTemp);
            }
        }
    } else if(receive_HEX->checkState() == Qt::Checked) {
        if(receive_stop->checkState() == Qt::Unchecked) {
            if(receive_diary->checkState() == Qt::Checked) {
                if(serial_main->dataBuf.isNull() == false) {
                    // 获取当前时间
                    this->getCurrentTime();
                    dateBufTemp += currentTimer;
                    // 转大写16进制,空格隔开
                    dateBufTemp += QString(serial_main->dataBuf.toHex(' ')).toUpper() + "\n";
                    text_receive->setText(dateBufTemp);
                }
            } else {
                // 转大写16进制,空格隔开
                dateBufTemp += QString(serial_main->dataBuf.toHex(' ')).toUpper() + " ";
                text_receive->setText(dateBufTemp);
            }
        }
    }
}
           

5.发送数据函数

void Page_one::transmitDate(void)
{
    if(transmit_ASCII->checkState() == Qt::Checked) {
        QByteArray transmitDataTemp;
        if(transmit_newLine->checkState() == Qt::Checked) {
            // 将获取的文本内容转换为QByteArray类型
            transmitDataTemp = tc->fromUnicode(text_transmit->toPlainText() + "\n");
        } else {
            transmitDataTemp = tc->fromUnicode(text_transmit->toPlainText());
        }
        serial_main->sendData(transmitDataTemp);
    } else if(transmit_HEX->checkState() == Qt::Checked) {
        QByteArray transmitDataTemp;
        if(transmit_newLine->checkState() == Qt::Checked) {
            // 将获取的文本内容转换为QByteArray类型后再转换为16进制并大写
            transmitDataTemp = QByteArray::fromHex(tc->fromUnicode(text_transmit->toPlainText() + "\n")).toUpper();
        } else {
            transmitDataTemp = QByteArray::fromHex(tc->fromUnicode(text_transmit->toPlainText())).toUpper();
        }
        serial_main->sendData(transmitDataTemp);
    }
}
           

6.串口定时更新函数

// 串口定时扫描更新
    t2 = new QTimer();
    t2->start(1000);
    connect(t2, &QTimer::timeout, this, [=](){
        serialNameListOld = serialNameList;
        serialNameList = serial_main->serialScan();
        currentPortText = serial_port_C->currentText();
        // 如果上次列表和当前列表不一致则更新端口列表
        if(serialNameListOld != serialNameList) {
            serial_port_C->clear();
            serial_port_C->addItems(serialNameList);
            serial_port_C->setCurrentText(currentPortText);
        }
        // 打开串口时串口变化 如果处于打开状态的端口被拔出则重置串口状态
        if(!serial_ONOFF_P_flag) {
            if((serial_port_C->currentText() == "") || (serial_port_C->currentText() != currentPort)) {
                serial_ONOFF_P->setText("打开串口");
                serial_ONOFF_L->setPixmap(QPixmap(":/IMG/OFF.png"));
                serial_ONOFF_P_flag = true;
                QMessageBox::about(this, "错误提示", "当前串口已关闭");
                serial_main->close();
            }
        }
    });
           

最终的样子就是这样的,基本功能也已经实现,测试能用

普通版:

Qt串口助手相关程序含源码

UI版:

Qt串口助手相关程序含源码

 最后将串口助手的安装包和源码给大家使用和参考:

普通版安装包:https://download.csdn.net/download/m0_50669075/20821190

普通版源码:https://download.csdn.net/download/m0_50669075/20821174

UI版安装包:https://download.csdn.net/download/m0_50669075/21789587

UI版源码:https://download.csdn.net/download/m0_50669075/21789600

继续阅读