32微控制器之外部中斷
stm32每個IO口都可以作為中斷,103系列有19個外部中斷線,其中線0-15為外部通用中斷。而微控制器不止16個IO口。因此每個線表示每組IO的特定的IO口。例如line2對應GPIOA-G.2。
外部中斷的使用步驟:
1)初始化 IO 口為輸入。
2)開啟 IO 口複用時鐘,設定 IO 口與中斷線的對映關係。
3)初始化線上中斷,設定觸發條件等。
4)配置中斷分組(NVIC),並使能中斷。
5)編寫中斷服務函式。
1-4在中斷初始化函式裡
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中斷,需要使能AFIO時鐘
KEY_init();//初始化按鍵對應io模式
//GPIOC.5 中斷線以及中斷初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根據EXTI_InitStruct中指定的引數初始化外設EXTI暫存器
//GPIOA.15 中斷線以及中斷初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
EXTI_InitStructure.EXTI_Line=EXTI_Line15;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根據EXTI_InitStruct中指定的引數初始化外設EXTI暫存器
//GPIOA.0 中斷線以及中斷初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);//根據EXTI_InitStruct中指定的引數初始化外設EXTI暫存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能按鍵所在的外部中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//搶佔優先順序2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子優先順序1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的引數初始化外設NVIC暫存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//使能按鍵所在的外部中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//搶佔優先順序2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;//子優先順序1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//使能按鍵所在的外部中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//搶佔優先順序2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//子優先順序1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);}
中斷服務函式的模板為
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)//判斷某個線上的中斷是否發生
{delay_ms(10); //消抖
if(WK_UP==1)
{
LED0=!LED0;
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0線路掛起位
}
}
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5)!=RESET)//判斷某個線上的中斷是否發生
{
delay_ms(10); //消抖
if(KEY0==0){
LED0=!LED0;
}
EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE5上的中斷標誌位
}
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line15)!=RESET)//判斷某個線上的中斷是否發生
{
delay_ms(10); //消抖
if(KEY1==0){
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line15); //清除LINE15線路掛起位
}}
注意:中斷線 0-4 每個中斷線對應一箇中斷函式,中斷線 5-9 共用中斷函式 EXTI9_5_IRQHandler,中
斷線 10-15 共用中斷函式 EXTI15_10_IRQHandler。