【QT】TemperAssistant—串口接收功能配置

目录

一、复位接收/发送计数器

二、串口接收数据程序

2.1 串口接收回调函数slots_serialRxCallback()

2.2 串口接收插入时间戳insertTimeStramp(QByteArray &tmp)

2.3 接收显示函数slots_rxDisplayTxt()

三、清空接收文本框on_btnClear_clicked()

工程下载链接:温度助手下载链接


一、复位接收/发送计数器

在temperassistant.h的private slots:自动声明

    void on_pushButton_clicked();//复位接收/发送计数器

在temperassistant.h的public:手动声明接收字节数变量

    qint32 rxCount = 0;            // 接收字节计数

在temperassistant.c中写入代码。

/**
 * @brief TemperAssistant::on_pushButton_clicked 复位接收/发送计数器
 */
void TemperAssistant::on_pushButton_clicked()
{
    rxCount = 0;//清零
    txCount = 0;
    ui->lblrxCnt->setText(QString("%1").arg(rxCount));//在ui文本上显示0
    ui->lbltxCnt->setText(QString("%1").arg(rxCount));
}

二、串口接收数据程序

2.1 串口接收回调函数slots_serialRxCallback()

在temperassistant.h的public slots:手动声明

    void slots_serialRxCallback();//串口接收回调函数

在temperassistant.h的public:手动声明接收标志位和接收时间戳

    bool rxFlag = false ;//接收标志位
    QTime rxTimeStamp;          // 接收数据时间戳

在temperassistant.c中写入代码。

/**
 * @brief TemperAssistant::slots_serialRxCallback 接收函数处理
 */
void TemperAssistant::slots_serialRxCallback()
{
    rxFlag = true;//接收标志位为真
    rxTimeStamp = QTime::currentTime();//添加当前时间戳
}

2.2 串口接收插入时间戳insertTimeStramp(QByteArray &tmp)

在temperassistant.h的public:手动声明插入时间戳

    void insertTimeStramp(QByteArray &tmp);// 插入时间戳

 在temperassistant.c中写入代码。

/**
 * @brief TemperAssistant::insertTimeStramp 插入时间戳
 * @param tmp  在tmp前面插入接收时间戳
 */
void TemperAssistant::insertTimeStramp(QByteArray &tmp)
{
    QString currentTime = rxTimeStamp.toString("[hh:mm:ss.zzz]Rx:\r\n");//生成当前时间戳的格式
    tmp.prepend( currentTime.toLocal8Bit() );//将时间戳放到接收字节的前面
}

2.3 接收显示函数slots_rxDisplayTxt()

在temperassistant.h的public slots:手动声明接收数据处理函数

    void slots_rxDisplayTxt();//接收数据处理函数

在temperassistant.h的public:手动声明接收缓存

    QByteArray rxBuffer;           // 接收缓存

 在temperassistant.h的public:手动声明接收缓冲区大小

    qint32 rxBufSize = 1024*1024; // 1M buffer

在temperassistant.c中初始化函数中将接收缓冲区设置为设定大小。

    currentPort->setReadBufferSize(rxBufSize);//将QSerialPort的内部读取缓冲区的大小设置为rxBufSize大小字节。

 在temperassistant.h的public:手动声明ui定时更新时间

    QTimer txtFlashTime;        // ui定时更新

在temperassistant.c中初始化函数中将定时时间设置为10ms。

    txtFlashTime.start(10);//定时时间为10毫秒

并将其与接收显示函数关联 

    connect(&txtFlashTime,SIGNAL(timeout()),this,SLOT(slots_rxDisplayTxt()));

在temperassistant.c中写入代码。

/**
 * @brief TemperAssistant::slots_rxDisplayTxt 接收显示函数
 */
