QT连载3:基于QT和STM32H750的LORA试验平台(2)

7 篇文章 2 订阅

前言

      LORA平台已经可以使用了,可以正常的收发数据,当然这些东西都是基于1个H750的,没有试验两个750上相互传输是个什么情况,下一步准备做一下两个H750互传是否能完成同样的功能。先将试验平台的东西贴上来,看看小伙伴还有什么需求,如果有需求或者不明白的地方欢迎留言或者关注订阅号,在订阅号上留言,届时将积极回答。

平台硬件结构

     一个一个的连载吧,先说下QT上位软件吧。然后再介绍H750的LORA配置。

第一节:QT界面

      整体界面是这样的。一部分一部分的按照思路说。

    (1)界面的标题肯定得修改下,LORA调试,这个东西应该挺好弄。直接在main.c里面,加入title的标题,代码如下:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.setWindowTitle("LORA调试");
    w.show();
    return a.exec();
}

    (2)整体分为发送和接收两个部分,所以建立个一tab选项卡,1分为2,里面内容一致,直接复制粘贴就可以了。但是tab的字体和栏的大小必须改变下,具体代码如下:

    ui->MYTAB->move(0,0);
    ui->MYTAB->setTabText(0,"LORA发送端");
    ui->MYTAB->setTabText(1,"LORA接收端");

    ui->MYTAB->setCurrentIndex(0);
    QFont ft;
    ft.setPointSize(12);
    ui->MYTAB->setFont(ft);

    其中:设置0和1两个标签的名称,并且运行后第一个显示0标签。改变标签字体的大小,这个都是固定格式,直接复制粘贴就好。

    (3)串口设置。由于自己试验的话,波特率,停止位什么的都是固定的,所以这部分可以不要,仅仅添加一个串口号选项就好。代码如下:

    serialPortinfo1 = QSerialPortInfo::availablePorts();
    int count1 = serialPortinfo1.count();
    for(int i = 0; i<count1; i++)
    {
        ui->SPUPORT1->addItem(serialPortinfo1.at(i).portName());
    }

    首先,扫描可用串口,然后放入设计好的串口号下拉菜单就好。

    注:这部分只有打开软件的时候运行一次,所以串口转usb接口必须先接上,才能显示用的串口,如果先运行软件,后插入串口,这部分会检测不到可用的串口号。曾经试验过利用按钮来触发槽函数检索这部分。可以出现这个效果,但是会出现一个bug,就是点一次按钮,就会出现串口号的序列比如com1,再点一次,会再重复出现com1,串口号选项里出现两个com1。试验过怎么消除多余的那个,结果失败了,所以暂时没有用按钮扫描串口号。仅仅在打开软件的时候扫描下串口号。

    (4)按钮槽函数:这部分包含读取、保存还有其他按钮,直接设置槽函数就行。槽函数里面的内容下面再一一叙述。

    (5)发送窗口。

    问题:发送窗口,

    1. 输入只能从0到9,或者A到F,所以必须限定输入字符;

    2. 输入部分取值仅仅为字符,但是发送的时候需要16进制,所以需要将字符转化。

    解决办法:

    第一个:代码如下:

    QRegExp regx("[A-Fa-f0-9]{40}");
    QValidator *validator1 = new QRegExpValidator(regx, ui->LORA1SENDDATA);
    ui->LORA1SENDDATA->setValidator(validator1);
    QValidator *validator2 = new QRegExpValidator(regx, ui->LORA2SENDDATA);
    ui->LORA2SENDDATA->setValidator(validator2);

    至于为啥这样写,不知道,试验了,加入这个函数后,其他数据就不能输入了。如果需要其他字符,可以修改第一行里的内容。

    第二个:代码如下:

