如何用stm32实现使用中断exti按一下实现一个功能

2024-11-28 04:49:42
推荐回答(1个)
回答(1):

  外部中断/事件控制器由19个产生事件/中断要求的边沿检测器组成。每个输入线可以独立地配置

  输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以被独

  立的屏蔽。挂起寄存器保持着状态线的中断要求。

  =========================================分割线=========================================

  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将公用一个中断程序段。当然如果特殊需要,也

  可以这样设计。

  =========================================分割线=========================================

  配置使用方法:

  初始化相应的GPIO管脚配置外部中断源并进行中断源和GPIO的连接编写相应中断源的中断处理程序
  =========================================分割线=========================================

  程序代码

  初始化相应的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的复用功能必须打开,如红字部分

  配置外部中断源并进行中断源和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);

  编写相应中断源的中断处理程序

  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)
  {
  caseExti_From_Pin8:
  EXTI_ClearITPendingBit(EXTI_Line8);
  break;
  caseExti_From_Pin9:
  if(Sys_Status < MAX_STATUS)
  {
  Sys_Status ++;
  }
  EXTI_ClearITPendingBit(EXTI_Line9);
  break;
  default:break;
  }
  }

  =========================================分割线=========================================

  中断处理程序说明,由于外部中断EXTI5——EXTI9公用了一个中断(EXTI10——EXTI15类似)所以要

  区分不同的中断源需要进行相应的判断。如上EXTI9_5_IRQHandler中,通过取读EXTI->PR寄存器来判

  断中断的来源。