串口中斷函數詳解


串口中斷函數詳解

ARM cortex_m3 內核支持 256 個中斷(16 個內核+240 外部)和可編程 256 級中斷優先級的設置。

STM32支持的中斷共為84個(16個內核+68個外部),和16級可編程中斷優先級的設置。

AIRCR是NIVC配置中一個關鍵的寄存器,由於STM32有很多中斷,要處理這些中斷的時候總是需要先后順序的,所以采用AIRCR寄存器給中斷優先級進行分組。

優先組別總用有5組, 0-4,分為搶占優先級和響應優先級(也稱為子優先級),使用低字節的高四位來設置中斷優先級分組。

例如:當AIRCR寄存器的第八位到第十位都為1時,寄存器的第四位到第七位都是在設置響應優先級,最高可以有0個搶占優先級和16級響應優先級。具體分配如下表:

AIRCR[10: 8] bit[7: 4] 結果
0 111 0:4 0 位搶占優先級, 4 位響應優先級
1 110 1:3 1 位搶占優先級, 3 位響應優先級
2 101 2:2 2 位搶占優先級, 2 位響應優先級
3 100 3:1 3 位搶占優先級, 1 位響應優先級
4 011 4:0 4 位搶占優先級, 0 位響應優先級

在使用NVIC初始化以前需要使用NVIC_PriorityGroupConfig( )函數設置中斷優先級分組。分組后再在中斷初始化函數中使用NVIC_IRQChannelPreemptionPriority設置具體的中斷優先級。

下面為串口初始化函數以及中斷函數:

void uart_init (){
  	//GPIO端口設置
  	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能	USART1,GPIOA時鍾
  
	//USART1_TX   GPIOA.9
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//復用推挽輸出
  	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  	//USART1_RX	  GPIOA.10初始化
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
  	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  	//Usart1 NVIC 配置
    //
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優先級3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子優先級3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根據指定的參數初始化VIC寄存器
  
   	//USART 初始化設置
	USART_InitStructure.USART_BaudRate = 115200;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//	 無硬件數據流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收發模式

  	USART_Init(USART1, &USART_InitStructure); //初始化串口1
  	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
  	USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

void USART1_IRQHandler (void)                	//串口1中斷服務程序
{
	u8 Res;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){  //接收中斷(接收到的數據必須是		0x0d 0x0a結尾)。USART_GetITStatus函數如果接收寄存器存在數據就返回SET   
			Res =USART_ReceiveData(USART1);	 //讀取接收到的數據,一次發送一個字節
			if ((USART_RX_STA&0x8000)==0){   //接收未完成
				if (USART_RX_STA&0x4000){     //接收到了0x0d 0x0D(asc碼是13) 指的是“回車” 
                    if(Res!=0x0a)USART_RX_STA=0;//接收錯誤,重新開始
					else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else {//還沒收到0X0D	
				if (Res==0x0d)USART_RX_STA|=0x4000;
				else {
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if (USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數據錯誤,重																		新開始接收	  
					}		 
				}
			}   		 
     	} 
} 

這里詳細介紹稍難理解一點的語句

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  • 第一個參數為使用串口1

  • 第二個參數為中斷標志,串口有很多種中斷,這里是使用USART_IT_RXNE中斷

  • 第三個參數為使能

下面為中斷處理函數:

if((USART_RX_STA&0x8000)==0) 

USART_RX_STA是狀態標記變量,bit0~13接收有效字節數目,bit14接收0x0d,bit15接收完成標志。當接收完成時,bit15置為1。

該變量從0開始,串口中斷接收到一個數據(一個字節)就自增1。當數據讀取全部OK時候(回車和換行符號來的時候),那么 USART_RX_STA的最高位置1,表示串口數據接收全部完畢了,然后main函數里面可以處理數據了。

當接收到從電腦發過來的數據,把接收到的數據保存在USART_RX_BUF 中,同時在接收狀態寄存器(USART_RX_STA)中計數接收到的有效數據個數,當收到回車(0X0D,0X0A)的第一個字節0X0D 時,計數器將不再增加,等待0X0A 的到來,而如果0X0A 沒有來到,則認為這次接收失敗,重新開始下一次接收。如果順利接收到0X0A,則標記USART_RX_STA的第16位,這樣完成一次接收,並等待該位被其他程序清除,從而開始下一次的接收,而如果遲遲沒有收到0X0D,那么在接收數據超過設定值個數后,會丟棄前面的數據,重新接收。

0x4000,即二進制0100 0000 0000 0000,與變量USART_RX_STA,按位與(&),作用是判斷USART_RX_STA數值第15位是否為0。

0x8000,即二進制1000 0000 0000 0000,與變量USART_RX_STA,按位與(&),作用是判斷USART_RX_STA數值第16位是否為0。

USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;

為了去除最高兩位的影響,將最高兩位置0。

if (USART_RX_STA>200) USART_RX_STA=0

200為自己設定的值,如果接收到的函數大於這個值,就清除掉整個字符串重新輸入。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM