串口调试工具开发

初学Qt,完成一个简单的串口调试工具

最终效果图,图上功能都可实现

UI界面绘制

代码如下


串口调试工具开发

1.创建工程QWidget,根据串口调试工具绘制Ui界面
给每个控件设置特定名,方便调用

2.在.pro文件添加代码
QT  += core gui serialport

3.在.h文件头添加代码
#include <QSerialPort>
#include <QSerialPortInfo>

private:
    Ui::Widget *ui;
    QSerialPort * serialport;//串口端口
    QTimer *timSend;//创建定时器对象
    QString  mTime;//拼接日志样式对象
    QDateTime mDateTime;//获取当前时间
    QByteArray Sendtext;//发送缓存区
    QByteArray Receivetext;//接收缓存区
    long int SendByte=0;//发送字符数
    long int ReceByte=0;//接收字符数

4.给串口号设置自动获取电脑中的串口

//遍历可用串口设备
    //创建一个QStringList 对象来存储端口名
    QStringList serialPort_Name;
    //foreach遍历方法
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){
        //端口名呈现格式
        serialPort_Name << info.portName();
    }
    //添加到控件串口显示
    ui->PostName->addItems(serialPort_Name);

*如果需要过滤无用串口,代码如下

//获取串口列表
        int snum=0;
        
        //用下面的方法会过滤掉一些无用的串口
        QSerialPort temp_serial;
        foreach (const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) {

            temp_serial.setPort(Info);
            if(temp_serial.open(QIODevice::ReadWrite)){//如果串口是可以读写方式打开的
                ui->PostName->addItem(Info.portName());
                temp_serial.close();
                ++snum;
            }
        }
        //默认选中第0项
        if(snum>2){
            ui->PostName->setCurrentIndex(1);
        }
         ui->PostName->currentText();

*如果需要对下拉框进行自适应设置,代码如下

//下拉列表自适应
    /* 获取最长字符串 */
    int maxlen = 0;
    for (int index = 0; index < ui->PostName->count(); index++)
    {
        if (ui->PostName->itemText(index).length() > maxlen)
        {
            maxlen = ui->PostName->itemText(index).length();
        }
    }
    /*获取字体磅值转换为像素值*/
    int fontsize = ui->PostName->font().pointSize();//获取字体的磅值
    ui->PostName->setFixedWidth(fontsize * maxlen * 0.75);//设置像素值
```

接下来需声明一个串口全局对象,在.h文件中
QSerialPort * serialport;//串口端口


声明后在.cpp文件中创建出来
serialport = new QSerialPort(this);//声明后把对象创建出来

给打开按钮设置转到槽

.h文件自动生成
private slots:
    void on_Btn_Open_clicked();//打开键按下

/*打开按钮配置*/
/*串口参数配置*/
void Widget::on_Btn_Open_clicked()
{
    if (ui->Btn_Open->text()=="打开") {
        //设置串口名
        serialport->setPortName(ui->PostName->currentText());
        //设置波特率
        switch (ui->BaudRate->currentIndex())
        {
        case 0:
            serialport->setBaudRate(QSerialPort::Baud19200,QSerialPort::AllDirections);
            break;

        case 1:
            serialport->setBaudRate(QSerialPort::Baud38400,QSerialPort::AllDirections);
            break;
        case 2:
            serialport->setBaudRate(QSerialPort::Baud57600,QSerialPort::AllDirections);
            break;
        default:
            serialport->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
            break;
        }
/* 检验位、数据位、停止位、流控制 与 波特率(switch)写法一致 */
        
        //打开串口
        if(!serialport->open(QIODevice::ReadWrite)){
            QMessageBox::about(NULL,"提示","无法打开串口");
            return;
        }
        
        /*点击后效果*/
        //设置控件不可编辑
        ui->PostName->setEnabled(false);
        ui->BaudRate->setEnabled(false);
        ui->Parity->setEnabled(false);
        ui->DataBits->setEnabled(false);
        ui->StopBits->setEnabled(false);
        ui->FlowControl->setEnabled(false);
        //点击打开按钮后发送和循环发送可编辑
        ui->Btn_Send->setEnabled(true);
        ui->Cyclet_time->setEnabled(true);
        //点击打开后显示关闭
        ui->Btn_Open->setText("关闭");
        ui->Btn_Open->setStyleSheet("QPushButton{color:red;background:yellow}");
        
        /*点击前效果*/
        与上方代码相反,写在else{}中
```

获取时间戳

/*获取时间戳*/
先在.h头文件创建对象,如经常使用的对象,都在头文件创建,减少损耗资源
QString  mTime;
QDateTime mDateTime;
.cpp文件写对应事件
if(ui->Re_Log->isChecked()){
        mDateTime = QDateTime::currentDateTime();
    //拼接日志样式
        mTime = "[";
        mTime += mDateTime.toString("[yyyy-MM-dd hh:mm:ss.zzz]") ;
        mTime += "]:RECV ->" ;
        mTime += Receivetext;
        ui->Re_Edit->append(mTime);
    }

添加数据换行问题,insertPlainText函数在原数据末尾直接添加,可以使用append函数替代换行添加

if(ui->Re_Line->checkState()==Qt::Checked)
    {
        ui->Re_Edit->append(Receivetext);
    }
    else
    {
        ui->Re_Edit->insertPlainText(Receivetext);
    }
