STM32那点事(3)_中断(下)

上节主要讲述了STM32 的中断基础知识以及一般配置过程。外部中断与其他模块中断相对要复杂一点。外部中断一般都是由GPIO触发,是在整个系统中需要经常用到。

介绍

STM32F4 有多达23个中断,每个中断都由相应的单独寄存器进行配置,也可以单独进行屏蔽相关不影响。每个GPIO都可以设置成中断输入线,占用Ext0 至 Exit1 15, 示意图如下:

STM32 有多少达140个GPIO,被分别按照A~I分成16组, 由上图可知 GPIO按照组被分到EXTI0~Exit15 16个中断,每个中断内的GPIO所有编号在组内都是一样,只是分布在不同的组内,除了上述16个中断,还有其他7个外部中断(如下图所示),共有23个中断。

EXIT 中断/事件
中断/事件线输入中断源
EXIT0PA0,PB0,PC0,PD0,PE0,PF0,PG0,PH0,PI0
EXIT1PA1,PB1,PC1,PD1,PE1,PF1,PG1,PH1,PI1
EXIT2PA2,PB2,PC2,PD2,PE2,PF2,PG2,PH2,PI2
EXIT3PA3,PB3,PC3,PD3,PE3,PF3,PG3,PH3,PI3
EXIT4PA4,PB4,PC4,PD4,PE4,PF4,PG4,PH4,PI4
EXIT5PA5,PB5,PC5,PD5,PE5,PF5,PG5,PH5,PI5
EXIT6PA6,PB6,PC6,PD6,PE6,PF6,PG6,PH6,PI6
EXIT7PA7,PB7,PC7,PD7,PE7,PF7,PG7,PH7,PI7
EXIT8PA8,PB8,PC8,PD8,PE8,PF8,PG8,PH8,PI8
EXIT9PA9,PB0,PC9,PD9,PE9,PF9,PG9,PH9,PI9
EXIT10PA10,PB10,PC10,PD10,PE10,PF10,PG10,PH10,PI10
EXIT11PA11,PB11,PC11,PD11,PE11,PF11,PG11,PH11,PI1
EXIT12PA12,PB12,PC12,PD12,PE12,PF12,PG12,PH12,PI2
EXIT13PA13,PB13,PC13,PD13,PE13,PF13,PG13,PH13,PI13
EXIT14PA14,PB14,PC14,PD14,PE14,PF14,PG14,PH14,PI14
EXIT15PA15,PB15,PC15,PD15,PE15,PF15,PG15,PH15,PI15
EXIT16PVD输出
EXIT17RTS闹钟事件
EXIT18USB OTG FS唤醒司机
EXIT19以太网唤醒事件
EXIT20USB OTG HS唤醒事件
EXIT21RTC入侵和事件搓戳事件
EXIT22RTC唤醒事件

 EXTI 挂载总线

EXTI在STM32 总线位置如下图所示:

EXTI中断挂载在APB2总线上,故要使用EXIT中断就要先使能APB2 时钟。

EXTI框架 

EXTI框架(如下图所示),图中的23数字为23根中断,每根一个单独单独寄存器相互不影响。

 

由中断框架图可以看出,中断模块有两个输出:

    1:至NVIC中断控制器,通知内核产生一个中断。

    2:通过脉冲发生器产生一个脉冲(事件)

上述两种功能互斥不可同时使用,故EXIT称为EXIT中断/事件模块,即可以产生一个中断,也可以当作发生一个事件。整个EXTI框架中分成两个流程:中断和事件。下面将按照这两个流程发生过程分布做介绍:

EXTI中断

EXTI中断流程是开发过程中经常使用到的,主要分成6步。

上图是整个中断的产生流程: 

1:为中断输入,EXIT控制器可以通过配置 SYSCFG_EXTICRX(1~4)寄存器确定相应GPIO对应相应中断,确定中断源是哪个GPIO:

由上述寄存器可知,每个EXTI中断配置占4bit,最多配置16个GPIO配置,实际STM32F只有9组,每个寄存器可以配置4个EXTI,共有16EXTI中断,故SYSCFG_EXTICR系列寄存器有4个。配置给寄存器,STM32提供给官方API,其内部实现如下:

