1. 程式人生 > >STM32串列埠之空閒中斷

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;
			clear = 0;
			USART2_RX_STA = 1;
		}else{
			;
		}
	}
}

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