STM32
直播中

百合子

8年用户 888经验值
擅长:控制/MCU
私信 关注
[问答]

如何对STM32的外部中断进行配置呢?有哪些步骤

STM32外部中断使用配置的过程是怎样的?
如何对STM32的外部中断进行配置呢?有哪些步骤?

回帖(1)

王晶

2021-11-16 11:53:45
  EXTI0_IRQn的值,其实就是EXTI0中断向量在中断向量表中的位置(STM32技术参考手册中断向量表position栏中的数值)
  一:外部中断使用配置过程:
  (1)配置时钟信号
  (2)引脚属性
  (3)NVIC配置
  (4)外部中断配置
  二:配置步骤
  步骤如下: 
  1.系统初始化,如系统时钟初始化,使之进入72MHZ主频;程序启动时已调用SystemInit()函数将主频改为72MHZ。
  2.GPIO配置,务必注意打开GPIO时钟时,一定打开AFIO时钟。 在使用引脚的重映射功能和外部中断时需要使用AFIO时钟。
  3.EXTI配置,在这里配置需要选择哪个引脚作为中断引脚。 
  //定义一个EXTI初始化结构体
  EXTI_InitTypeDef EXTI_InitStructure; 
  //设置中断线:EXTIL_Line1为中断线1
  EXTI_InitStructure.EXTI_Line = EXTI_Line1; 
  //模式
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
  模式:这里有两个模式:(1)中断模式,(2)事件,具体区别如下:
  “事件:是表示检测有一某件触发事件发生了。中断:有某个事件发生并产生中断,并跳转到对应的中断处理程序中。事件可以触发中断,也可以不触发中断有可能被更优先的中断屏蔽,事件不会事件本质上就是一个触发信号,是用来触发特定的外设模块或核心本身(唤醒)。事件只是一个触发信号(脉冲),而中断则是一个固定的电平信号”
  //设置中断触发方式(3种)
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
   EXTI_Trigger_Falling:设置输入线路下降沿为中断请求
   EXTI_Trigger_Rising:设置输入线路上升沿为中断请求
  EXTI_Trigger_Rising_Falling:设置输入线路上升沿和下降沿为中断请求
  //定义选择中断线的新状态
  EXTI_InitStructure.EXTI_LineCmd=ENABLE;
  //根据EXTI_InitStructure中指定的参数初始化外设EXTI寄存器
  EXTI_Init(&EXTI_InitStructure);
  4.NVIC配置,这也是比单片机多出来的部分,我们必须把NVIC中对应的通道使能,并且设置优先级别。
  
  
  
  5.编写中断函数
  void EXTI2_IRQHandler(void)
  三:STM32外部中断与各通道对应关系
  
  
  
  例子 1:
  exit.c文件
  #include “exti.h”
  #include “delay.h”
  extern int isr_flag ;
  void EXTIX_Init(void)
  {
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  //时钟配置
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE);
  //IO配置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
  GPIO_SetBits(GPIOE,GPIO_Pin_0);
  //EXTI
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);
  EXTI_InitStructure.EXTI_Line=EXTI_Line0;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  //NVIC
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  }
  void EXTI0_IRQHandler(void)
  {
  delay_ms(1);
  if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
  {
  isr_flag = 1;
  EXTI_ClearITPendingBit(EXTI_Line0);
  }
  }
  例子2:
  #include “exti.h”
  #include “led.h”
  #include “key.h”
  #include “delay.h”
  #include “usart.h”
  #include “beep.h”
  //外部中断0服务程序
  void EXTIX_Init(void)
  {
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  //初始化KEY0--》GPIOA.13,KEY1--》GPIOA.15 上拉输入
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE);//使能PORTA,PORTE时钟
  //IO初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //PE2~4
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
  GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化GPIOE2,3,4
  //初始化 WK_UP--》GPIOA.0 下拉输入
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0
  //EXTI
  //GPIOE.2 中断线以及中断初始化配置 下降沿触发
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
  EXTI_InitStructure.EXTI_Line=EXTI_Line2; //KEY2
  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寄存器
  //GPIOE.3 中断线以及中断初始化配置 下降沿触发 //KEY1
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
  EXTI_InitStructure.EXTI_Line=EXTI_Line3;
  EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
  //GPIOE.4 中断线以及中断初始化配置 下降沿触发 //KEY0
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
  EXTI_InitStructure.EXTI_Line=EXTI_Line4;
  EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
  //GPIOA.0 中断线以及中断初始化配置 上升沿触发 PA0 WK_UP
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
  EXTI_InitStructure.EXTI_Line=EXTI_Line0;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
  //NVIC
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键WK_UP所在的外部中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  NVIC_Init(&NVIC_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键KEY2所在的外部中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级2
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  NVIC_Init(&NVIC_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //使能按键KEY1所在的外部中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
  NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; //使能按键KEY0所在的外部中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
  }
  //外部中断0服务程序
  void EXTI0_IRQHandler(void)
  {
  delay_ms(10);//消抖
  if(KEY3==1) //WK_UP按键
  {
  BEEP=!BEEP;
  }
  EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位
  }
  //外部中断2服务程序
  void EXTI2_IRQHandler(void)
  {
  delay_ms(10); //消抖
  if(KEY2==0) //按键KEY2
  {
  LED0=!LED0;
  }
  EXTI_ClearITPendingBit(EXTI_Line2); //清除LINE2上的中断标志位
  }
  //外部中断3服务程序
  void EXTI3_IRQHandler(void)
  {
  delay_ms(10); //消抖
  if(KEY1==0) //按键KEY1
  {
  LED1=!LED1;
  }
  EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位
  }
  void EXTI4_IRQHandler(void)
  {
  delay_ms(10); //消抖
  if(KEY0==0) //按键KEY0
  {
  LED0=!LED0;
  LED1=!LED1;
  }
  EXTI_ClearITPendingBit(EXTI_Line4); //清除LINE4上的中断标志位
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分