今天說一下STM32單片機的接收不定長度字節(jié)數(shù)據(jù)的方法。由于STM32單片機帶IDLE中斷,所以利用這個中斷,可以接收不定長字節(jié)的數(shù)據(jù),由于STM32屬于ARM單片機,所以這篇文章的方法也適合其他的ARM單片機。
IDLE中斷什么時候發(fā)生?
IDLE就是串口收到一幀數(shù)據(jù)后,發(fā)生的中斷。什么是一幀數(shù)據(jù)呢?比如說給單片機一次發(fā)來1個字節(jié),或者一次發(fā)來8個字節(jié),這些一次發(fā)來的數(shù)據(jù),就稱為一幀數(shù)據(jù),也可以叫做一包數(shù)據(jù)。
如何判斷一幀數(shù)據(jù)結(jié)束,就是我們今天討論的問題。因為很多項目中都要用到這個,因為只有接收到一幀數(shù)據(jù)以后,你才可以判斷這次收了幾個字節(jié)和每個字節(jié)的內(nèi)容是否符合協(xié)議要求。
看了前面IDLE中斷的定義,你就會明白了,一幀數(shù)據(jù)結(jié)束后,就會產(chǎn)生IDLE中斷。這個中斷真是太TMD有用了。省去了好多判斷的麻煩。
如何配置好IDLE中斷?
下面我們就配置好串口IDLE中斷吧。
%E4%B8%B2%E5%8F%A3%E6%8E%A5%E6%94%B6%E5%A4%9A%E5%AD%97%E8%8A%821.png (21.35 KB, 下載次數(shù): 309)
下載附件
2015-10-29 23:11 上傳
這是串口CR1寄存器,其中,對bit4寫1開啟IDLE中斷,對bit5寫1開啟接收數(shù)據(jù)中斷。(注意:不同系列的STM32,對應(yīng)的寄存器位可能不同)
(RXNE中斷和IDLE中斷的區(qū)別?
當接收到1個字節(jié),就會產(chǎn)生RXNE中斷,當接收到一幀數(shù)據(jù),就會產(chǎn)生IDLE中斷。比如給單片機一次性發(fā)送了8個字節(jié),就會產(chǎn)生8次RXNE中斷,1次IDLE中斷。)
%E4%B8%B2%E5%8F%A3%E6%8E%A5%E6%94%B6%E5%A4%9A%E5%AD%97%E8%8A%822.png (19.34 KB, 下載次數(shù): 309)
下載附件
2015-10-29 23:11 上傳
這是狀態(tài)寄存器,當串口接收到數(shù)據(jù)時,bit5就會自動變成1,當接收完一幀數(shù)據(jù)后,bit4就會變成1.
需要注意的是,在中斷函數(shù)里面,需要把對應(yīng)的位清0,否則會影響下一次數(shù)據(jù)的接收。比如RXNE接收數(shù)據(jù)中斷,只要把接收到的一個字節(jié)讀出來,就會清除這個中斷。IDLE中斷,如何是F0系列的單片機,需要用ICR寄存器來清除,如果是F1系列的單片機,清除方法是“先讀SR寄存器,再讀DR寄存器”。(我怎么知道?手冊上寫的)
下面以STM32F103為例給出源程序。
我們先來看程序中的主要部分。
串口初始化函數(shù)片段
%E7%A9%BA%E9%97%B2%E4%B8%AD%E6%96%AD.png (17.99 KB, 下載次數(shù): 313)
下載附件
2015-10-29 23:11 上傳
如果你原來的串口初始化函數(shù)具有打開串口接收中斷的話,實際上就是在初始化函數(shù)中多了一條打開空閑中斷的語句。
串口中斷函數(shù)
%E7%A9%BA%E9%97%B2%E4%B8%AD%E6%96%AD2.png (25.9 KB, 下載次數(shù): 309)
下載附件
2015-10-29 23:11 上傳
串口中斷函數(shù)里面,最重要的兩條語句,就是上圖中圈出來的兩條語句。第一條語句用來判斷是否接收到1個字節(jié),第二條語句用來判斷是否接收到1幀數(shù)據(jù)。(是不是感覺超級方便?媽媽再也不用擔心我如何判斷是否接收完1幀數(shù)據(jù)了。)
主函數(shù)
%E7%A9%BA%E9%97%B2%E4%B8%AD%E6%96%AD3.png (19.36 KB, 下載次數(shù): 305)
下載附件
2015-10-29 23:11 上傳
我寫的這個主函數(shù),是用來驗證接收的正確性的。RxCounter表示的是這一幀數(shù)據(jù)有幾個字節(jié),接收完一幀數(shù)據(jù),會在中斷函數(shù)里面把ReceiveState置1,然后,通過串口把接收到的數(shù)據(jù)發(fā)送回串口。這樣,既驗證了接收了多少字節(jié)的正確性,又驗證了接收到的數(shù)據(jù)是否正確。
%E7%A9%BA%E9%97%B2%E4%B8%AD%E6%96%AD4.png (26.1 KB, 下載次數(shù): 283)
下載附件
2015-10-29 23:11 上傳
上圖是結(jié)果驗證。
點擊下載源程序:
STM32串口接收不定長數(shù)據(jù)程序.7z
(207.13 KB, 下載次數(shù): 1812)
2020-11-11 17:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
我是瑞生,毫無保留的給大家透露電子設(shè)計經(jīng)驗,不定時分享實用的落地的電子設(shè)計技巧,希望能夠幫助到大家。
- /**
- ******************************************************************************
- * @file 串口接收不定長字節(jié)數(shù)據(jù)
- * @author 瑞生
- * @version V1.0
- * @date 2015.10.23
- * @brief Main program body
- ******************************************************************************
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "stm32f10x.h"
- #include "uart.h"
- volatile uint8_t aRxBuffer[100]={0x00};
- volatile uint8_t RxCounter=0;
- volatile uint8_t ReceiveState=0;
- /**
- * @brief Main program.
- * @param None
- * @retval None
- */
- int main(void)
- {
- uint8_t i=0;
-
- USART1_Init();
-
- while (1)
- {
- if(ReceiveState==1)//如果接收到1幀數(shù)據(jù)
- {
- ReceiveState=0;
- i=0;
- while(RxCounter--)// 把接收到數(shù)據(jù)發(fā)送回串口
- {
- USART_SendData(USART1, aRxBuffer[i++]);
- while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
- }
- RxCounter=0;
- }
- }
- }
復制代碼
|