新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > STM32單片機學習(2) 外部中斷

STM32單片機學習(2) 外部中斷

作者: 時間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
李想stm32視頻教程49集http://pan.baidu.com/s/1kTyt03PSTM32的中斷(上中下)外部中斷(寄存器、庫函數(shù))

STM32的函數(shù)說明(中文).pdf http://download.csdn.net/detail/leytton/7630851
中?斷?管?理?函?數(shù).pdf http://wenku.baidu.com/view/b90e5b82360cba1aa811dad3.html

本文引用地址:http://butianyuan.cn/article/201611/318701.htm

概念基礎(chǔ)

STM32共76個中斷,16個內(nèi)核中斷,60個外部中斷,即可屏蔽中斷

中斷分5組:0-4,所有中斷只能放在同一組里

ISER[0]、ISER[1]是32位的中斷使能寄存器數(shù)組,ISER[0]的bit0-31對應(yīng)中斷0-31、ISER[1]的bit0-27對應(yīng)中斷32-59,置1有效
ICER[0]、ICER[1]正好相反,是清除使能,置1有效

stm32中斷搶占優(yōu)先級和響應(yīng)優(yōu)先級有什么區(qū)別?
中斷A搶占優(yōu)先級比B高,那么A的中斷可以在B里面觸發(fā),忽略響應(yīng)優(yōu)先級;
A和B搶占優(yōu)先級相同,則A、B的響應(yīng)優(yōu)先級決定誰先響應(yīng);
搶占優(yōu)先級高的可以打斷搶占優(yōu)先級低的中斷,響應(yīng)式則不能
數(shù)字越小,優(yōu)先級越高

中斷配置步驟


源代碼

/**	* 軟件功能:	 中斷閃燈實驗(軟件延時方式) 按鍵中斷* */#include "stm32f10x.h"#include #include "delay.h"void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void EXTI_Configuration(void);/*函數(shù): int main(void)功能: main主函數(shù)參數(shù): 無返回: 無/int main(void){RCC_Configuration();GPIO_Configuration();delay_init(72);NVIC_Configuration();EXTI_Configuration();GPIO_ResetBits(GPIOA,GPIO_Pin_0);//滅	  GPIO_ResetBits(GPIOA,GPIO_Pin_2);//滅while(1);}/*函數(shù): void RCC_Configuration(void)功能: 復(fù)位和時鐘控制 配置參數(shù): 無返回: 無/void RCC_Configuration(void){ErrorStatus HSEStartUpStatus;                    //定義外部高速晶體啟動狀態(tài)枚舉變量RCC_DeInit();                                    //復(fù)位RCC外部設(shè)備寄存器到默認值RCC_HSEConfig(RCC_HSE_ON);                       //打開外部高速晶振HSEStartUpStatus = RCC_WaitForHSEStartUp();      //等待外部高速時鐘準備好if(HSEStartUpStatus == SUCCESS)                  //外部高速時鐘已經(jīng)準別好{FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //開啟FLASH預(yù)讀緩沖功能,加速FLASH的讀取。所有程序中必須的用法.位置:RCC初始化子函數(shù)里面,時鐘起振之后FLASH_SetLatency(FLASH_Latency_2);                    //flash操作的延時RCC_HCLKConfig(RCC_SYSCLK_Div1);               //配置AHB(HCLK)時鐘等于==SYSCLKRCC_PCLK2Config(RCC_HCLK_Div1);                //配置APB2(PCLK2)鐘==AHB時鐘RCC_PCLK1Config(RCC_HCLK_Div2);                //配置APB1(PCLK1)鐘==AHB1/2時鐘RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //配置PLL時鐘 == 外部高速晶體時鐘 * 9 = 72MHzRCC_PLLCmd(ENABLE);                                   //使能PLL時鐘while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)    //等待PLL時鐘就緒{}RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);            //配置系統(tǒng)時鐘 = PLL時鐘while(RCC_GetSYSCLKSource() != 0x08)                  //檢查PLL時鐘是否作為系統(tǒng)時鐘{}}RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);  //允許 GPIOB、AFIO時鐘}/*函數(shù): void GPIO_Configuration(void)功能: GPIO配置參數(shù): 無返回: 無/void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;        //定義GPIO初始化結(jié)構(gòu)體GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); 	   //PA用于輸出控制LED燈GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //上拉輸入GPIO_Init(GPIOB, &GPIO_InitStructure); 	   //PB.0用于接受按鍵k1輸入}void NVIC_Configuration(void)	 //中斷分組和優(yōu)先級配置	 詳見《STM32的函數(shù)說明(中文).pdf》P165{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	 //0組,先占優(yōu)先級0位,從優(yōu)先級4位NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中斷線 0 中斷NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 	  //0組無搶占優(yōu)先級,所以只配置從優(yōu)先級,即響應(yīng)式優(yōu)先級NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能NVIC_Init(& NVIC_InitStructure); //初始化配置}void EXTI_Configuration(void)  //中斷配置  //詳見《STM32的函數(shù)說明(中文).pdf》	  P99{EXTI_InitTypeDef EXTI_InitStructure;		EXTI_ClearITPendingBit(EXTI_Line0);//清除 EXTI 線路掛起位EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //設(shè)置 EXTI 線路為中斷請求EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //設(shè)置輸入線路下降沿為中斷請求EXTI_InitStructure.EXTI_Line = EXTI_Line0; //外部中斷線 0EXTI_InitStructure.EXTI_LineCmd	= ENABLE;//使能EXTI_Init(& EXTI_InitStructure); //初始化配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);	 ///*將EXTI線0連接到PB0*/}/*中斷服務(wù)程序*/void EXTI0_IRQHandler()	  //按下按鈕還是放開按鈕是下降沿??{if(EXTI_GetITStatus(EXTI_Line0) == SET)//檢查指定的EXTI線路觸發(fā)請求發(fā)生與否,返回一個EXTI_Line新狀態(tài){EXTI_ClearITPendingBit(EXTI_Line0);//清除線路掛起位EXTI_ClearFlag(EXTI_Line0);//清除中斷掛起位 GPIO_SetBits(GPIOA,GPIO_Pin_0);//點亮LED                delay_ms(500);//延時GPIO_ResetBits(GPIOA,GPIO_Pin_0);//滅if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0))  GPIO_SetBits(GPIOA,GPIO_Pin_2);//點亮LEDelse  GPIO_ResetBits(GPIOA,GPIO_Pin_2);//滅} }

