1. 程式人生 > >32微控制器之外部中斷

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。