QT实现串口调试助手(八):HEX与字符串格式处理

10 篇文章 37 订阅

上一篇:
QT实现串口调试助手(七):字体设置面板创建及窗体间传值
 

串口调试工具往期相关文章


串口工具一般都会有HEX格式的收发处理,现在我们来给串口工具添上这一功能。

这主要分为两类,一类是把串口工具收到的HEX格式数据,以十六进制字符串回显到接收面板。另一类是把发送面板上的十六进制字符串,转为HEX格式数据发送出去


1、接收数据处理

原先我们已经在主界面添加了HEX发送和接收框了,没有添加的话,添加一个即可



然后更改一下原先的接收处理函数:

//填入接收数据到面板
void MainWindow::insertDataToPlain()
{
    curDateTime = QDateTime::currentDateTime();

    QString tempRecData = "\r\n";

    if(ui->timeZoneCheckBox->isChecked())
    {
        tempRecData.append(curDateTime.toString("[hh:mm:ss]")).append("R:");
        ui->uartReadPlain->insertPlainText(tempRecData);
        if(ui->checkBoxHexR->isChecked())
        {
            QString ss;
            for(int c :uart_rec_ss)
            {
                if(c>=0)
                {
                    ss += QString(" %1")
                            .arg(c, 2, 16, QChar('0'));
                }
                else
                {
                    ss += QString(" %1")
                            .arg(c+256, 2, 16, QChar('0'));
                }
            }
            ui->uartReadPlain->insertPlainText(ss);
        }
        else
        {
            ui->uartReadPlain->insertPlainText(uart_rec_ss);
        }
    }
    else
    {
        if(ui->checkBoxHexR->isChecked())
        {
            QString ss;
            for(int c :uart_rec_ss)
            {
                if(c>=0)
                {
                    ss += QString(" %1")
                            .arg(c, 2, 16, QChar('0'));
                }
                else
                {
                    ss += QString(" %1")
                            .arg(c+256, 2, 16, QChar('0'));
                }
            }
            ui->uartReadPlain->insertPlainText(ss);
        }
        else
        {
            ui->uartReadPlain->insertPlainText(uart_rec_ss);
        }
    }
    ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾
}

重点是中间的这段处理,将接收到的数据每字节拆成字符串,比如0x30就拆成字符串“30”,再做拼接。需要注意QT接收到数据的时候是有符号类型的,会有负数,我们需要加上256把它转成正值再做字符串转换,不然转换出的字符串里就一堆FFFFFFF了。

            for(int c :uart_rec_ss)
            {
                if(c>=0)
                {
                    ss += QString(" %1")
                            .arg(c, 2, 16, QChar('0'));
                }
                else
                {
                    ss += QString(" %1")
                            .arg(c+256, 2, 16, QChar('0'));
                }
            }

2、发送数据处理

因为处理发送的事件类型比较多,涉及参数也比较多(HEX、时间戳、回车换行),可以把它封装一下。
创建一个新的CPP文件,比如uart.cpp和uart.h

在文件里面添加一个发送的串口函数,如下:

#include "uart.h"

//发送串口数据
QString MainWindow::sendUartData(QString data,bool isHex,bool hasTimerStamp,bool isAT)
{
    curDateTime = QDateTime::currentDateTime();

    QString command = "";
    QString showBuff = "";

    command.append(data);

    if(isAT){
        command.append("\r\n");
    }

    if(hasTimerStamp){
        QString tempStr = "\r\n"+curDateTime.toString("[hh:mm:ss]")+"S:";
        showBuff = tempStr + command;
    }

    //HEX格式发送
    if(isHex){
        //将接收到的HEX格式字符串转为HEX格式原始数据
        QByteArray arr;

        //分析字符串格式中是否带空格
        for(int i = 0;i<data.size();i++)
        {
            if(data[i]==' ')
                continue;   //跳过

            int num  = data.mid(i,2).toUInt(nullptr,16);
            i++;

            arr.append(num);
        }

        send_buf_len += arr.length();
        //发送HEX格式原始数据
        serial->write(arr);

        //返回HEX格式字符串显示到串口接收面板
        return showBuff;
    }
    //非HEX格式发送
    else {
        send_buf_len += data.length();
        serial->write(command.toLatin1());
        return showBuff;
    }
}

带上发送内容、是否HEX格式、是否有时间戳、是否带回车换行这几个参数,返回值为被修改后的新的字符串,用于发送完后显示到接收面板上。