/**
  * @brief  Selects the GPIO pin used as EXTI Line.
  * @param  EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for
  *          EXTI lines where x can be (A..K) for STM32F42xxx/43xxx devices, (A..I) 
  *          for STM32F405xx/407xx and STM32F415xx/417xx devices or (A, B, C, D and H)
  *          for STM32401xx devices.  
  *            
  * @param  EXTI_PinSourcex: specifies the EXTI line to be configured.
  *           This parameter can be EXTI_PinSourcex where x can be (0..15, except
  *           for EXTI_PortSourceGPIOI x can be (0..11) for STM32F405xx/407xx
  *           and STM32F405xx/407xx devices and for EXTI_PortSourceGPIOK x can   
  *           be (0..7) for STM32F42xxx/43xxx devices. 
  *             
  * @retval None
  */
void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)
{
  uint32_t tmp = 0x00;

  /* Check the parameters */
  assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx));
  assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex));

  tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03));
  SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp;
  SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)));
}

2:配置中断边沿检测电路,配置中断是上升沿触发(EXTI_RTSR)还是下降沿触发(EXTI_FTSR), 如果中断触发之后信中断信号将传递到3. 

由表可知 EXTI_RTSR和EXTI_FTSR寄存器每个EXTI占1bit, 禁止,1允许,两个寄存器不能同时设置1.

3:中断发生后,传递给3.3部分实际上是一个或门电路,与软件中断寄存器求与操作。可以通过配置软件中断事件寄存器(EXTI_SWIER),来控制是否启动中断。

也可以通过手动配置寄存,来触发一个软件中断,其官方API:

/**
  * @brief  Generates a Software interrupt on selected EXTI line.
  * @param  EXTI_Line: specifies the EXTI line on which the software interrupt
  *         will be generated.
  *         This parameter can be any combination of EXTI_Linex where x can be (0..22)
  * @retval None
  */
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
{
  /* Check the parameters */
  assert_param(IS_EXTI_LINE(EXTI_Line));
  
  EXTI->SWIER |= EXTI_Line;
}

4:当来自 3的中断到达4后,将会与中断屏蔽寄存器(EXTI_IMR)求与,用来确定该中断是否屏蔽,如果该中断被屏蔽将不会进入到下一步

 5:当中断进入到4后没有被屏蔽,中断将进入到挂起请求寄存器():

当中断发生后,中断将会挂起。在中断函数处理完之后,每次都要将其清除为0,才能够使下次中断到来,代表“这次中断处理完成,可以来下次中断”,主要是用来防止 “处理该中断过程中,中断处理函数还没有处理完这次中断,又重新触发新的中断”。 官网固件API为

void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
{
  /* Check the parameters */
  assert_param(IS_EXTI_LINE(EXTI_Line));
  
  EXTI->PR = EXTI_Line;
}

6: 上次中断被清理后,这次中断可以发生,中断将被送到NVIC 

EXTI事件 

 EXTI事件主要流程如下,其主要过程和EXTI中断类似,限于篇幅不在详述

EXTI配置用例 

以官方提供的固件用例讲解配置过程,配置PA0为外部中断,上升沿触发,代码如下:

static void EXTILine0_Config(void)
{
  EXTI_InitTypeDef   EXTI_InitStructure;
  GPIO_InitTypeDef   GPIO_InitStructure;
  NVIC_InitTypeDef   NVIC_InitStructure;

  /* Enable GPIOA clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  /* Enable SYSCFG clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  
  /* Configure PA0 pin as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Connect EXTI Line0 to PA0 pin */
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

  /* Configure EXTI Line0 */
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI Line0 Interrupt to the lowest priority */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

1:使能 PA0和 EXIT挂载总线时钟,分别为AHB1和APB 总线

2:配置GPIO PA0端口为输入模式

3:配EXTI Line0的中断为PA0

4: 配置EXTI0中断触发模式,并使能

5:通过NVIC使能EXTI0_IRQn,并配置优先级

中断处理函数如下:

/**
  * @brief  This function handles External line 0 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI0_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  {
    /**EXIT0 process***/
    
    /* Clear the EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line0);
  }
}

参考文档

 

《 零死角玩转STM32》
《STM32F4XX中文参考手册》
《arm体系结构与编程》 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Huo的藏经阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值