串口主从通信方式 QT主机实现

配合我的另外一篇从机做的主机,环境win10+QT5.10
widget文件:

#include "widget.h"
#include "ui_widget.h"
#include "spcomm.h"
#include<QtSerialPort/QSerialPortInfo>
#include<QMessageBox>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);


    //QStringList baudList ={"1200","2400","4800","9600","19200","38400","57600","115200"};
    QStringList baudList ={"115200"};
    ui->comboBoxBaud->addItems(baudList);
    ui->comboBoxBaud->setCurrentIndex(0);

    QStringList cmdList ={"0x01读源地址","0x02写源地址","0x03读目的地址","0x04写目的地址","0x05读IMEI","0x06读IOT端口IP",
                          "0x07写IOT端口IP","0x08读网络环境","0x09写网络环境","0x0a保存设置","0x0b恢复出场设置","0x0c读取产品编号","0x7f复位",
                          "0x10设置模拟量上传周期(分钟)","0x11读取模拟量上传周期"
                         };
    ui->comboBoxPort_cmd->addItems(cmdList);
    ui->comboBoxPort_cmd->setCurrentIndex(0);

    ui->textEdit->setReadOnly(true);
    ui->textEditRev->setReadOnly(true);
    ui->pushButton_search->setEnabled(true);
    ui->pushButton_save->setEnabled(true);
    ui->comboBoxPort_cmd->setEnabled(false);
    ui->pushButtonSend->setEnabled(false);

    ui->label_info_2->setStyleSheet("color:red");

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->comboBoxPort->addItem(serial.portName());
            serial.close();
        }
    }
    m_spcomm = new SPComm();

    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(timeOutProcess()));
    connect(m_spcomm->m_serialPort,SIGNAL(readyRead()),this,SLOT(readData()));//QObject::

    timerInfo = new QTimer(this);
    connect(timerInfo,SIGNAL(timeout()),this,SLOT(timeOutInfoProcess()));

    revBuf.reserve(128);

}

Widget::~Widget()
{
    delete m_spcomm;
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    ui->textEditRev->clear();
}

void Widget::on_pushButtonOpen_clicked()
{
    if(ui->pushButtonOpen->text()=="打开串口")
    {
        m_spcomm->setPortName(ui->comboBoxPort->currentText());
        m_spcomm->setBaudRate(ui->comboBoxBaud->currentText());

        if(m_spcomm->open())
        {
            ui->pushButtonOpen->setText("关闭串口");
            ui->pushButtonOpen->setStyleSheet("color:red");
            ui->comboBoxPort->setEnabled(false);
            ui->comboBoxBaud->setEnabled(false);
        }
        else
        {
            QMessageBox::information(NULL, "警告", "打开失败", QMessageBox::Yes , QMessageBox::Yes);
        }
    }
    else
    {
        m_spcomm->close();
        ui->pushButtonOpen->setText("打开串口");
        ui->pushButtonOpen->setStyleSheet("color:black");
        ui->comboBoxPort->setEnabled(true);
        ui->comboBoxBaud->setEnabled(true);
    }
}

void Widget::readData()
{
    QByteArray buf;
    buf = m_spcomm->m_serialPort->readAll();
    if(!buf.isEmpty())
    {
        if(ui->checkBox->isChecked())
        {
            revBuf.append(buf);
            timer->start(300);
        }
        else
        {

            QString str=QTextCodec::codecForName("GB2312")->toUnicode(buf);
            QString tt = ui->textEditRev->toPlainText();
            tt += str;
            ui->textEditRev->clear();
            ui->textEditRev->append(tt);
        }

    }
    buf.clear();
}


void Widget::timeOutInfoProcess(void)
{
    ui->label_info_2->clear();
}

