STM32
直播中

张浩

7年用户 1127经验值
私信 关注
[问答]

如何去使用STM32F103ZET6的外部中断按键呢

STM32F103ZET6中断优先级的配置步骤有哪些?
如何去使用STM32F103ZET6的外部中断按键呢?

回帖(2)

谢丹丹

2021-11-24 09:59:08
  野火F1开发板STM32案例-外部中断(按键)使用
  硬件平台
  野火STM32F103ZET6 霸道V2开发板
  正点原子F1系列开发板
  软件平台
  Keil MDK 5.31
  串口调试助手
  中断相关概念
  中断配置寄存器
  # 配置中断时,使用ISER、 ICER 和 IP 寄存器,
  ## ISER 是中断使能寄存器
  ## ICER 是中断清除寄存器
  ## IP 是中断优先级寄存器
  中断优先级
  1. 数值越小,优先级越高
  2. STM32F103 中只使用4位,高4位有效。
  3. 用于表达优先级的高 4 位又被分组成抢占式优先级和响应优先级,称为“亚优先级”或“副优先级”
  4. 每个中断源都需要被指定这两种优先级。
  中断配置步骤
  1.使能外设中断
  6. 设置中断优先级分组
  初始化 NVIC_InitTypeDef 结构体,设置抢占优先级和响应优先级,使能中断请求。
  typedef struct
  {
  uint8_t NVIC_IRQChannel; //中断源
  uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级
  uint8_t NVIC_IRQChannelSubPriority; //响应优先级
  FunctionalState NVIC_IRQChannelCmd; //中断使能或失能
  } NVIC_InitTypeDef;
  NVIC_IRQChannel 中断源:中断源的设置,不同的外设中断,中断源不一样
  NVIC_IRQChannelPreemptionPriority //抢占优先级
  NVIC_IRQChannelSubPriority //响应优先级
  NVIC_IRQChannelCmd //中断使能或失能:使能配置为 ENABLE,失能配置为 DISABLE。
  NVIC_IRQChannel //中断源
  /****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
  NonMaskableInt_IRQn = -14, /*!《 2 Non Maskable Interrupt */
  MemoryManagement_IRQn = -12, /*!《 4 Cortex-M3 Memory Management Interrupt */
  BusFault_IRQn = -11, /*!《 5 Cortex-M3 Bus Fault Interrupt */
  UsageFault_IRQn = -10, /*!《 6 Cortex-M3 Usage Fault Interrupt */
  SVCall_IRQn = -5, /*!《 11 Cortex-M3 SV Call Interrupt */
  DebugMonitor_IRQn = -4, /*!《 12 Cortex-M3 Debug Monitor Interrupt */
  PendSV_IRQn = -2, /*!《 14 Cortex-M3 Pend SV Interrupt */
  SysTick_IRQn = -1, /*!《 15 Cortex-M3 System Tick Interrupt */
  /****** STM32 specific Interrupt Numbers *********************************************************/
  WWDG_IRQn = 0, /*!《 Window WatchDog Interrupt */
  PVD_IRQn = 1, /*!《 PVD through EXTI Line detection Interrupt */
  TAMPER_IRQn = 2, /*!《 Tamper Interrupt */
  RTC_IRQn = 3, /*!《 RTC global Interrupt */
  FLASH_IRQn = 4, /*!《 FLASH global Interrupt */
  RCC_IRQn = 5, /*!《 RCC global Interrupt */
  EXTI0_IRQn = 6, /*!《 EXTI Line0 Interrupt */
  EXTI1_IRQn = 7, /*!《 EXTI Line1 Interrupt */
  EXTI2_IRQn = 8, /*!《 EXTI Line2 Interrupt */
  EXTI3_IRQn = 9, /*!《 EXTI Line3 Interrupt */
  EXTI4_IRQn = 10, /*!《 EXTI Line4 Interrupt */
  DMA1_Channel1_IRQn = 11, /*!《 DMA1 Channel 1 global Interrupt */
  DMA1_Channel2_IRQn = 12, /*!《 DMA1 Channel 2 global Interrupt */
  DMA1_Channel3_IRQn = 13, /*!《 DMA1 Channel 3 global Interrupt */
  DMA1_Channel4_IRQn = 14, /*!《 DMA1 Channel 4 global Interrupt */
  DMA1_Channel5_IRQn = 15, /*!《 DMA1 Channel 5 global Interrupt */
  DMA1_Channel6_IRQn = 16, /*!《 DMA1 Channel 6 global Interrupt */
  DMA1_Channel7_IRQn = 17, /*!《 DMA1 Channel 7 global Interrupt */
  STM32F103 中断向量表
  
  
  EXTI外部中断
  1. STM32F10x 外部中断/事件控制器(EXTI)包含多达 20 个用于产生事件/中断请求的边沿检测器。
  2. EXTI 的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发)
  还可独立地被屏蔽。
  3. EXIT功能:产生中断;产生事件。
  STM32 EXIT框架图
  
  EXTI外部中断步骤
  使能I0口时钟,配置I0口模式为输入
  开启AFIO时钟,设置I0口与中断线的映射关系
  配置中断分组(NVIC),使能中断
  初始化EXTI,选择触发方式
  编写EXTI中断服务函数
  GPIO引脚配置(本文中和外部中断bsp_exit.h一起进行初始化,可以分开进行配置相关函数)
  (一般配置过程类似,无论使用什么外设,UART,IIC,SPI,ADC 一般情况都要GPIO初始化)
  //定义GPIO初始化结构体
  //使能 GPIO时钟 (时钟分频)
  //设置相关外部设备的对应引脚
  //设置GPIO端口模式(GPIO输入 GPIO输出)
  //设置生效(GPIO端口启动生效)
  # GPIO输入模式
  void initKey(void)
  {
  GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIO时钟 (时钟分频)
  GPIO_InitStructure.GPIO_Pin = KEY_UP_PIN|KEY_DOWN_PIN;//设置相关外部设备的对应引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置上拉输入 //设置GPIO端口模式
  GPIO_Init(GPIOA, &GPIO_InitStructure); //设置生效(GPIO端口启动生效)
  }
  # GPIO输出模式
  void initLED(void)
  {
  GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO时钟
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //设置对应引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //工作速度50MHz
  GPIO_Init(GPIOB, &GPIO_InitStructure); //设置生效
  GPIO_ResetBits(GPIOB, GPIO_Pin_5); //默认低电平,LED不
  }
  配置嵌套向量中断控制器NVIC步骤
  定义NVIC结构体 NVIC_InitTypeDef 结构体
  typedef struct
  {
  uint8_t NVIC_IRQChannel; //中断源
  uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级
  uint8_t NVIC_IRQChannelSubPriority; //响应优先级
  FunctionalState NVIC_IRQChannelCmd; //中断使能或失能
  } NVIC_InitTypeDef;
  配置NVIC为优先级组
  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  配置中断源
  NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
  // #define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
  // #define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0
  // #define KEY1_INT_EXTI_LINE EXTI_Line0
  // #define KEY1_INT_EXTI_IRQ EXTI0_IRQn
  配置抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  配置子优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  使能中断通道
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  初始化NVIC
  NVIC_Init(&NVIC_InitStructure); 配置 EXTI中断口,并设置中断优先级步骤流程
  1. 定义GPIO_InitTypeDef EXTI_InitTypeDef 结构体
  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  typedef struct
  {
  uint16_t GPIO_Pin; /*!《 Specifies the GPIO pins to be configured.
  This parameter can be any value of @ref GPIO_pins_define */
  GPIOSpeed_TypeDef GPIO_Speed; /*!《 Specifies the speed for the selected pins.
  This parameter can be a value of @ref GPIOSpeed_TypeDef */
  GPIOMode_TypeDef GPIO_Mode; /*!《 Specifies the operating mode for the selected pins.
  This parameter can be a value of @ref GPIOMode_TypeDef */
  }GPIO_InitTypeDef;
  typedef struct
  {
  uint32_t EXTI_Line; /*!《 Specifies the EXTI lines to be enabled or disabled.
  This parameter can be any combination of @ref EXTI_Lines */
  EXTIMode_TypeDef EXTI_Mode; /*!《 Specifies the mode for the EXTI lines.
  This parameter can be a value of @ref EXTIMode_TypeDef */
  EXTITrigger_TypeDef EXTI_Trigger; /*!《 Specifies the trigger signal active edge for the EXTI lines.
  This parameter can be a value of @ref EXTIMode_TypeDef */
  FunctionalState EXTI_LineCmd; /*!《 Specifies the new state of the selected EXTI lines.
  This parameter can be set either to ENABLE or DISABLE */
  }EXTI_InitTypeDef;
  
  
  /*开启按键GPIO口的时钟*/
  RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
  /* 配置 NVIC 中断*/
  NVIC_Configuration();
  GPIO引脚配置
  /*--------------------------KEY1配置-------------------------*/
  /* 选择按键用到的GPIO */
  GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
  /* 配置为浮空输入 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
  /*------------------------KEY2配置-----------------------------*/
  /* 选择按键用到的GPIO */
  GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
  /* 配置为浮空输入 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);
  中断配置
  中断信号源
  EXIT模式
  外部中断触发类型
  使能中断EXIT
  中断初始化
  /* 选择EXTI的信号源 */
  GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);
  EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
  /* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  /* 上升沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  /* 使能中断 */
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  BSP_EXIT.H
  //引脚定义
  #define KEY1_INT_GPIO_PORT GPIOA
  #define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)
  #define KEY1_INT_GPIO_PIN GPIO_Pin_0
  #define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
  #define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0
  #define KEY1_INT_EXTI_LINE EXTI_Line0
  #define KEY1_INT_EXTI_IRQ EXTI0_IRQn
  #define KEY1_IRQHandler EXTI0_IRQHandler
  #define KEY2_INT_GPIO_PORT GPIOC
  #define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO)
  #define KEY2_INT_GPIO_PIN GPIO_Pin_13
  #define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC
  #define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13
  #define KEY2_INT_EXTI_LINE EXTI_Line13
  #define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn
  #define KEY2_IRQHandler EXTI15_10_IRQHandler
  
