如何實現Qt上位機軟件串口的按字節數據處理?

1.Qt串口類的選擇

最近在做一個小項目,需要用到Qt做上位機軟件,本人也是邊學邊做,買了本《QtCreator快速入門》看了看就動手了,由於初學不是很瞭解Qt5的官方資源,一開始串口開發使用的是第三方串口類QExtSerialPort,但是後來發現這個第三方串口類似乎不提供串口信息的查詢,就果斷放棄了。
同時也發現Qt5本身是提供串口類的,所以就用了官方資源,官方的串口類是提供串口信息查詢,也就可以實現上位機軟件的的串口號查找功能了,人性化很多。

2.如何實現Qt上位機軟件串口的按字節數據處理?

這部分我在網上找了許多資料都不太管用,一些常見的學習資料,基本上都是說,在槽函數裏使用QByteArray類型變量直接讀出串口對象的全部數據,資料範例如下:

void Widget::readMyCom() //讀取串口數據並顯示出來
{
   
   
	QByteArray temp = myCom->readAll();
	//讀取串口緩衝區的所有數據給臨時變量 temp
	ui->textBrowser->insertPlainText(temp);
	//將串口的數據顯示在窗口的文本瀏覽器中
}

在我這個項目裏,需要從STM32(下位機)的串口接收6字節長度的數據,然後上位機軟件接收數據,再做進一步處理工作。 顯然上面的方法不適合,因爲以上讀出來的數據是一個流式文本,時長時短,不好控制長度。經過我仔細地檢索信息,功夫不負有心人,終於找到了解決辦法,大家可以參考這個知乎問答:

https://www.zhihu.com/question/46717728?sort=created

3.我的例子

首先是下位機部分,我這裏測試時是在定時器更新中斷中完成串口發送的,代碼如下:

char num = 0;
int SHU = 0;
char DataBuff[6]={
   
   0x00};
float i = 0.0;
void TIM2_IRQHandler( void )
{
   
   
	if( TIM_GetITStatus( TIM2,TIM_IT_Update )!= RESET )
	{
   
   
		TIM_ClearITPendingBit( TIM2,TIM_IT_Update );
		
		SHU = i*100;//取四個整數和兩個小數,i放大100倍,方便取小數
		//注意取出來的數必須加0x30
		//要以字符的形式發送纔行,上位機軟件纔可以用qDebug()打印出來
		DataBuff[0] =     SHU/100000+0x30;
		DataBuff[1] = (   SHU%100000)/10000+0x30;
		DataBuff[2] = ((  SHU%100000)%10000)/1000+0x30;
		DataBuff[3] = ((( SHU%100000)%10000)%1000)/100+0x30;
		DataBuff[4] = ((((SHU%100000)%10000)%1000)%100)/10+0x30;
		DataBuff[5] = ((((SHU%100000)%10000)%1000)%100)%10+0x30;
		
		USART1->SR;//空讀SR,避免硬件上電後,首字節發送丟失
		for( num=0;num<6;num++ )
		{
   
   
			USART_SendData( USART1,DataBuff[num]);
			while( USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET );
			USART_ClearFlag( USART1,USART_FLAG_TC );
		}
		if(i==1500) i=0;
		else i++;
	}
}

再是Qt上位機軟件的信號和槽函數連接:

//連接信號至槽函數:串口有數據就讀串口
connect(mycom,SIGNAL(readyRead()),this,SLOT(MyReadData()));

最後是槽函數和打印信息:

char DataBuff[6] = {
   
   0x00};//在類中定義
unsigned char cnt = 0;    //在類中定義
float distance = 0.0;     //在類中定義
void MainWindow::MyReadData( void )
{
   
   
    char ch = 0;
    while( mycom->read(&ch,1) )
    {
   
   
        DataBuff[cnt] = ch;
        cnt++;
        if( cnt == 6 )
        {
   
   
            cnt = 0;
            distance = (DataBuff[0]-0x30)*1000+(DataBuff[1]-0x30)*100+(DataBuff[2]-0x30)*10+
                       (DataBuff[3]-0x30)+     (DataBuff[4]-0x30)*0.1+(DataBuff[5]-0x30)*0.01;
            qDebug("%4.2f",distance);
            qDebug()<<DataBuff;
        }
    }
}

調試信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章