然后,修改一下之前发送串口数据的函数,主要是两个地方:

(1)串口发送面板发送数据更改

//主界面串口发送面板,按键发送数据
void MainWindow::on_sendDataButton_clicked()
{
    if(ui->openSerialButton->text() == "打开串口")
    {
        QMessageBox::warning(NULL, "警告", "未打开可用串口,无法发送数据!\r\n\r\n");
        return;
    }

    QString command = ui->uartWritePlain->toPlainText();

    //发送数据
    QString recShowData = sendUartData(command,ui->checkBoxHexS->isChecked(),
                 ui->timeZoneCheckBox->isChecked(),ui->changeLineCheckBox->isChecked());

    if(ui->timeZoneCheckBox->isChecked())
    {
        ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾
        ui->uartReadPlain->insertPlainText(recShowData);
        ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾
    }

    ui->TXLenLabel->setText(QString::number(send_buf_len)+"bytes");
}

(2)命令列表面板发送数据更改


 

//命令菜单按键发送数据
void MainWindow::sendButtonClick(QString command,bool isChecked)
{
    //未打开串口则不准发送
    if(ui->openSerialButton->text() == "打开串口")
    {
        QMessageBox::warning(NULL, "警告", "未打开可用串口,无法发送数据!\r\n\r\n");
        return;
    }

    //拼接数据
    QString recShowData = sendUartData(command,isChecked,
                 ui->timeZoneCheckBox->isChecked(),ui->changeLineCheckBox->isChecked());

    if(ui->timeZoneCheckBox->isChecked())
    {
        ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾
        ui->uartReadPlain->insertPlainText(recShowData);
        ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾
    }

    ui->TXLenLabel->setText(QString::number(send_buf_len)+"bytes");
}

和第一个稍有不同,主要是添加一个是否选择HEX格式的参数,因为一般串口工具的命令面板的HEX格式不是由主界面的check框决定的,而是列表里面的Check框决定的,所以我们要多添加一个参数。



然后,我们需要将这个HEX选项加入配置文件里,并做处理,使其每次打开不会丢失:

(1)保存HEX配置参数:

在原先配置基础上,增加一段是否选择HEX格式的内容

    //命令面板相关
    qint32 rowNum = ui->tableWidget->rowCount();
    for(int i =0;i<rowNum;i++)
    {
        //保存命令内容
        auto cellWidget = (ui->tableWidget->cellWidget(i, 1));
        QLineEdit *lines =(QLineEdit*)cellWidget;
        QString cmdVal = "cmdParam/cmd";
        cmdVal.append(QString::number(i));
        configIni->setValue(cmdVal,lines->text());

        //保存是否选择HEX
        cellWidget = (ui->tableWidget->cellWidget(i, 0));
        QCheckBox *box =(QCheckBox*)cellWidget;
        cmdVal = "cmdParam/hex";
        cmdVal.append(QString::number(i));
        configIni->setValue(cmdVal,box->isChecked());
    }

(2)启动时读取HEX配置参数:

同样增加一段HEX参数选择解析,同时按键的绑定事件sendButtonClick也做了相应修改,因为添加了一个是否使用HEX的参数

    for(int i=0;i<100;i++)
    {
        ui->tableWidget->insertRow(i);

        //根据配置文件内容填充数据
        
        //HEX格式选择
        QCheckBox *box = new QCheckBox();
        ui->tableWidget->setCellWidget(i,0,box);
        if(configIni != NULL)
        {
            QString tempPara = "cmdParam/hex";
            tempPara.append(QString::number(i));
            box->setChecked(configIni->value(tempPara).toBool());
        }

        //命令文本
        QLineEdit *lineOne = new QLineEdit();
        if(configIni != NULL)
        {
            QString tempPara = "cmdParam/cmd";
            tempPara.append(QString::number(i));
            lineOne->setText(configIni->value(tempPara).toString());
        }
        ui->tableWidget->setCellWidget(i,1,lineOne);

        QPushButton *button = new QPushButton();
        button->setText("发送");
        ui->tableWidget->setCellWidget(i,2,button);
        connect(button,&QPushButton::clicked,
                    [=] ()
                    {
                        sendButtonClick(lineOne->text(),box->isChecked());
                    }
                    );
    }

大功告成!现在无论是发送窗口,还是命令面板,HEX格式和字符串格式都可以自由收发和切换了。


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值