解决51,stm32 Qt qt serial串口接收问题

1、解决串口分包问题。即本来接收串口数“1122334455”,被分成了112233和4455两帧数据。

2、解决串口数据长度不固定,且没有规律,没有包头,没有包尾等。

3、发送两帧数据的间隔必须超过设置的超时时间。我一般用5ms的超时时间,所以只要两帧数据发送间隔超过5ms,都能被解析出来。

4、主要是交流学习,如果有什么疑问一起讨论学习,看完有帮助,请点赞,我会分享更多的东西。

解决思路:
当串口数据来了,会触发一个接收中断函数。我们再接收函数里面将数据接收下来,并在这个启动一个定时器,并刷新定时器。
如果定时时间到了,说明数据接收完毕了。

代码理解:(主要是为了更好的理解思路就列出主要代码,思路还是比较简单的。但是这个确实解决了一件令你头疼的事情)

//stm32f1代码
#define   dataLength   255    //串口数据最大长度
struct usartData
{
        unsigned  char  data[dataLength];  //串口数据
        unsigned  char  count;             //数据计数
        unsigned  char  flag;              //接收完毕一帧数据
        unsigned  char  overtime;          //计时
};

void  main(void)
{
    USART_Config();
    TIM5_Configuration(); //1ms定时器
    while(1)
    {
     msgDebug();  //消息处理
    }
}


void  USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
    {
             //这样就ok了,设置time 接收数据,接下来看 定时器中断处理
            usart1_UP.overtime =1;
            usart1_UP.data[usart1_UP.count++] = USART_ReceiveData(USART1);            
            if(usart1_UP.count > 255)
            {
                usart1_UP.count    =0;
                usart1_UP.overtime =0;
            }
    }
}

void TIM5_IRQHandler(void) //1ms
{
  if ( TIM_GetITStatus(TIM5 , TIM_IT_Update) != RESET )
  { 
            TIM_ClearITPendingBit(TIM5 , TIM_FLAG_Update);     
            if(usart1_UP.overtime)
            {
                    if(usart1_UP.overtime++ > 5)
                    {
                            usart1_UP.overtime =0;
                            usart1_UP.flag =1;
                            USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
                    }
            }
    }
}

void msgDebug(void)
{
        if(usart1_UP.flag)
        {
            usart1_UP.flag =0;
            //这里处理数据吧usart1_UP.data
            
            //清除数据
            memset(usart1_UP.data,0,usart1_UP.count);
            usart1_UP.count  =0;
            USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        }
}

51代码

//串口初始化
void Uart1_Init(void);
//配置一个1ms的定时器
void Timer2Init(void);

/*usart
  串口接收结构体
  rxFlag: 1 表示接收到一帧数据
  rxTime;超时变量
  rxCount 接收数据的长度最多如果数据大于255重新定义
  rxBuff[255] 接收到的数据
*/

struct usart_s 
{
        unsigned char  rxFlag;
        unsigned char  rxTime;
        unsigned char  rxCount;
        unsigned char  rxBuff[30];
};


//串口接收中断
void Uart1() interrupt UART1_VECTOR using 1
{
    ES =0;
    if(RI)
    {
        //这样就ok了,设置time 接收数据,接下来看 定时器中断处理
        myUat1.rxTime =1; 
        myUat1.rxBuff[myUat1.rxCount++] = SBUF;
    }
    else
    {
    }
    if(TI)
    {
        TI = 0;
    }
    ES =1;
}
//1ms定时器中断函数
void TIM2_IRQHandler()  interrupt TIMER2_VECTOR using 1
{    
        if(myUat1.rxTime)
        {
                if(myUat1.rxTime++ > 5)
                {
                        myUat1.rxTime =0;
                        myUat1.rxFlag =1; //接收完毕一帧数据
                }
        }
}


//主函数
void main(void)
{
    Uart1_Init();
    Timer2Init();
    while(1)
    {
        if(myUat1.rxFlag)
        {
            myUat1.rxFlag=0;
            //这里就可以处理接收的数据myUat1.rxBuff,最后记得清除数据
            
        }
    
    }

}
 

//QT部分代码

QByteArray myBuf; //接收的数据
void QtWeight3::Read_Data()
{
    QByteArray buf;
    buf   = serial->readAll();
    myBuf += buf;
    myTimer2->start(50); 
    qDebug() << "shoudao";
}

//定时器时间50ms到了会执行该函数
void QtWeight3::TimerUpdate_COM()
{    
    myTimer2->stop();
    qDebug() << myBuf;
    //这里处理接收完整的数据myBuf
        
    myBuf.clear();//处理完毕了记得情况buf
    qDebug() << "timeout";
}

你可能感兴趣的:(stm32)