可另行參考文章:

STM32學習筆記之EXTI(外部中斷)http://blog.sina.com.cn/s/blog_6623834301018woa.html

參考資料:STM32數(shù)據(jù)手冊、網(wǎng)絡(luò)資料

==================================================================================

外部中斷/事件控制器由19個產(chǎn)生事件/中斷要求的邊沿檢測器組成。每個輸入線可以獨立地配置

輸入類型(脈沖或掛起)和對應(yīng)的觸發(fā)事件(上升沿或下降沿或者雙邊沿都觸發(fā))。每個輸入線都可以被獨

立的屏蔽。掛起寄存器保持著狀態(tài)線的中斷要求。

==================================================================================

19個中斷如下:

17——EXTI線16連接到PVD輸出

18——EXTI線17連接到RTC鬧鐘事件

19——EXTI線18連接到USB喚醒事件

注:有上圖可知EXTI0連接的引腳為PA0、PB0、PC0、PD0、PE0、PF0、PG0,其他外部中斷EXTI1——

EXTI15類似。所以在使用時盡量將需要的外部中斷配置在不同的EXTIx上。

例如需要3個外部中斷,我們可以配置到PA0、PB4、PG3上,此時每個中斷都有自己的中斷處理程

序段。如果配置到PA0、PB0、PC1,則PA0和PB0將公用一個中斷程序段。當然如果特殊需要,也

可以這樣設(shè)計。

==================================================================================

配置使用方法:

  1. 初始化相應(yīng)的GPIO管腳
  2. 配置外部中斷源并進行中斷源和GPIO的連接
  3. 編寫相應(yīng)中斷源的中斷處理程序

==================================================================================

程序代碼

  • 初始化相應(yīng)的GPIO管腳

GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

注:GPIO的復(fù)用功能必須打開,如紅字部分

  • 配置外部中斷源并進行中斷源和GPIO的連接


GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource1);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);


EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line1|EXTI_Line8|EXTI_Line9;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

  • 編寫相應(yīng)中斷源的中斷處理程序


void EXTI0_IRQHandler(void)
{
if(Sys_Status > MIN_STATUS)
{
Sys_Status --;
}
EXTI_ClearITPendingBit(EXTI_Line0);
}


void EXTI1_IRQHandler(void)
{
PEout(2) = ~PEout(2);
EXTI_ClearITPendingBit(EXTI_Line1);
}


#define Exti_From_Pin8 0x00000100
#define Exti_From_Pin9 0x00000200

void EXTI9_5_IRQHandler(void)
{

u32 Temp = 0x00;

PEout(2) = ~PEout(2);
Temp = EXTI->PR; //取讀是那個引腳的中斷
switch(Temp)
{
case Exti_From_Pin8:
EXTI_ClearITPendingBit(EXTI_Line8);
break;
case Exti_From_Pin9:
if(Sys_Status < MAX_STATUS)
{
Sys_Status ++;
}
EXTI_ClearITPendingBit(EXTI_Line9);
break;
default:break;
}
}

==================================================================================

中斷處理程序說明,由于外部中斷EXTI5——EXTI9公用了一個中斷(EXTI10——EXTI15類似)所以要

區(qū)分不同的中斷源需要進行相應(yīng)的判斷。如上EXTI9_5_IRQHandler中,通過取讀EXTI->PR寄存器來判

斷中斷的來源。



關(guān)鍵詞: STM32單片機學習外部中

評論


技術(shù)專區(qū)

關(guān)閉