stm32串口中斷接收一幀數據

最近用到stm32的串口,中斷一個字符一個字符接收好心累,網上度了一下發現了一篇好的帖子,和大家分享一下,原貼地址:http://www.51hei.com/bbs/dpj-39885-1.html

再次感謝原貼樓主的分享,爲了方便大家,我把原文複製過來》

 

今天說一下STM32單片機的接收不定長度字節數據的方法。由於STM32單片機帶IDLE中斷,所以利用這個中斷,可以接收不定長字節的數據,由於STM32屬於ARM單片機,所以這篇文章的方法也適合其他的ARM單片機。
IDLE中斷什麼時候發生?
IDLE就是串口收到一幀數據後,發生的中斷。什麼是一幀數據呢?比如說給單片機一次發來1個字節,或者一次發來8個字節,這些一次發來的數據,就稱爲一幀數據,也可以叫做一包數據。
如何判斷一幀數據結束,就是我們今天討論的問題。因爲很多項目中都要用到這個,因爲只有接收到一幀數據以後,你纔可以判斷這次收了幾個字節和每個字節的內容是否符合協議要求。
看了前面IDLE中斷的定義,你就會明白了,一幀數據結束後,就會產生IDLE中斷。這個中斷真是太TMD有用了。省去了好多判斷的麻煩。
如何配置好IDLE中斷?
下面我們就配置好串口IDLE中斷吧。

這是串口CR1寄存器,其中,對bit4寫1開啓IDLE中斷,對bit5寫1開啓接收數據中斷。(注意:不同系列的STM32,對應的寄存器位可能不同)
(RXNE中斷和IDLE中斷的區別?
當接收到1個字節,就會產生RXNE中斷,當接收到一幀數據,就會產生IDLE中斷。比如給單片機一次性發送了8個字節,就會產生8次RXNE中斷,1次IDLE中斷。)

 

這是狀態寄存器,當串口接收到數據時,bit5就會自動變成1,當接收完一幀數據後,bit4就會變成1.
需要注意的是,在中斷函數裏面,需要把對應的位清0,否則會影響下一次數據的接收。比如RXNE接收數據中斷,只要把接收到的一個字節讀出來,就會清除這個中斷。IDLE中斷,如何是F0系列的單片機,需要用ICR寄存器來清除,如果是F1系列的單片機,清除方法是“先讀SR寄存器,再讀DR寄存器”。

 

	/* 使能接收中斷*/
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	/* 使能空閒中斷*/
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
	USART_Cmd(USART1, ENABLE);

重點是使能空閒中斷。

 

 

 

uint8_t ch[20];
char i = 0;
void USART1_IRQHandler(void)
{

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收到一個字節
	{ 	
	    //ch = USART1->DR;
			ch[i++] = USART_ReceiveData(USART1);
	
	} 
	else if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)//接收到一幀數據
	{
		USART1->SR;//先讀SR
		USART1->DR;//再讀DR
		i = 0;
		printf("%s",ch);//只是測試,所以直接在中斷裏調用printf
	}
	 
}

 

 

 

 

 

 

 

發佈了31 篇原創文章 · 獲贊 59 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章