void Widget::timeOutProcess(void)
{
    QByteArray &p=revBuf;
    int a,b,c;
    int size=revBuf.size();
    if(size>=5)
    {
       int crc16=SPComm::crc16Check(p,size);
       if(0==crc16)
       {

            switch(quint8(revBuf.at(1)))
            {
                case 0x81:
                case 0x83:
                {
                    QString info=m_spcomm->QByteArray2HexString(revBuf);
                    info = info.trimmed();
                    QString str = info.section(' ',3,8);
                    ui->textEditRev->append(str);
                }
                break;
                case 0x85:
                case 0x86:
                case 0x88:
                case 0x8c:
                {
                    char *a=revBuf.data();
                    QString str;
                    str=QString("%1").arg(a+3);
                    if(str.length()<1)
                    {
                       ui->textEditRev->append("空");
                    }
                    else
                    {
                        ui->textEditRev->append(str);
                    }
                }
                break;
                case 0x82:
                case 0x84:
                case 0x87:
                case 0x89:
                case 0x8a:
                case 0x8b:

                    ui->textEditRev->append("成功");
                break;
                case 0x90:
                    if(revBuf.at(3)==0)
                    {
                       ui->textEditRev->append("成功");
                    }
                    else
                    {
                        ui->textEditRev->append("失败");
                    }
                break;
                case 0x91:
                    a = revBuf.at(3);
                    b = revBuf.at(4);
                    c = a | b<<8;
                    ui->textEditRev->append(QString("周期: %1").arg(c));
                break;

                case 0xff:
                    ui->textEditRev->append("成功复位");
                break;

            }
        }

    }

    revBuf.clear();
}
void Widget::sendMsg(int msg,QByteArray payload)
{
    QByteArray data;         
    data.reserve(128);
    data[0]=0;
    data[1]=msg;
    data[2]=0;
    data.append(payload);
    data[0]=data.size()+2;
    data[2]=data.size()-3;
    QByteArray &p=data;

    int crc16 = SPComm::crc16Check(p,p.size());
    data.append(crc16&0xff);
    data.append(crc16>>8);


    if(m_spcomm->m_serialPort->isOpen())
    {
       m_spcomm->writeData(p);
       ui->textEdit->setText(m_spcomm->QByteArray2HexString(data));
       ui->label_info_2->setText("发送成功");
       timerInfo->start(1000);
    }
    else
    {
        QMessageBox::warning(0,tr("错误:"),QString("串口未打开"));
    }
}

void Widget::on_pushButtonSend_clicked()
{
    int index = ui->comboBoxPort_cmd->currentIndex();
    QString str=ui->lineEdit->text();
    int a;
    bool ok;
    QByteArray payload;
    payload.reserve(80);
    switch(index)
    {
    case 0:
        sendMsg(1,payload);
        break;
    case 1:
        payload = m_spcomm->HexString2ByteArray(str);
        if(payload.size()==6)
        {
            sendMsg(2,payload);
        }
        else
        {
            QMessageBox::warning(0,tr("错误:"),QString("应该是6个U8型Hex字符串"));
        }
        break;

    case 2:
        sendMsg(3,payload);
        break;
    case 3:
        payload = m_spcomm->HexString2ByteArray(str);
        if(payload.size()==6)
        {
            sendMsg(4,payload);
        }
        else
        {
            QMessageBox::warning(0,tr("错误:"),QString("应该是6个U8型Hex字符串"));
        }
        break;

    case 4:
        sendMsg(5,payload);
        break;

    case 5:
        sendMsg(6,payload);
        break;

    case 6:
        str=str.trimmed();
        str=str.simplified();
        if(str.length()>25)
        {
            QMessageBox::warning(0,tr("错误:"),QString("长度不符(0~25): \"%1\"").arg(str));
            return;
        }
        else
        {
            QString str1 ;
            str1 = QString("AT+NCDP=%s\r\n").arg(str);//180.101.147.115,5683
            str=str1;
        }
        payload.append(str+'\0');
        sendMsg(7,payload);
        break;

    case 7:
        sendMsg(8,payload);
        break;

    case 8:
        str=str.trimmed();
        str=str.simplified();
        if(str.length()>10||str.length()==10)
        {
            QMessageBox::warning(0,tr("错误:"),QString("长度不符(1~10): \"%1\"").arg(str));
            return;
        }
        else
        {
            QString str1 ;
            str1 = QString("AT+CGDCONT=1,\"IP\",\"%1\"\r\n").arg(str);
            str=str1;
        }
        payload.append(str+'\0');
        sendMsg(9,payload);
        break;

    case 9:
        sendMsg(10,payload);
        break;

    case 10:
        sendMsg(11,payload);
        break;

    case 11:
        sendMsg(12,payload);
        break;
    case 12:
        sendMsg(0x7f,payload);
        break;

    case 13:
        str=str.trimmed();
        str=str.simplified();

        a = str.toInt(&ok,10)&0xFFFF;
        if(ok)
        {
            if(a>0&&a<2001)
            {
                char c;
                c = a&0xff;
                payload.append(c);
                c = a>>8;
                payload.append(c);
                sendMsg(0x10,payload);
            }
            else
            {
               QMessageBox::warning(0,tr("错误:"),QString("范围1~2000"));
            }
        }
        else
        {
            QMessageBox::warning(0,tr("错误:"),QString("非法的16进制字符: \"%1\"").arg(str));
        }

        break;
    case 14:
        sendMsg(0x11,payload);
        break;


    default:break;
    }
}