举报

步雅芸

2021-11-24 09:59:22
BSP_EXIT.C
  配置嵌套向量中断控制器NVIC
  #include “bsp_exit.h”
  /**
  * @brief 配置嵌套向量中断控制器NVIC
  * @param 无
  * @retval 无
  */
  static void NVIC_Configuration(void)
  {
  NVIC_InitTypeDef NVIC_InitStructure;
  /* 配置NVIC为优先级组1 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  /* 配置中断源:按键1 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
  /* 配置抢占优先级 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 配置子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /* 配置中断源:按键2,其他使用上面相关配置 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
  NVIC_Init(&NVIC_InitStructure);
  }
  配置 IO为EXTI中断口,并设置中断优先级
  void EXTI_Key_Config(void)
  {
  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  /*开启按键GPIO口的时钟*/
  RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
  /* 配置 NVIC 中断*/
  NVIC_Configuration();
  /*--------------------------KEY1配置-----------------------------*/
  /* 选择按键用到的GPIO */
  GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
  /* 配置为浮空输入 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
  /* 选择EXTI的信号源 */
  GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);
  EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
  /* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  /* 上升沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  /* 使能中断 */
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  /*--------------------------KEY2配置-----------------------------*/
  /* 选择按键用到的GPIO */
  GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
  /* 配置为浮空输入 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);
  /* 选择EXTI的信号源 */
  GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE);
  EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
  /* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  /* 下降沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  /* 使能中断 */
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  }
  中断服务函数
  #include “stm32f10x_it.h”
  #include “bsp_test.h”
  /**
  ******************************************************************************
  * @file stm32 用户自定义外部中断
  * @author dele
  * @version V1.0
  * @date 2020-10-03
  * @brief 按键测试(中断模式/EXTI模式)
  * 实验平台:野火 F103-霸道 STM32 开发板
  ******************************************************************************
  */
  void KEY1_IRQHandler(void)
  {
  //确保是否产生了EXTI Line中断
  if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
  {
  // LED1 取反
  LED1_TOGGLE;
  BSP_KEY1_EXIT_LCDTEST();
  USART_SendString(USART1,“KEY1 EXIT www.delehub.top”);
  USART_SendLine(USART1);
  //清除中断标志位
  EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
  }
  }
  void KEY2_IRQHandler(void)
  {
  //确保是否产生了EXTI Line中断
  if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET)
  {
  // LED2 取反
  LED2_TOGGLE
  BSP_KEY2_EXIT_LCDTEST();
  USART_SendString(USART1,“KEY2 EXIT 2020-10-03 14:50”);
  USART_SendLine(USART1);
  //清除中断标志位
  EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);
  }
  }
  按键外部中断测试函数
  void BSP_KEY1_EXIT_LCDTEST(void)
  {
  LCD_SetFont(&Font8x16);
  LCD_SetColors(RED,WHITE);
  ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); /* 清屏,显示全黑 */
  ILI9341_DispStringLine_EN(LINE(0),“2020-10-03 14:30 BSP_EXIT_TEST”);
  ILI9341_DispStringLine_EN(LINE(1),“KEY1 EXIT TEST”);
  LCD_SetTextColor(RED);
  ILI9341_DrawCircle(100,200,20,1);
  }
  void BSP_KEY2_EXIT_LCDTEST(void)
  {
  LCD_SetFont(&Font8x16);
  LCD_SetColors(RED,WHITE);
  ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); /* 清屏,显示全黑 */
  ILI9341_DispStringLine_EN(LINE(3),“2020-10-03 14:30 DELEHUB”);
  ILI9341_DispStringLine_EN(LINE(4),“KEY2 EXIT TEST”);
  LCD_SetTextColor(GREEN);
  ILI9341_DrawCircle(100,200,40,0);
  }
  MAIN.C
  /****************************************************************
  * @file main.c
  * 实验平台:野火 F103-霸道 STM32 开发板 ***************************************************************** 第三方库文件导入 START THE FILE
  ***************************************************************/
  #include “stm32f10x.h”
  #include “bsp_led.h”
  #include “bsp_key.h”
  #include “bsp_beep.h”
  #include “bsp_exit.h”
  #include “timer.h”
  #include “bsp_ili9341_lcd.h”
  #include “bsp_SysTick.h”
  #include “bsp_usart.h”
  #include 《stdio.h》
  #include “bsp_test.h”
  #include “STM32F103xxxx_USART.H”
  /******************************************************************************
  END THE FILE
  * 第三方库文件导入*********************************************************/
  void HardWare_Iint(void)
  {
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  EXTI_Key_Config();
  LED_Iint();
  Key_Iint();
  Beep_Init();
  //TIM4_Int_Init(9999,7199);
  ILI9341_Init();
  USART_Configure();
  }
  /**
  * @brief 主函数
  * @param 无
  * @retval 无
  */
  int main(void)
  {
  /* 硬件端口初始化 */
  HardWare_Iint();
  while(1)
  {
  }
  }
  串口打印效果
  
举报

更多回帖

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