欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32笔记之 EXIT(外部中断)

程序员文章站 2022-04-01 21:49:23
...

写在前面:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。

 

目录

一、EXIT控制原理

二、外部中断的 I/O映像

三、中断服务

四、配置流程(代码解析)

五、中断函数处理


 

在上一篇 STM32笔记之 GPIO引脚中,有用到 EXIT外部中断作为 Key输入触发,所以本篇来诠释一下 EXIT外部中断的功能

 

一、EXIT控制原理

STM32笔记之 EXIT(外部中断)

 

二、外部中断的 I/O映像

STM32笔记之 EXIT(外部中断)

从上面图中我们可以发现,每一组端口都对应着相应的 “ 线 ”,先称之为线吧!

STM32笔记之 EXIT(外部中断)

其中,还有 4条 EXIT线是特殊的,看上图

 

三、中断服务

#define EXTI_Line0       ((uint32_t)0x00001)  /*!< External interrupt line 0 */
#define EXTI_Line1       ((uint32_t)0x00002)  /*!< External interrupt line 1 */
#define EXTI_Line2       ((uint32_t)0x00004)  /*!< External interrupt line 2 */
#define EXTI_Line3       ((uint32_t)0x00008)  /*!< External interrupt line 3 */
#define EXTI_Line4       ((uint32_t)0x00010)  /*!< External interrupt line 4 */
#define EXTI_Line5       ((uint32_t)0x00020)  /*!< External interrupt line 5 */
#define EXTI_Line6       ((uint32_t)0x00040)  /*!< External interrupt line 6 */
#define EXTI_Line7       ((uint32_t)0x00080)  /*!< External interrupt line 7 */
#define EXTI_Line8       ((uint32_t)0x00100)  /*!< External interrupt line 8 */
#define EXTI_Line9       ((uint32_t)0x00200)  /*!< External interrupt line 9 */
#define EXTI_Line10      ((uint32_t)0x00400)  /*!< External interrupt line 10 */
#define EXTI_Line11      ((uint32_t)0x00800)  /*!< External interrupt line 11 */
#define EXTI_Line12      ((uint32_t)0x01000)  /*!< External interrupt line 12 */
#define EXTI_Line13      ((uint32_t)0x02000)  /*!< External interrupt line 13 */
#define EXTI_Line14      ((uint32_t)0x04000)  /*!< External interrupt line 14 */
#define EXTI_Line15      ((uint32_t)0x08000)  /*!< External interrupt line 15 */
#define EXTI_Line16      ((uint32_t)0x10000)  /*!< External interrupt line 16 Connected to the PVD Output */
#define EXTI_Line17      ((uint32_t)0x20000)  /*!< External interrupt line 17 Connected to the RTC Alarm event */
#define EXTI_Line18      ((uint32_t)0x40000)  /*!< External interrupt line 18 Connected to the USB Device/USB OTG FS
                                                   Wakeup from suspend event */                                    
#define EXTI_Line19      ((uint32_t)0x80000)  /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */

以上的 EXIT线的宏都可以在 stm32f10x_exti.h文件中找到

 

STM32笔记之 EXIT(外部中断)

STM32笔记之 EXIT(外部中断)

STM32笔记之 EXIT(外部中断)

STM32笔记之 EXIT(外部中断)

上图的中断函数表可以在参考手册中找到,下面用一个表格来整合官方划分的中断函数

I/O 口外部中断函数 中断线
EXTI0_IRQHandler EXIT0 Line
EXTI1_IRQHandler EXIT1 Line
EXTI2_IRQHandler EXIT2 Line
EXTI3_IRQHandler EXIT3 Line
EXTI4_IRQHandler EXIT4 Line
EXTI9_5_IRQHandler EXIT5 - 9 Line
EXTI15_10_IRQHandler EXIT10 - 15 Line

因为在官方提供的 stm32f10x_it.c文件中,所列出来的中断函数只有下图的部分重要的中断,其他外设中断函数需要我们自己添加

STM32笔记之 EXIT(外部中断)