void MainWindow::on_LORA1SEND_clicked()
{
    uint8_t gngetdatalength = ui->LORA1SENDDATA->text().length();
    QByteArray  gsgetsenddata = ui->LORA1SENDDATA->text().toUtf8();

    uint8_t LORA1senddata[gngetdatalength];

    for(int i=0; i<gngetdatalength; i++)
    {
        LORA1senddata[i] = int(gsgetsenddata.at(i));

        if((LORA1senddata[i]>=48)&&(LORA1senddata[i]<=57))
            LORA1senddata[i] = LORA1senddata[i] - 48;
        if((LORA1senddata[i]>=65)&&(LORA1senddata[i]<=70))
            LORA1senddata[i] = LORA1senddata[i] - 55;
    }

    uint8_t LORA1sendDataBuffer[qCeil(gngetdatalength*0.5)];

    if(gngetdatalength%2 == 0)
    {

        for(int i=0; i<gngetdatalength*0.5; i++)
        {
            LORA1sendDataBuffer[i] = LORA1senddata[2*i+1]+16*LORA1senddata[2*i];
        }

    }
    else
    {
        for(int j=0; j<(gngetdatalength+1)*0.5-1; j++)
        {
            LORA1sendDataBuffer[j] = LORA1senddata[2*j+1]+16*LORA1senddata[2*j];
        }
        LORA1sendDataBuffer[int((gngetdatalength+1)*0.5-1)] = LORA1senddata[gngetdatalength-1];
    }
}

    一部分一部分的介绍:

    1. 取输入字符的长度和字符内容;

    2. for循环里:将字符赋值给另一个数组变量(变换一次需要定义一个数组,原因在前面文章里有详细介绍),并且将字符ASC码转化为16进制编码,这个可以看看ASCII的表,也就是减几个数,加几个数的逻辑。

    3.if和else语句:输入为单个的字符:AA,需要将AA字符转化为AA16进制,这是长度为2,需要除以2,才能组成一个byte,也就是一个0xFF,这样才能发送。

    所以当字符为AA(长度偶数)时,一种情况;当字符AAB(长度奇数)时,另一种情况。

    当为AA时,转化为16进制,并将第一个A乘以16,加第二个A,就能得到需要的16进制0xAA了;

    当为AAB时,AA处理方法和前面一样,后面的B,不作处理,直接按照0x0B处理。

    这样就将任意长度的字符串转为可以发送的16进制数据了。

  (6)接收窗口

        nRxAllLength = m1Serial.bytesAvailable();
        recvData.resize(50);
        recvData = m1Serial.readAll();

        for(int i=0; i<nRxAllLength; i++)
        {
            gnReceiveData[i] = recvData[i];
        }
        nRxHeadCheck_H    = gnReceiveData[0];
        nRxHeadCheck_L    = gnReceiveData[1];
        nRxDataLength     = gnReceiveData[2];
        uint8_t gnShowData[50];
        QString hexbigshow;
        for(int i=0; i<nRxDataLength; i++)
        {
            gnShowData[i] = gnReceiveData[i+3];
            QString hexsmall = QString("%1").arg(gnShowData[i], 2, 16, QLatin1Char('0')).toUpper();

            hexbigshow=hexbigshow+" "+hexsmall;
        }
        if(nRxHeadCheck_H == 3)ui->LORA2RECEIVEDATA->setText(hexbigshow);
        if(nRxHeadCheck_H == 4)ui->LORA1RECEIVEDATA->setText(hexbigshow);

    一部分一部分的解释:

    1. 取接收数据长度;

    2. 取接收数据;

    3. 放入另一个数组里;

    4. 根据接收协议,除去报头,将数据位放入字符串中,变为16进制显示,并且加入空格,然后加以显示。

    5.报头3和4对应接收和发送LORA的对话框。具体协议可以看看上篇文章。https://blog.csdn.net/weixin_45426095/article/details/119248641 《QT连载2:基于QT和STM32H750的LORA试验平台(1)》

    (7)其他函数

    这部分包含按钮下的槽函数,具体举例:

void MainWindow::on_LORA1TANS_clicked()
{
    ui->LORA1SEND->setEnabled(true);

    ui->LORA1ADDRSAVE->setEnabled(false);
    ui->LORA1BAUDSAVE->setEnabled(false);
    ui->LORA1SPEEDSAVE->setEnabled(false);
    ui->LORA1WORKMODESAVE->setEnabled(false);
    ui->LORA1TRANSMODESAVE->setEnabled(false);
    ui->LORA1CHANNELSAVE->setEnabled(false);
    ui->LORA1READINIT->setEnabled(false);

    ui->LORA1ADDRREAD->setEnabled(false);
    ui->LORA1BAUDREAD->setEnabled(false);
    ui->LORA1SPEEDREAD->setEnabled(false);
    ui->LORA1WORKMODEREAD->setEnabled(false);
    ui->LORA1TRANSMODEREAD->setEnabled(false);
    ui->LORA1CHANNELREAD->setEnabled(false);

    SLAVEADRESS_1 = 0x03;
    FUCTION_1     = 0x06;
    REGADRESS_1   = 0x00A5;
    REGNUM_1      = 0x0001;
    ModbusRTUSend_1(SLAVEADRESS_1,FUCTION_1,REGADRESS_1,REGNUM_1);
}

    这个是传输模式按钮点击的槽函数,先是禁用和使能按钮,不至于发生点击错误。然后根据通讯协议发送数值,最好是搞几个形参的函数,这样每次发送都可以调用这个函数,好看,意义清晰。具体发送函数:

int MainWindow::ModbusRTUSend_1(uint8_t SlaAdrtemp,uint8_t Fuctemp,uint16_t RegAdrtemp,uint16_t RegNumtemp)
{
    sendData_1.resize(8);
    sendData_1[0] = SlaAdrtemp;
    sendData_1[1] = Fuctemp;
    sendData_1[2] =(RegAdrtemp&0XFF00)>>8;
    sendData_1[3] = RegAdrtemp;
    sendData_1[4] =(RegNumtemp&0XFF00)>>8;
    sendData_1[5] = RegNumtemp;
    nTxVerify_1 = 0xFFFF;
    for(int i=0;i<6;i++)
    {
       nTxVerify_1 = GetCRC16_1(sendData_1[i], nTxVerify_1);
    }
    sendData_1[6] = nTxVerify_1;
    sendData_1[7] =(nTxVerify_1&0XFF00)>>8;

    m1Serial.write(sendData_1);
    return 0;
}

    解释:先将数据放入发送buffer,CRC校验,这个函数前述文章有介绍,然后执行write函数,这样数据就通过串口发送到H750了。

第二节:工具

    这样QT界面和QT下面的程序都已经编写完毕。点击相应按钮,串口发送写入的数据,达到发送和接收的目的。当然这里仅仅是QT的接口部分,剩下的是H750的处理和LORA的发送部分,这节将下面再连载叙述。

    使用虚拟串口工具和串口助手,就可以模拟具体串口发送和接收的数据了。当然都需要按照通讯协议去发和收。

    经过验证,点击某个按钮,串口助手接收到的数据符合自己的预期,就证明QT部分编写正确了。

总结

    这部分差不多和前面的一样,仅仅是在原有的基础上进行修改,大体框架都一致。有需要源代码的小伙伴可以关注订阅号,里面留言将发送源代码。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值