```

**串口接收代码**

/*串口接收*/
void Widget::on_SerialPort_readyRead(){
    int i,length;
    Receivetext = serialport->readAll();

    //接收字节并显示
    ReceByte+=Receivetext.length();
    ui->Re_Byte->setText(QString::number(ReceByte));

    //十六进制
    if(ui->Re_Hex->checkState()==Qt::Checked)
    {
        //字符串转十六进制
        Receivetext = Receivetext.toHex().toUpper();
        length=Receivetext.length();
        for(i=0;i<=length/2;i++)
        {
            //插入空格字符串
            Receivetext.insert((2+3*i),' ');
        }
    }

    //自动换行
    if(ui->Re_Line->checkState()==Qt::Checked)
    {
        ui->Re_Edit->append(Receivetext);
    }
    //日志显示样式
    else if(ui->Re_Log->isChecked()){
        //获取当前时间
        mDateTime = QDateTime::currentDateTime();
        //时间展示拼接样式
        mTime = "[";
        mTime += mDateTime.toString("[yyyy-MM-dd hh:mm:ss.zzz]") ;
        mTime += "]:RECV ->" ;
        mTime += Receivetext;
        //append自动换行
        ui->Re_Edit->append(mTime);
    }
    else
    {
        //原数据末尾添加(文本接收)
        ui->Re_Edit->insertPlainText(Receivetext);
    }
}

**串口发送代码**

void Widget::on_Btn_Send_clicked()
{
    int i,length;
    Sendtext = ui->Se_Edit->toPlainText().toUtf8();

    //发送设置HEX
    if(ui->Se_Hex->checkState()==Qt::Checked)
    {
        //转换成十六进制
        Sendtext = Sendtext.toHex().toUpper();
        length=Sendtext.length();
        for(i=0;i<=length/2;i++)
        {
            //插入空格字符串
            Sendtext.insert((2+3*i),' ');
        }

        serialport->write(Sendtext);
    }
    else
    {
        serialport->write(Sendtext);

    }
    //发送字节显示
    SendByte+=Sendtext.length();
    ui->Se_Byte->setText(QString::number(SendByte));
//    ui->Se_Edit->moveCursor(QTextCursor::End);

}


定时器使用方法

在.h头文件中
//定义并初始化mTimerID
int  mTimerID= 0;
    
  /*定时器定时发送*/
    //设置默认值1000ms
mTimerID = startTimer(500);

在.cpp文件中
void Widget::timerEvent(QTimerEvent *event)
{
    qDebug()<<"我是定时器!";
}
void Widget::closeEvent(QCloseEvent *event)
{
    if(mTimerID)
    {
        killTimer(mTimerID);

        mTimerID = 0;
    }
}

**串口循环发送代码**

在.h头文件
QTimer *timSend;//创建定时器对象

在.cpp文件
//定时发送=定时器
       timSend=new QTimer;
       timSend->setInterval(1000);//设置默认值1000ms
        //定时器信号连接发送信号
        connect(timSend,&QTimer::timeout,this,[=]()
        {
           on_Btn_Send_clicked();
        });

ui界面给循环发送checkbox转到槽
    void on_Cyclet_time_stateChanged(int arg1);//循环发送

void Widget::on_Cyclet_time_stateChanged(int arg1)
{
    //获取复选框状态,没有选就为0,选择了就为2
        if(arg1==0)
        {
            timSend->stop();
        }
        else {
            //对输入的值大小的限制,小于10会弹出对话框提示
            if(ui->Se_Line_2->text().toInt()>=10)
            {
                timSend->start(ui->Se_Line_2->text().toInt());//设置时长,重新计数
            }
            else {
                ui->Cyclet_time->setCheckState(Qt::Unchecked);
                QMessageBox::information(this,"错误提示","定时发送最小间隔为10ms!");
            }
        }
}

```

清空按钮

在.h头文件
void on_Btn_Reclean_clicked();//清空接收区域
void on_Btn_Seclean_clicked();//清空发送区域

在.cpp文件
/*清空接收区域*/
void Widget::on_Btn_Reclean_clicked()
{
    ui->Re_Edit->clear();
}
/*清空发送区域*/
void Widget::on_Btn_Seclean_clicked()
{
    ui->Se_Edit->clear();
}

ASCII、HEX发送与接收

在.h头文件中
void on_Re_Hex_clicked();//点击十六进制接收
void on_Se_Ascll_clicked();//点击ASCII发送

在.cpp文件中
/*十六进制接收*/
void Widget::on_Re_Hex_clicked()
{
    ui->Re_Ascll->setCheckState(Qt::Unchecked);
    ui->Re_Hex->setCheckState(Qt::Checked);
}

/*ASCII发送*/
void Widget::on_Se_Ascll_clicked()
{
    ui->Se_Ascll->setCheckState(Qt::Checked);
    ui->Se_Hex->setCheckState(Qt::Unchecked);
}

复位计数

在.h头文件中
void on_Btn_Reset_clicked();//复位计数

在.cpp文件中
/*清除计数*/
void Widget::on_Btn_Reset_clicked()
{
    SendByte = 0;
    ReceByte = 0;
    ui->Re_Byte->setText(QString::number(ReceByte));
    ui->Se_Byte->setText(QString::number(SendByte));
}
```

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值