QT串口动态实时显示大量数据波形曲线(五)========“最终完美解决版”

前言

最近忙着学习linux的嵌入式开发,QT的开发暂时告一段落,所以完美解决的程序也没有编写,现在抽出时间对前面的QT串口动态实时显示大量数据波形程序又加工了下,希望能帮助从事单片机而又不熟悉QT的小伙伴。

先总结下QT的最终感受:

(1)能用别人编写好的模板就用模板,能省下来不少时间;

(2)能用全局变量就用变量,方便。最重要的是能看这篇文章的大部分都是搞单片机的,不是搞嵌入式显示的,所以思维逻辑一时半会也改不过来,按照以前的思维方式比较舒服;

(3)想快速出东西,不用知道具体代码什么意思,知道怎么用就行。QT和while(1)的程序不一样,都是一块一块的,知道一个功能,改吧改吧就行,能输出自己想要的就行。

第一章:程序思路介绍

串口接收程序

此部分分为两部分,(1)数据接收,(2)数据处理。

    先说数据接收:20ms接收一次,不管接收多少东西,只要在20ms的特定波特率能接收的最大数据之内就好,也就是能接收到全部数据。直接上程序:

void MainWindow::receive_20ms()
{
    int nRxAllLength;
    QByteArray recvData;
    recvData.resize(256);
    uint8_t gnReceiveData[256];

    nRxAllLength = m_serial->bytesAvailable();
    recvData = m_serial->readAll();
    for(int i=0; i=UART_RX_BUF_SIZE)	nUartRxBufHead=0;
        if(nUartRxBufHead==nUartRxBufTail)
        {
            nUartRxBufTail++;
            if(nUartRxBufTail>=UART_RX_BUF_SIZE)	nUartRxBufTail=0;
        }
    }
}

    代码功能:接收数据,并且放到一个fifo里面,接收多少,把fifo开大点,接收一个别覆盖原来的数据就行,反正电脑上运行,随便开。如果需要精简内存,那没办法,需要自己算算开多大合适。

    再说处理程序:1ms处理一次。为啥1ms,2ms也是可以的,只要比20ms小就行,最好越快处理越好,但是不能处理不过来。

    存在问题:1ms在嵌入式里面不是不能正确定时么?差不多就行,1ms左右就行,只要能在短时间内执行就行。不用特别精确的时间,这个自己估量就行。反正线程处理的时间都是大概的时间,不用太在意这个。除非你要非常精确的时间输出或者输入,那没办法。还是直接上程序:

void MainWindow::dealdata_1ms()
{
    nUartRxLengthTemp = nUartRxBufHead - nUartRxBufTail;
    if( nUartRxLengthTemp < 0 ) 
    {
        nUartRxLengthTemp = nUartRxLengthTemp+ UART_RX_BUF_SIZE;
    }
    switch( nUartRxCtrlMode )
    {
        case MODE_UARTRXCMD_WAIT:
            if(nUartRxLengthTemp >= 2)//报头为两个byte,先检测报头
            {
                nUartRxHeadCheck = UartRdCharRxBuff();
                if(nUartRxHeadCheck == 0x5A)          //保证解析的前两个字节时5AA5
                {
                    nUartRxHeadCheck = UartRdCharRxBuff();
                    if(nUartRxHeadCheck == 0xA5)
                    {
                        nUartRxCtrlMode = MODE_UARTRXCMD_FRAME;
                    }
                }
            }
        break;
    case MODE_UARTRXCMD_FRAME:
        if(nUartRxLengthTemp >= 14)//数据帧14个字节,根据自己需要变化
        {
            for (int i=0;i<14;i++)
            {
               gnUartRxDataBuffer[i] = UartRdCharRxBuff();
            }

            数据处理程序代码;
            gnLatchCnt++;
            if(gnLatchCnt == 8)//8个点存储一次,根据需要多少个点显示存储多少次
            {
                gnUartRxRecDoneFlag = 1;
            }
            nUartRxCtrlMode = MODE_UARTRXCMD_WAIT;
        }
    break;
        default:
            nUartRxCtrlMode = MODE_UARTRXCMD_WAIT;
        break;
    }
}

    代码功能:(1)从接收的数据里面寻找报头5AA5,这个根据自己的数据定,只要能找到就行,找不到就抛掉,知道找到开始的5AA5。(2)找到后处理剩余14数据,14是我自己的剩余数据,也就是说每帧数据一共16个字节,前两个是报头,后面的数据是自己需要显示的数据。

    注意:这里需要说一个习惯,每次处理数据最好用buffer缓存下,第一个功能防止被覆盖,第二个是可以随时加入其它程序,变换一步最好放入一个新的数组里。

    缓存8帧数据(8个点)之后,出来一个flag,用来显示数据标志。这个看你自己想要多少个点显示一次,因为是用串口助手发的数据,所以8个点差不多了,如果用单片机的数据,这个随便改。

波形处理程序

    波形处理程序就比较简单了,直接上代码:

void ampshow::dealdata_5ms()
{
    if(gnUartRxRecDoneFlag == 1)
    {
        ui->PLOTVAMP->graph(0)->setData(gvUTCms,gvVsuAmp);
        ui->PLOTVAMP->graph(1)->setData(gvUTCms,gvVsvAmp);
        ui->PLOTVAMP->graph(2)->setData(gvUTCms,gvVswAmp);
        ui->PLOTIAMP->graph(0)->setData(gvUTCms,gvIsuAmp);
        ui->PLOTIAMP->graph(1)->setData(gvUTCms,gvIsvAmp);
        ui->PLOTIAMP->graph(2)->setData(gvUTCms,gvIswAmp);
        ui->PLOTVAMP->replot();
        ui->PLOTIAMP->replot();

        gnUartRxRecDoneFlag = 0;
    }
}

接收里面1ms处理一次,这个5ms更新一次,当flag变化后,这边开始描点,就可以正确显示了。

第二章:效果

    先上报文:随便发,5AA5是报头,0001到0008变化是时间,一共8次。后面是显示数据。根据自己的需要自己变化。

5AA50001000100020003000400050006
5AA50002000100020003000400050006
5AA50003000100020003000400050006
5AA50004000100020003000400050006
5AA50005000100020003000400050006
5AA50006000100020003000400050006
5AA50007000100020003000400050006
5AA50008000100020003000400050006

效果图:

QT串口动态实时显示大量数据波形曲线(五)========“最终完美解决版”_第1张图片

 第三章:测试

    用串口助手测试接收数据,试过每次发100个数据,每10ms发一次,串口都可以正确接收。并且可以正确显示。

第四章:写在最后

    需要代码的小伙伴可以加公众号,完整代码将放在百度网盘中,可自行下载,如有问题可在公众号中私信,届时会一一解答。

QT串口动态实时显示大量数据波形曲线(五)========“最终完美解决版”_第2张图片

你可能感兴趣的:(ARM,串口,QT,qt,开发语言)