1. 程式人生 > >USART與USB接收不定數據方法,標準庫、HAL庫都適用

USART與USB接收不定數據方法,標準庫、HAL庫都適用

文件中 修改 .com 適用於 判斷 清0 服務函數 res image

很多時候,我們使用串口或USB接收數據時,往往不知道PC端會發多長的數據下來,

為了解決這個不定數據接收問題,在此各提供一個解決思路。

串口數據不定接收:

  由於STM32單片機帶IDLE中斷,所以利用這個中斷,可以接收不定長字節的數據,

由於STM32屬於ARM單片機,所以這篇文章的方法也適合其他的ARM單片機。

IDLE就是串口收到一幀數據後,發生的中斷。什麽是一幀數據呢?比如說給單片機一

次發來1個字節,或者一次發來8個字節,這些一次發來的數據,就稱為一幀數據,也可以

叫做一包數據。

還有一個RXNE中斷,當接收到1個字節,就會產生RXNE中斷,當接收到一幀數據,就

會產生IDLE中斷。比如給單片機一次性發送8個字節,就會產生8次RXNE中斷,1次IDLE中斷。

這裏只寫RXNE中斷例子,IDLE中斷的類似,只是寄存器地址不同,各位可以查手冊編寫。

eg:

  在中斷服務函數裏添加一下代碼,函數外部定義 buff[ ] 和 i=0 ; 我這裏使用的是串口1:

  if(UASART_GetITStatus(UASART1, UASART_IT_RXNE != RESET)) //接收一個字節判斷

  {

    buff [i++] = UASART1->DR; //把接收到的字節保存到數組後,數組下標自加1

  }

  就這麽幾句代碼就可以實現了,buff[ ],就是接收到的數據,i-1 就是數據長度了

=======================================================================

USB不定數據接收:

usb不定數據接收,利用了定時器作為校驗來接收,這個方法通用性強,適用於uasart

也適用於usb,還使用於hal庫。不過這個方法有一個局限性,就是PC端發送數據過來的時間

間隔不可以太短,否則會出現誤判情況。

定時器方法的原理是:先定時一個時間間隔合適的時間,一般幾毫秒就可以了,然後在

接收服務函數裏把接收到的數據存到buff[ ],i++,接著定時器計數值清0,打開定時器,如果

數據沒接受完,每次接收都清空了定時器計數器,使得定時器無法進入定時器中斷。如果數據

接收完成了,則過不會清空定時器計數器,進入定時器中斷,此時則判斷數據已經接收完成,

可以在定時器中斷中取出數據和數據長度。

eg:

這裏我是用HAL庫作為例子,在usbd_cdc_if.c文件中找到USB接收中斷服務函數,在裏面

修改代碼即可。

  技術分享圖片

  技術分享圖片

  技術分享圖片

  技術分享圖片

因為usb發送,每發送最大包是64個字節,而且usb接收可以自己算出接收長度,不過超

過64字節就會出錯,所以我這裏進行了一個最大包處理。

USART與USB接收不定數據方法,標準庫、HAL庫都適用