void Widget::on_pushButton_search_clicked()
{
    QByteArray payload;
    payload.reserve(80);

    sendMsg(0x0d,payload);
}

void Widget::on_pushButton_save_clicked()
{
    QByteArray payload;
    payload.reserve(80);

    sendMsg(0x0e,payload);
}

void Widget::on_comboBoxPort_cmd_currentIndexChanged(int index)
{
    ui->pushButton_search->setEnabled(false);
    ui->pushButton_save->setEnabled(false);
    status = 0;
    switch(index)
    {
    case 0:
        ui->label_info->setText("");
    break;
    case 1:
        ui->label_info->setText("6个字节的源地址,hex字符,空格分隔");
    break;
    case 2:
        ui->label_info->setText("");
    break;
    case 3:
        ui->label_info->setText("6个字节的源地址,hex字符,空格分隔");
    break;
    case 4:
        ui->label_info->setText("模块唯一ID");
    break;
    case 5:
        ui->label_info->setText("IOT云服务器IP和端口号");
    break;
    case 6:
        ui->label_info->setText("IOT云服务器IP和端口号");
    break;
    case 7:
        ui->label_info->setText("当地电信物联网名字");
    break;
    case 8:
        ui->label_info->setText("当地电信物联网名字");
    break;
    case 9:
        ui->label_info->setText("保存所有写操作,掉电不消失");
    break;
    case 10:
        ui->label_info->setText("恢复出厂设置");
    break;
    case 11:
    break;
    case 12:
        ui->label_info->setText("复位重启");
    break;

    case 13:
        ui->label_info->setText("单位分钟,范围1~2000");
    break;
    case 14:
        ui->label_info->setText("单位分钟,范围1~2000");
    break;

    default:
        ui->label_info->setText("");
    break;
    }
}



void Widget::on_checkBox_stateChanged(int arg1)
{
    if(arg1 == Qt::Unchecked)
    {
        ui->pushButton_search->setEnabled(true);
        ui->pushButton_save->setEnabled(true);
        ui->comboBoxPort_cmd->setEnabled(false);
        ui->pushButtonSend->setEnabled(false);
    }
    else
    {
        ui->pushButton_search->setEnabled(false);
        ui->pushButton_save->setEnabled(false);
        ui->comboBoxPort_cmd->setEnabled(true);
        ui->pushButtonSend->setEnabled(true);
    }
}
完整包https://download.csdn.net/download/suxingtian/10431803
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值