• qt 串口程序


    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QMessageBox>
    #include <QDebug>
    #include <QTimer>
    /***********************************全局变量***********************************/
    QDateTime current_date_time;   //获取当前时间
    //串口助手
    bool EnableTimeFlag;    //使能时间戳
    bool HexSendFlag;       //使能Hex发送
    bool HexRecvFlag;       //使能Hex接收
    bool RnSendFlag;        //使能回车换行
    bool SendDisplayFlag;   //发送回显
    //网口助手
    
    /****************************************************************************/
    
    MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        this->setWindowTitle("多功能调试助手");
        ui->lineEdit_STime->setText("1000");
        SerialSetInit();   //串口助手界面初始化
        NetworkInit();     //网口助手初始化
    
        ui->comboBox_ComType->addItem("UART");
        ui->comboBox_ComType->addItem("USB");
        ui->comboBox_ComType->addItem("TCP/IP");
    }
    
    
    // 串口设置界面初始化
    void MainWindow::SerialSetInit()
    {
         //使用foreach获取有效的串口信息
         foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
         {
             //这里相当于自动识别串口号之后添加到了cmb,如果要手动选择可以用下面列表的方式添加进去
             Serial.setPort(info);
             if(Serial.open(QIODevice::ReadWrite))
             {
                 //将串口号添加到cmb
                 ui->comboBox_Port->addItem(info.portName());
                 //关闭串口等待人为(打开串口按钮)打开
                 Serial.close();
             }
         }
        // 填充波特率
        QStringList Baud;
        Baud<<"1200"<<"2400"<<"4800"<<"9600"<<"19200"<<"38400"<<"115200";
        ui->comboBox_Baud->addItems(Baud);
        // 填充数据位
        QStringList DataBit;
        DataBit<<"5"<<"6"<<"7"<<"8";
        ui->comboBox_DataBit->addItems(DataBit);
        // 填充停止位
        QStringList StopBit;
        StopBit<<"1"<<"1.5"<<"2";
        ui->comboBox_StopBit->addItems(StopBit);
        // 填充效验位
        QStringList CheckBit;
        CheckBit<<"奇效验"<<"偶效验"<<"";
        ui->comboBox_CheckBit->addItems(CheckBit);
    
        //初始化默认参数
        ui->comboBox_Baud->setCurrentIndex(3); //默认9600
        ui->comboBox_DataBit->setCurrentIndex(3); //默认8bit Data
        ui->comboBox_StopBit->setCurrentIndex(0); //默认1bit Stop
        ui->comboBox_CheckBit->setCurrentIndex(2); //默认 无效验
    }
    
    // 网口助手界面初始化
    void MainWindow::NetworkInit()
    {
    
        ui->comboBox_StackType->addItem("UDP");
        ui->comboBox_StackType->addItem("TCP Server");
        ui->comboBox_StackType->addItem("TCP Client");
    
        ui->lineEdit_NetPort->setText("8080");
    
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    //串口打开和关闭按钮
    void MainWindow::on_pushButton_Open_clicked()
    {
        //设置串口号;也就是说打开的是当前显示的串口
        if(ui->comboBox_Port->currentText().isEmpty())
        {
            QMessageBox::information(this,"提示","没有可用的串口");
            return;
        }
        Serial.setPortName(ui->comboBox_Port->currentText());
        if(ui->pushButton_Open->text() == "打开串口")
        {
               if(Serial.open(QIODevice::ReadWrite))//读写方式打开,成功后设置串口
               {
                   //设置波特率
                   Serial.setBaudRate(ui->comboBox_Baud->currentText().toInt());
    
                   //设置数据位
                   switch(ui->comboBox_DataBit->currentText().toInt())
                   {
                         case 5:
                                 Serial.setDataBits(QSerialPort::Data5);
                         break;
                         case 6:
                                 Serial.setDataBits(QSerialPort::Data6);
                         break;
                         case 7:
                                  Serial.setDataBits(QSerialPort::Data7);
                         break;
                         case 8:
                                  Serial.setDataBits(QSerialPort::Data8);
                         break;
                         default:
                                  QMessageBox::information(this,"提示","数据位配置出错");
                                  return;
                         break;
                   }
    
                   //设置校验位
                   if (ui->comboBox_CheckBit->currentText() == "奇效验")
                   {
                       Serial.setParity(QSerialPort::OddParity);
                   }
                   else if (ui->comboBox_CheckBit->currentText() == "偶效验")
                   {
                       Serial.setParity(QSerialPort::EvenParity);
                   }
                   else if (ui->comboBox_CheckBit->currentText() == "")
                   {
                       Serial.setParity(QSerialPort::NoParity);
                   }
    
                   //设置停止位
                   if (ui->comboBox_StopBit->currentText().toFloat() == 1)
                   {
                       Serial.setStopBits(QSerialPort::OneStop);
                   }
                   else if(ui->comboBox_StopBit->currentText().toFloat() == 1.5)
                   {
                       Serial.setStopBits(QSerialPort::OneAndHalfStop);
                   }
                   else if(ui->comboBox_StopBit->currentText().toFloat() == 2)
                   {
                       Serial.setStopBits(QSerialPort::TwoStop);
                   }
    
                   //设置流控制
                   Serial.setFlowControl(QSerialPort::NoFlowControl);
                   ui->pushButton_Open->setText("关闭串口");
    
    
                   //建立串口接收的槽函数
                   connect(&Serial,&QSerialPort::readyRead ,this,&MainWindow::ReadRecData);
    
                  // timer0->start(100);
    
                }
               else//串口打开失败
               {
                   QMessageBox::about(NULL, "提示", "打开出错,串口被占用!");
                   return ;
               }
        }
        else if(ui->pushButton_Open->text() == "关闭串口")
        {
    
            Serial.close();//关串口
            ui->checkBox->setChecked(false);
            on_checkBox_clicked(false);
            ui->pushButton_Open->setText("打开串口");
        }
    }
    
    void MainWindow::Delay_MSec(unsigned int msec)
    {
        QTime _Timer = QTime::currentTime().addMSecs(msec);
    
        while( QTime::currentTime() < _Timer )
    
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    
    // 串口接收数据
    void MainWindow::ReadRecData()
    {
        Delay_MSec(100);
        QByteArray readData = Serial.readAll();//读取串口数据
        QByteArray NewData;
        QString current_date;
    
       if(!readData.isNull())//将读到的数据显示到数据接收区
       {
           if(HexRecvFlag)  //判断是否使用HEX
           {
               //判断是否使用时间戳
               if(EnableTimeFlag == 1)
               {
                   current_date_time = QDateTime::currentDateTime();
                   current_date += "[";
                   current_date += current_date_time.toString("yyyy-MM-dd hh:mm:ss");
                   current_date += "]收->";
                   ui->textEdit_Recv->append(current_date.toUtf8() + readData.toHex());
               }
               else
               {
                  ui->textEdit_Recv->append(readData.toHex());
               }
    
           }
           else
           {
               //判断是否使用时间戳
               if(EnableTimeFlag == 1)
               {
                   current_date_time = QDateTime::currentDateTime();
                   current_date += "[";
                   current_date += current_date_time.toString("yyyy-MM-dd hh:mm:ss");
                   current_date += "]收->";
                   ui->textEdit_Recv->append(current_date.toUtf8() + readData);
               }
               else
               {
                   ui->textEdit_Recv->append(readData);
               }
           }
    
       }
    }
    
    //清除接收窗口数据
    void MainWindow::on_pushButton_ClearRecv_clicked()
    {
       ui->textEdit_Recv->clear();
    }
    
    //清除发送窗口数据
    void MainWindow::on_pushButton_2_clicked()
    {
       ui->textEdit_Send->clear();
    }
    
    
    //将一个字符串转换成十六进制
    QByteArray MainWindow::QString2Hex(QString str)
    {
        QByteArray senddata;
        int hexdata,lowhexdata;
        int hexdatalen = 0;
        int len = str.length();
        senddata.resize(len/2);
        char lstr,hstr;
        for(int i=0; i<len; )
        {
            hstr=str[i].toLatin1();
            if(hstr == ' ')
            {
                i++;
                continue;
            }
            i++;
            if(i >= len)
            break;
            lstr = str[i].toLatin1();
            hexdata = ConvertHexChar(hstr);
            lowhexdata = ConvertHexChar(lstr);
            if((hexdata == 16) || (lowhexdata == 16))
                break;
            else
                hexdata = hexdata*16+lowhexdata;
            i++;
            senddata[hexdatalen] = (char)hexdata;
            hexdatalen++;
        }
        senddata.resize(hexdatalen);
        return senddata;
    }
    
    
    char MainWindow::ConvertHexChar(char ch)
    {
        if((ch >= '0') && (ch <= '9'))
            return ch-0x30;
        else if((ch >= 'A') && (ch <= 'F'))
            return ch-'A'+10;
        else if((ch >= 'a') && (ch <= 'f'))
            return ch-'a'+10;
        else return (-1);
    }
    
    //发送数据
    void MainWindow::on_pushButton_Send_clicked()
    {
        QString DataStr;
        QString NewData;
        QString current_date;
    
        DataStr = ui->textEdit_Send->toPlainText();
        if(ui->pushButton_Open->text() == "打开串口")
        {
           QMessageBox::information(this,"提示","未打开串口");
           return;
        }
        qDebug() << "push button
    ";
        printf("push button 
    ");
        if(HexSendFlag)        //使能Hex发送时
        {
            QStringList strList = DataStr.split(" ", QString::SkipEmptyParts);  //
            QByteArray str_send;
    
            for(int i = 0;i < strList.size(); i++)
            {
                str_send += QString2Hex(strList[i]);
            }
    
           ui->checkBox_SendRN->setChecked(false);
           if(EnableTimeFlag)  //判断是否使能时间戳
           {
               current_date_time = QDateTime::currentDateTime();
               current_date += "[";
               current_date += current_date_time.toString("yyyy-MM-dd hh:mm:ss");
               current_date += "]发->";
               NewData = current_date + DataStr;
                if(SendDisplayFlag == 1)
               {
                   ui->textEdit_Recv->append(NewData);
               }
           }
           else
           {
              NewData = DataStr;
              if(SendDisplayFlag == 1)
              {
                  ui->textEdit_Recv->append(NewData);
              }
           }
           Serial.write(str_send);//写入缓冲区
        }
        else           //不使能Hex发送时
        {
            if(EnableTimeFlag)  //判断是否使能时间戳
            {
                current_date_time = QDateTime::currentDateTime();
                current_date += "[";
                current_date += current_date_time.toString("yyyy-MM-dd hh:mm:ss");
                current_date += "]发->";
                NewData = current_date + DataStr.toUtf8();
                if(SendDisplayFlag == 1)
                {
                    ui->textEdit_Recv->append(NewData);
                }
            }
            else
            {
               NewData = DataStr;
               if(SendDisplayFlag == 1)
               {
                   ui->textEdit_Recv->append(NewData);
               }
            }
            Serial.write(DataStr.toUtf8());//写入缓冲区
        }
    
    }
    
    //使能时间戳
    void MainWindow::on_checkBox_EnableTime_clicked(bool checked)
    {
         if(checked == true)
         {
             EnableTimeFlag = 1;
         }
         else
         {
             EnableTimeFlag = 0;
         }
    }
    //使能定时发送
    void MainWindow::on_checkBox_clicked(bool checked)
    {
        if(checked == true)
        {
            if(ui->pushButton_Open->text() == "打开串口")
            {
               QMessageBox::information(this,"提示","未打开串口");
               ui->checkBox->setChecked(false);
               return;
            }
            quint32 stime= ui->lineEdit_STime->text().toInt();
            timer_id1 = startTimer(stime);
            ui->lineEdit_STime->setEnabled(false);
        }
        else
        {
           killTimer(timer_id1);
           ui->lineEdit_STime->setEnabled(true);
        }
    }
    
    // HEX 接收 按钮
    void MainWindow::on_checkBox_HexRecv_clicked(bool checked)
    {
        if(checked)
        {
            HexRecvFlag = 1;
        }
    
        else
            HexRecvFlag = 0;
    }
    // HEX 发送 按钮
    void MainWindow::on_checkBox_HexSend_clicked(bool checked)
    {
        if(checked)
            HexSendFlag = 1;
        else
            HexSendFlag = 0;
    }
    //发送新行 按钮
    void MainWindow::on_checkBox_SendRN_clicked(bool checked)
    {
        if(checked)
            RnSendFlag = 1;
        else
            RnSendFlag = 0;
    }
    
    //发送回显 按钮
    void MainWindow::on_checkBox_SendDisplay_clicked(bool checked)
    {
        if(checked)
            SendDisplayFlag = 1;
        else
            SendDisplayFlag = 0;
    }
    
    //定时器中断
    void MainWindow:: timerEvent(QTimerEvent *ev)
    {
        if(ev->timerId() == timer_id1)
        {
           on_pushButton_Send_clicked();
        }
    }
    
    
    void MainWindow::on_pushButton_FlushPort_clicked()
    {
        ui->comboBox_Port->clear();  //清除串口下拉列表内容
        //使用foreach获取有效的串口信息
        foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
           //将串口号添加到cmb
           ui->comboBox_Port->addItem(info.portName());
        }
    }

    github 地址  https://github.com/itachi1121/serial-qt.git

    如果打不开串口,可能是权限不够

    sudo chmod 666 /dev/ttyUSB0(串口名字)

    再重新打开试试

    想添加永久权限,方法如下:

    1 查看串口信息

    $ ls -l /dev/ttyUSB0
    crw-rw---- 1 root dialout 4, 64 Jun  2 18:39 /dev/ttyUSB0

    2 查看当前用户名

    $ whoami



    3 当前用户加入到dialout用户组

    sudo usermod -aG dialout username


    4 最后重启系统即可

    Talk is cheap, show me the code
  • 相关阅读:
    LeetCode OJ-- LRU Cache ***@
    LeetCode OJ-- Maximal Rectangle ***@
    LeetCode OJ-- Maximum Subarray @
    LeetCode OJ--Merge Intervals @
    导出你的GAC Assembly中的DLLS -- 金大昊(jindahao)
    Unity3d学习日记(六)
    如何不冲会员高速下载百度网盘上的资源
    3dContactPointAnnotationTool开发日志(三四)
    3dContactPointAnnotationTool开发日志(三三)
    3dContactPointAnnotationTool开发日志(三二)
  • 原文地址:https://www.cnblogs.com/birdBull/p/14376950.html
Copyright © 2020-2023  润新知