串列埠接收完整一幀資料報的3種方法

2021-10-07 12:15:43 字數 2207 閱讀 1298

本文介紹3種使用串列埠接受一幀完整資料報的方法,串列埠接收資料是位元組接收的,串列埠每接收1位元組資料,產生乙個串列埠中斷,我們在中斷中將接收到的資料存放到buf中進行儲存,但是資料的傳送和接收都是按照幀為單位進行傳輸的,因此我們要在接收資料的同時判斷當前接收的資料是否是完整的一幀。

一般串列埠完整資料幀的定義:幀頭(2位元組,例如aa、bb) +  資料長度(2位元組) + 資料 + crc16校驗(2位元組)  +  幀尾(2位元組)

幀頭、幀尾表示一幀資料的開始和結尾,資料長度表示當前資料幀中負載資料大小,crc16校驗用來檢查接收到的資料是否正確。

第一種方法(根據幀頭、幀尾進行判斷):

串列埠在接收資料時,我門在串列埠中斷函式中對接收到的每一位元組資料進行判斷,如果檢測到幀頭資料(例如aa、bb),我們開始將接收到的資料存到buf中,同時記錄下該幀資料的資料長度字段,然後一直接收,直到接收到的資料長度與我們記錄下的資料長度字段值一致或接收到幀尾資料,到此一幀資料接收完成,將資料扔到訊息佇列,等待任務處理即可。

假如接收的資料報格式如下  幀頭(aa 、bb) + 資料長度 + 資料  + crc校驗 + 幀尾(cc、dd) 

void usart1_irqhandler(void)              //串列埠中斷處理函式  }

else

}      

if(buf_size  >=  buf_size)}} 

第二種方法(根據接收到的字元之間的間隔進行判斷):

串列埠數傳輸都是使用標準波特率,因此串列埠傳輸一幀資料時,字元與字元之間的時間間隔是乙個固定值,我們可以根據串列埠的波特率去計算串列埠每個字元的間隔時間,在資料接收的過程中判斷當字元間隔大於3.5個(modbus協議常用),則認為當前資料幀傳輸完畢,具體方法如下:

我們先設定定時器超時時間為計算出的3.5字元間隔時間,然後在串列埠中斷中每接收到乙個字元,就將其儲存至buf中,並重新整理定時器計數值,如果串列埠接收到的資料時間間隔大於3.5個字元間隔,定時器就會進入超時中斷,我們在定時器中斷中判斷當前buf中的資料是否完整,如果完整,則扔到訊息佇列中,等待任務去處理。

//本例中,如果串列埠字元間隔大於3ms,我們認為一幀資料接收完畢,如果使用的協議是modbus 協議,則時間間隔應該設定為3.5字元間隔時間。

#define   buf_size      128     // 定義串列埠接收buf 長度

typedef enum ;   //定義列舉型別

u16   buf_size  = 0;

u8    buf[buf_size] = ;     //定義串列埠接收快取區

u16 timercount  = 0;

u8  timerenable = enable;      //定義定時器計數使能標誌位

void usart1_irqhandler(void)              //串列埠中斷處理函式}} 

void tim1_irqhandler(void)        //定時器中斷處理函式  每1ms產生一次中斷}}

} 串列埠idle中斷,串列埠接收完完整的一幀資料自身產生的中斷,配置使能該中斷後,串列埠會判斷匯流排上乙個位元組的時間間隔內有沒有再次接收到資料,如果沒有則當前一幀資料接收完成,產生idle中斷。

使用方法,原串列埠配置不變,新增下列語句,開啟idle中斷:

#define   buf_size      128     // 定義串列埠接收buf 長度

u16   buf_size  = 0;

u8    buf[buf_size] = ;     //定義串列埠接收快取區

usart_itconfig(usart1, usart_it_idle, enable);//開啟串列埠幀空閒中斷

void usart1_irqhandler(void)       //串列埠中斷服務函式

if(buf_size >=  buf_size )

if(usart_getitstatus(usart1, usart_it_idle) != reset)        //當前為接收到一幀完整的資料報

{usart1->sr;  //先讀sr

usart1->dr;  //再度dr  清除幀空閒中斷標誌位

//此處為資料報處理邏輯

buf_size = 0;

memset(buf,0,buf_size);

教你使用stm32接收串列埠的一幀資料!

stm32支援接受單個資料或者一幀資料,若配置單個資料接收中斷的話,會出現接收包丟包,資料不完整的情況!因此在stm32的串列埠中斷中,還有乙個idle中斷,用來產生串列埠接受一幀資料而產生的中斷,比如說串列埠發來n個資料,會產生n次接收中斷和一次idle中斷,因此方便使用者來接收主機傳送或者從機返...

stm32串列埠接收完整的資料報

參考了文章 stm32串列埠中斷接收方式詳細比較 借鑑了第四種中斷方式 串列埠的配置這裡不做說明,僅對stm32接收中斷中的資料進行解析。資料幀協議 幀頭1幀頭2 資料長度 有效資料 crc 1 crc 2 b5 5b 0300 570b 幀頭1 幀頭2 資料長度 包含有效資料 crc 1 crc ...

串列埠通訊識別一幀資料的起始與結束標誌位

下面給出該方法在keil c5l中的示例程式 include regx52.h define head1 0x00 define head2 0x01 define len 0x02 define type 0x03 define data 0x04 define check 0x05 unsign...