stm32 迴環結構接收串口數據並處理

使用stm32 通過串口對接一款數據採集終端,對終端發送一條指令,串口會返回不定量的數據,

剛開始使用串口接收中斷的方式處理數據,發現處理速度較慢,出現丟幀情況。

進而改成迴環結構接收數據。

typedef struct 
{
    short write_point;//寫指針
    u8 Reader_RX_Buffer_Second[4096];//存儲空間
    short read_point;//讀指針
    u8 loop;//如果寫指針到末端的時候,重頭開始寫表示

}READER_UART_REC_STRUCT_T;

串口接收方法:

void DEBUG_Reader_IRQHandler(void)
{

    u8_t res;        
    if(USART_GetITStatus(DEBUG_Reader, USART_IT_RXNE) != RESET)//接收到數據
    {         
        res =USART_ReceiveData(DEBUG_Reader);//;讀取接收到的數據USART2->DR
        
       
                if(reader_uart_rec_t.loop<1 && reader_uart_rec_t.write_point>=reader_uart_rec_t.read_point)
                {
                        reader_uart_rec_t.Reader_RX_Buffer_Second[reader_uart_rec_t.write_point++] = res;
                        if(reader_uart_rec_t.write_point == 4095)
                        {
                            reader_uart_rec_t.write_point = 0;
                            reader_uart_rec_t.loop = 1;
                        
                        }
                
                }else if(reader_uart_rec_t.write_point<reader_uart_rec_t.read_point)
                {
                
                        reader_uart_rec_t.Reader_RX_Buffer_Second[reader_uart_rec_t.write_point++] = res;
                }

        USART_ClearITPendingBit(DEBUG_Reader, USART_IT_RXNE);
    
    }                                       
}    

 

數據解析方法:

main()

{

//我的協議最小數據長度爲6   

     if(reader_uart_rec_t.write_point>(reader_uart_rec_t.read_point+5)  || reader_uart_rec_t.loop>0)
        {
     //數據處理方法
                 AnalyData(&reader_uart_rec_t);
        }

}

typedef struct 
{
    u8 head;    
    u8 len;    
    u8 address;    
    u8 cmd; 

}RECEIVE_EPC_DATA_HEAD_T;

void AnalyData(READER_UART_REC_STRUCT_T* reader_uart_rec)
{

       RECEIVE_DATA_HEAD_T  head;
    if(reader_uart_rec->loop == 1)
    {
        len = 4095+reader_uart_rec->write_point - reader_uart_rec->read_point;
    }else
    {
        len = reader_uart_rec->write_point - reader_uart_rec->read_point;
         
    }
        while(len>0)
        {
                        len--;
                        if(reader_uart_rec->read_point >= 4096)
                            {
                                reader_uart_rec->read_point = 0;
                                reader_uart_rec->loop = 0;
                            
                            }

//0xA0 是協議報頭   循環查找報頭,報頭不對則移動指針,正確則判斷符不符合協議頭,然後再處理數據
                        if(reader_uart_rec->Reader_RX_Buffer_Second[reader_uart_rec->read_point] == 0xA0)
                        {
                                
                                memcpy(&head,&reader_uart_rec->Reader_RX_Buffer_Second[reader_uart_rec->read_point],sizeof(RECEIVE_DATA_HEAD_T));
                            
                                switch(head.cmd)
                                {

                                    case 0x1:
                                           //處理數據
                                            if((reader_uart_rec->read_point+ head.len+2)>4095)
                                            {
                                                    reader_uart_rec->read_point = reader_uart_rec->read_point+ head.len+2-4095;
                                                    reader_uart_rec->loop = 0;
                                            }else
                                            {
                                                    reader_uart_rec->read_point = reader_uart_rec->read_point+ head.len+2;
                                            }
                                     
                                            len = len - head.len-1;
                                            break;

                                   
                                    default:
                                        
                                            reader_uart_rec->read_point++;//如果協議不在處理範圍,可能是錯誤數據或者出現了丟幀,則read下標後移
                                            break;
                                }
                        }else
                        {
                        //如果數據不符合包頭則read下標後移繼續找報頭
                            reader_uart_rec->read_point++;
                        
                        }
            }
        
            
        }

 

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