外设的中断需要我们自己添加,官方在 stm32f10x_it.c文件的底部也有注释说明,看下图

STM32笔记之 EXIT(外部中断)

 

四、配置流程(代码解析)

在上一篇配置 Key输入检测的代码中,如下进行配置

STM32笔记之 EXIT(外部中断)

其中,上图框选的部分是跟 EXIT是相关联的,你可能会问 NVIC是干嘛的,别急,下篇再解释;

在分析 EXTI函数之前先来了解一下两个组定义

/** 
  * @brief  EXTI Trigger enumeration  
  */

typedef enum
{
  EXTI_Trigger_Rising = 0x08,          // 上升沿触发
  EXTI_Trigger_Falling = 0x0C,         // 下降沿触发
  EXTI_Trigger_Rising_Falling = 0x10   // 上下沿触发
}EXTITrigger_TypeDef;
/** 
  * @brief  EXTI Init Structure definition  
  */

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;

 

1、GPIO_EXTILineConfig() 函数

/* Connect EXTI1 Line to PB.01 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);    // 将 EXTI1线连接到 PB.01引脚

↓↓ 函数实现 ↓↓

/**
  * @brief  Selects the GPIO pin used as EXTI Line.
  * @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.
  *   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).
  * @param  GPIO_PinSource: specifies the EXTI line to be configured.
  *   This parameter can be GPIO_PinSourcex where x can be (0..15).
  * @retval None
  */
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{
  uint32_t tmp = 0x00;
  /* Check the parameters */
  assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));
  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  
  tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));
  AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;
  AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}

2、EXTI_Init()函数

/* Configure EXTI1 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line1;              // 选着 EXIT1线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;     // 配置为输入模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;               // 使能 EXIT1线
EXTI_Init(&EXTI_InitStructure);

↓↓ 函数实现 ↓↓

/**
  * @brief  Initializes the EXTI peripheral according to the specified
  *         parameters in the EXTI_InitStruct.
  * @param  EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
  *         that contains the configuration information for the EXTI peripheral.
  * @retval None
  */
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
{
  uint32_t tmp = 0;

  /* Check the parameters */
  assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
  assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
  assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));  
  assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));

  tmp = (uint32_t)EXTI_BASE;
     
  if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)
  {
    /* Clear EXTI line configuration */
    EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;
    EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;
    
    tmp += EXTI_InitStruct->EXTI_Mode;

    *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;

    /* Clear Rising Falling edge configuration */
    EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;
    EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;
    
    /* Select the trigger for the selected external interrupts */
    if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)
    {
      /* Rising Falling edge */
      EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
      EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
    }
    else
    {
      tmp = (uint32_t)EXTI_BASE;
      tmp += EXTI_InitStruct->EXTI_Trigger;

      *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
    }
  }
  else
  {
    tmp += EXTI_InitStruct->EXTI_Mode;

    /* Disable the selected external lines */
    *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;
  }
}

3、EXTI_GenerateSWInterrupt()函数

/* Generate software interrupt: simulate a falling edge applied on EXTI1 line */
EXTI_GenerateSWInterrupt(EXTI_Line1);    // 生成软件中断:模拟应用于 EXTI1线路的下降沿

↓↓ 函数实现 ↓↓

/**
  * @brief  Generates a Software interrupt.
  * @param  EXTI_Line: specifies the EXTI lines to be enabled or disabled.
  *   This parameter can be any combination of EXTI_Linex where x can be (0..19).
  * @retval None
  */
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
{
  /* Check the parameters */
  assert_param(IS_EXTI_LINE(EXTI_Line));
  
  EXTI->SWIER |= EXTI_Line;
}

 

五、中断函数处理

/**
  * @brief  This function handles External line 1 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI1_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line1) != RESET)      // 检测 EXIT线路是否触发
	{
		/* Clear the  EXTI line 1 pending bit */
		EXTI_ClearITPendingBit(EXTI_Line1);        // 清除 EXIT线路触发标志
	}
}

 

相关标签: STM32