STM32串口之空閒中斷

背景

在做Nbiot的一個路燈項目,NBiot模塊一般都是串口接口,使用AT指令集,對接中國移動onenet平臺。先用串口助手去測試,流程測試OK之後需要在MCU上重新寫一遍。一開始用的STC15系列的MCU,然後跟平臺之間對接協議很多,代碼量較大,所以換到了STM32F1系列的MCU。在STC15MCU上面通過串口接收數據只能老老實實用接收中斷來做,每接收一個字節都需要判斷幀頭幀尾,一幀結束再處理。之前就聽說過STM32串口上面有幀中斷,一直沒有用過,然後纔有了這篇博客。

STM32串口 IDLE中斷

IDLE其實是 空閒的意思。IDLE中斷叫空閒中斷,不叫幀中斷。那麼什麼叫空閒,怎麼定義空閒呢?
在實際發送數據的時候,比如一串字符串,我們會採用如下方式發送

void uart1_putc(char dat){
	SBUF = dat;
	while (!TI);
	TI = 0;
}
void uart1_puts_n(char *str){
	while (*str)
		uart1_putc(*str++);
}
void uart1_puts_n("i am handsome");

其實發送的兩個字符之間間隔非常短,所以在兩個字符之間不叫空閒。空閒的定義是總線上在一個字節的時間內沒有再接收到數據,空閒中斷是檢測到有數據被接收後,總線上在一個字節的時間內沒有再接收到數據的時候發生的。
而總線在什麼情況時,會有一個字節時間內沒有接收到數據呢?一般就只有一個數據幀發送完成的情況,所以串口的空閒中斷也叫幀中斷。
要怎麼開啓幀中斷呢?
其實其他串口配置不用改變,只需要在開啓串口接收中斷的時候加上一句話就Ok。

USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啓串口接收中斷
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//開啓串口空閒中斷

然後中斷函數如下

void USART2_IRQHandler(void){                	//串口1中斷服務程序
	int clear;
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){  //字符接收中斷(接收到的數據必須是0x0d 0x0a結尾)
		USART2_RX_BUF[length++] = USART2->DR & 0x0FF;
	}else if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){//空閒幀中斷
		if(USART2_RX_BUF[length - 1] == 0xff){
			clear = USART2->DR;
			clear = USART2->SR;
			length = clear;
			length = 0;
			USART2_RX_STA = 1;
		}else{
			;
		}
	}
}

在普通中斷的時候僅僅保存數據,在幀中斷的時候需要執行相應處理函數。
如果沒有幀中斷,必須在接收中斷中判斷每一個接收數據與幀頭幀尾是否相符,效率極低。
之前一直以爲天下串口都一樣,還是有很多細節的,可以提升不少效率!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章