hugo0chen的个人空间 https://bbs.21ic.com/?1077662 [收藏] [复制] [RSS]

日志

一个中断源 对应多个中断接口EXTI9_5_IRQHandler()中识别不同的口 ...

已有 4174 次阅读2016-3-29 18:54 |系统分类:单片机| stm32, exti9_5_irqhandler

KEY的中断方式 : 一个中断源,对应多个中断接口EXTI_Line 如何区别不同的中断line?
GPIO配置为up形式,使用falling方式触发中断可以,如果使用nopull方式,使用falling或者是rising有干扰信号。
测试:
PB5\6\7 中断EXTI9_5_IRQHandler()
单独PB5、6、7中断都可以进入
如果是5、6组合,不能进中断;
57或是67组合,只有7可以进中断;
567组合时,只有7可以进中断。
找到原因是:SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource5|EXTI_PinSource6|EXTI_PinSource7);不能够或的方式,必须分开初始化
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource5);
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource6);
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource7);
void Key_InterruptMode_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable GPIOs clock */        
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
 
        //init GPIOA.13  ÉÏÀ­ÊäÈë Key_1
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
        // Connect Button EXTI Line to  GPIO Pin 15
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_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);
       
  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
        // exti9_5 pb5 pb6 pb7       
        GPIO_InitStructure.GPIO_Pin= GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource5);
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource6);
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource7);
       
        EXTI_InitStructure.EXTI_Line = EXTI_Line5|EXTI_Line6|EXTI_Line7;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_Init(&EXTI_InitStructure);

        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
void EXTI9_5_IRQHandler(void)
{
        #ifdef KEY_INTERRUPT
  uint8_t data;
               
        if(EXTI_GetITStatus(EXTI_Line5) != RESET)   // key2
  {          
                BOARD_LED_OFF(LED1);
                BOARD_LED_OFF(LED3);
                data='2';
                usart1_sendbyte(&data,1);
                EXTI_ClearITPendingBit(EXTI_Line5);    // Clear the EXTI line 5 pending bit   
  }
         if(EXTI_GetITStatus(EXTI_Line6) != RESET)  // key3
  {          
                BOARD_LED_ON(LED1);
                BOARD_LED_OFF(LED3);
                data='3';
                usart1_sendbyte(&data,1);               
                EXTI_ClearITPendingBit(EXTI_Line6);    // Clear the EXTI line 5 pending bit   
  } 
        if(EXTI_GetITStatus(EXTI_Line7) != RESET)  // key4
  {          
                BOARD_LED_OFF(LED1);
                BOARD_LED_ON(LED3);
                data='4';
                usart1_sendbyte(&data,1);
                EXTI_ClearITPendingBit(EXTI_Line7);    // Clear the EXTI line 5 pending bit   
  }
 #endif       
}

一个是获取状态的,一个是获取中断的。
EXTI_GetFlagStatus只是纯粹读取中断标志位的状态,但是不一定会响应中断(EXT_IMR寄存器对该中断进行屏蔽);而EXTI_GetITStatus除了读取中断标志位,还查看EXT_IMR寄存器是否对该中断进行屏蔽,在中断挂起&没有屏蔽的情况下就会响应中断。仔细看看代码就知道区别了
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
{
  FlagStatus bitstatus = RESET;
 
  assert_param(IS_GET_EXTI_LINE(EXTI_Line));
 
  if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET)
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;
}

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
{
  ITStatus bitstatus = RESET;
  uint32_t enablestatus = 0;
 
  assert_param(IS_GET_EXTI_LINE(EXTI_Line));
 
  enablestatus =  EXTI->IMR & EXTI_Line;
  if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  return bitstatus;
}
 


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)