USART與USB接收不定數據方法,標準庫、HAL庫都適用
很多時候,我們使用串口或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庫都適用