void TemperAssistant::slots_rxDisplayTxt()
{
    if(rxFlag)//如果接收标志位为真
    {
        disconnect(currentPort ,SIGNAL(readyRead()),this,SLOT( slots_serialRxCallback()));// 可读缓冲区有数据可用,启用接收数据回调
        QByteArray tmp = currentPort->readAll();//读取所有数据返回字节
        qDebug()<<"receive tmp:"<<tmp;
        /* 读取数据,empty代表没有再接收到数据 */
        if( tmp.isEmpty() )//如果接收字节数组为零,返回真
        {
            if(rxBuffer.isEmpty())return;//接收缓存为零,返回
            tmp = rxBuffer;//将接收缓存赋给返回的字节变量
            if(ui->chkDisplayHex->isChecked())//如果先择了HEX显示
            {
                tmp = tmp.toHex(' ').toUpper();//将字节转化为HEX格式并大写
            }
            QString str ;//定义字符串变量
            if(ui->checkBox_2->isChecked())//如果点击了增加时间戳
            {
                this->insertTimeStramp( tmp );//引用加入接收时间戳函数
                if( ui->rdbGB18030->isChecked() )//如果选择了GB18030显示方式
                {
                    QTextCodec *codec = QTextCodec::codecForName("GB18030");
                    str = codec->toUnicode(tmp);
                }
                else //否则显示UTF8显示格式
                {
                    str = QString::fromUtf8(tmp);
                }
                ui->textBrower->appendPlainText(str);
            }
            else//否则不加入时间戳
            {
                if( ui->rdbGB18030->isChecked() )
                {
                    QTextCodec *codec = QTextCodec::codecForName("GB18030");
                    str = codec->toUnicode(tmp);
                }
                else
                {
                    str = QString::fromUtf8(tmp);
                }
                ui->textBrower->insertPlainText(str);
            }
            if( txtStreamSave != NULL )
            {
                txtStreamSave->operator<<( str );
            }
            rxBuffer.clear();
            rxFlag = false;// 标记为false,只有在下一次触发readyRead信号的时候才会进入这里
            connect(currentPort, SIGNAL(readyRead()),this,SLOT( slots_serialRxCallback()));// 接收数据回调
        }
        else
        {
            rxBuffer.append(tmp);
            rxCount += tmp.size();//接收字符计数
            if( rxCount > rxBufSize )//如果接收计数大于定义的接收缓冲区1M Buffer,则全部清零
            {
                rxBuffer.clear();
                rxCount = 0;
            }
        }
    }
    ui->lblrxCnt->setText( QString::number(rxCount) );//显示接收字符数
}

注意:这么写入,在执行程序的时候由于接收标志位rxFlag = false,所以正常执行slots_rxDisplayTxt()是不会进入处理的,所以需要进行一个初始化配置。也就是需要将rxFlag = true,我们看到slots_serialRxCallback()

可以实现标志位的功能,并且只有当接收到数据的时候才会进入这个接收回调函数,我们将接收数据信号和接收回调函数用这个程序实现:

    connect(currentPort ,SIGNAL(readyRead()),this,SLOT( slots_serialRxCallback()));

而这句程序放在配置串口参数的configPort()函数中:如下

/**
 * @brief TemperAssistant::configPort配置端口的波特率\数据位\奇偶校验\停止位
 */
void TemperAssistant::configPort()
{
    QVariant tmpVariant;
    /* 设置波特率 */
    tmpVariant = ui->cbbBaud->currentData();  // 读取控件的当前项的值
    currentPort->setBaudRate(tmpVariant.value < BaseSerialComm::BaudRate > ()  );

    /* 设置数据位 */
    tmpVariant = ui->cbbDataBit->currentData();
    currentPort->setDataBits( tmpVariant.value <BaseSerialComm::DataBits > () );

    /* 设置校验位 */
    tmpVariant = ui->cbbVerify->currentData();
    currentPort->setParity (tmpVariant.value < BaseSerialComm::Parity > () );

    /* 设置停止位 */
    tmpVariant = ui->cbbStopBit->currentData();// 某些情况不支持1.5停止位
    if(currentPort->setStopBits (tmpVariant.value < BaseSerialComm::StopBits > () ) == false ){
        ui -> cbbStopBit->clear();
        BaseSerialComm::listStopBit ( ui -> cbbStopBit );
        QMessageBox::information(NULL, tr("不支持的设置"),  tr("该串口设备不支持当前停止位设置,已修改为默认的设置"), 0, 0);
    }
    currentPort->setDataTerminalReady(false);
    currentPort->setRequestToSend(false);
    connect(currentPort ,SIGNAL(readyRead()),this,SLOT( slots_serialRxCallback()));
    qDebug()<<"进入串口配置函数";
}

所以在打开串口按钮的程序中,我们打开串口,就配置了等待接收数据的信号,如果数据接收,则发送信号,直接关联到接收回调函数,使标志位rxFlag = true,

我们在初始化程序中用定时器不断定时进入slots_rxDisplayTxt()接收数据处理并显示槽函数。

具体流程如下:

三、清空接收文本框on_btnClear_clicked()

在temperassistant.h的private slots:自动声明清空接收文本函数

    void on_btnClear_clicked();//清空接收文本框

在temperassistant.c中写入代码。

/**
 * @brief TemperAssistant::on_btnClear_clicked 清空接收文本框和缓存
 */
void TemperAssistant::on_btnClear_clicked()
{
    ui->lblrxCnt->clear();
    ui->lbltxCnt->clear();
    ui->textBrower->clear();
    rxBuffer.clear();
    rxCount = 0;
    txCount = 0;
    ui->lblrxCnt->setText(QString("%1").arg(rxCount));
    ui->lbltxCnt->setText(QString("%1").arg(rxCount));
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米杰的声音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值