STM32單片機(jī)學(xué)習(xí)(2) 外部中斷
STM32的函數(shù)說明(中文).pdf http://download.csdn.net/detail/leytton/7630851
中?斷?管?理?函?數(shù).pdf http://wenku.baidu.com/view/b90e5b82360cba1aa811dad3.html
概念基礎(chǔ)
STM32共76個(gè)中斷,16個(gè)內(nèi)核中斷,60個(gè)外部中斷,即可屏蔽中斷
中斷分5組:0-4,所有中斷只能放在同一組里
ISER[0]、ISER[1]是32位的中斷使能寄存器數(shù)組,ISER[0]的bit0-31對(duì)應(yīng)中斷0-31、ISER[1]的bit0-27對(duì)應(yīng)中斷32-59,置1有效
ICER[0]、ICER[1]正好相反,是清除使能,置1有效
stm32中斷搶占優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí)有什么區(qū)別?
中斷A搶占優(yōu)先級(jí)比B高,那么A的中斷可以在B里面觸發(fā),忽略響應(yīng)優(yōu)先級(jí);
A和B搶占優(yōu)先級(jí)相同,則A、B的響應(yīng)優(yōu)先級(jí)決定誰先響應(yīng);
搶占優(yōu)先級(jí)高的可以打斷搶占優(yōu)先級(jí)低的中斷,響應(yīng)式則不能
數(shù)字越小,優(yōu)先級(jí)越高
中斷配置步驟
源代碼
/** * 軟件功能: 中斷閃燈實(shí)驗(yàn)(軟件延時(shí)方式) 按鍵中斷* */#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í)鐘控制 配置參數(shù): 無返回: 無/void RCC_Configuration(void){ErrorStatus HSEStartUpStatus; //定義外部高速晶體啟動(dòng)狀態(tài)枚舉變量RCC_DeInit(); //復(fù)位RCC外部設(shè)備寄存器到默認(rèn)值RCC_HSEConfig(RCC_HSE_ON); //打開外部高速晶振HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速時(shí)鐘準(zhǔn)備好if(HSEStartUpStatus == SUCCESS) //外部高速時(shí)鐘已經(jīng)準(zhǔn)別好{FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //開啟FLASH預(yù)讀緩沖功能,加速FLASH的讀取。所有程序中必須的用法.位置:RCC初始化子函數(shù)里面,時(shí)鐘起振之后FLASH_SetLatency(FLASH_Latency_2); //flash操作的延時(shí)RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB(HCLK)時(shí)鐘等于==SYSCLKRCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2(PCLK2)鐘==AHB時(shí)鐘RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1(PCLK1)鐘==AHB1/2時(shí)鐘RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL時(shí)鐘 == 外部高速晶體時(shí)鐘 * 9 = 72MHzRCC_PLLCmd(ENABLE); //使能PLL時(shí)鐘while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL時(shí)鐘就緒{}RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置系統(tǒng)時(shí)鐘 = PLL時(shí)鐘while(RCC_GetSYSCLKSource() != 0x08) //檢查PLL時(shí)鐘是否作為系統(tǒng)時(shí)鐘{}}RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //允許 GPIOB、AFIO時(shí)鐘}/*函數(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)先級(jí)配置 詳見《STM32的函數(shù)說明(中文).pdf》P165{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //0組,先占優(yōu)先級(jí)0位,從優(yōu)先級(jí)4位NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中斷線 0 中斷NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //0組無搶占優(yōu)先級(jí),所以只配置從優(yōu)先級(jí),即響應(yīng)式優(yōu)先級(jí)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 線路為中斷請(qǐng)求EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //設(shè)置輸入線路下降沿為中斷請(qǐng)求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ā)請(qǐng)求發(fā)生與否,返回一個(gè)EXTI_Line新狀態(tài){EXTI_ClearITPendingBit(EXTI_Line0);//清除線路掛起位EXTI_ClearFlag(EXTI_Line0);//清除中斷掛起位 GPIO_SetBits(GPIOA,GPIO_Pin_0);//點(diǎn)亮LED delay_ms(500);//延時(shí)GPIO_ResetBits(GPIOA,GPIO_Pin_0);//滅if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)) GPIO_SetBits(GPIOA,GPIO_Pin_2);//點(diǎn)亮LEDelse GPIO_ResetBits(GPIOA,GPIO_Pin_2);//滅} }
可另行參考文章:
STM32學(xué)習(xí)筆記之EXTI(外部中斷)http://blog.sina.com.cn/s/blog_6623834301018woa.html
參考資料:STM32數(shù)據(jù)手冊(cè)、網(wǎng)絡(luò)資料
==================================================================================
外部中斷/事件控制器由19個(gè)產(chǎn)生事件/中斷要求的邊沿檢測(cè)器組成。每個(gè)輸入線可以獨(dú)立地配置
輸入類型(脈沖或掛起)和對(duì)應(yīng)的觸發(fā)事件(上升沿或下降沿或者雙邊沿都觸發(fā))。每個(gè)輸入線都可以被獨(dú)
立的屏蔽。掛起寄存器保持著狀態(tài)線的中斷要求。
==================================================================================
19個(gè)中斷如下:
17——EXTI線16連接到PVD輸出
18——EXTI線17連接到RTC鬧鐘事件
19——EXTI線18連接到USB喚醒事件
注:有上圖可知EXTI0連接的引腳為PA0、PB0、PC0、PD0、PE0、PF0、PG0,其他外部中斷EXTI1——
EXTI15類似。所以在使用時(shí)盡量將需要的外部中斷配置在不同的EXTIx上。
例如需要3個(gè)外部中斷,我們可以配置到PA0、PB4、PG3上,此時(shí)每個(gè)中斷都有自己的中斷處理程
序段。如果配置到PA0、PB0、PC1,則PA0和PB0將公用一個(gè)中斷程序段。當(dāng)然如果特殊需要,也
可以這樣設(shè)計(jì)。
==================================================================================
配置使用方法:
- 初始化相應(yīng)的GPIO管腳
- 配置外部中斷源并進(jìn)行中斷源和GPIO的連接
- 編寫相應(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ù)用功能必須打開,如紅字部分
- 配置外部中斷源并進(jìn)行中斷源和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; //取讀是那個(gè)引腳的中斷
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公用了一個(gè)中斷(EXTI10——EXTI15類似)所以要
區(qū)分不同的中斷源需要進(jìn)行相應(yīng)的判斷。如上EXTI9_5_IRQHandler中,通過取讀EXTI->PR寄存器來判
斷中斷的來源。
評(píng)論