《零死角玩转STM32》-17-EXTI外部中断/事件控制器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《零死角玩转STM32》-17-EXTI外部中断/事件控制器相关的知识,希望对你有一定的参考价值。

/*

* 本文中的相关图片来自火哥的教程,只作为随笔记录,无侵权之意

* 21:25:46, 2017-04-08

*/

EXTI:外部中断/事件控制器。STM32F429共有23根,其中EXTI0~EXTI15,分别对应GPIO中的PX0 ~ PX15,另外7根线有如下用途:

技术分享

(中间省略了EXTI1 ~ EXTI15)

技术分享

 

 EXTI功能框图如下所示:

技术分享

 

按照图中的序号标识,可以清晰的看出外部GPIO引脚上的电平变化是如何传递到内核,即GPIO -> EXTI -> NVIC,并触发相应的中断/事件。NVIC属于内核上的外设,EXTI和GPIO同属于STM32F4XX的片上外设。

举例:按键触发中断控制LED亮灭

分析:分别从GPIO, EXTI以及NVIC和最后的ISR部分,来构建整个程序的功能

如果我们需要使用EXTI和GPIO这两个外设,第一步就需要中RCC(Reset & Clock Control)相关寄存器中使能(ENABLE)相应的时钟,因此需要分别使能实际用到的GPIOA-I中的一个或多个端口时钟;使能EXTI时钟

RCC_AHB1PeriphClockCmd (KEY2_GPIO_CLK, ENABLE);    
RCC_APB2PeriphClockCmd (RCC_APB2Periph_SYSCFG, ENABLE); 

接下来需要配置GPIO的引脚各寄存器,比如输入输出,上下拉等,之后可以调用固件库函数GPIO_Init(Init_Struct)进行初始化。

现在,引脚的相关工作模式已经配置好,如何把PIN与EXTI进行关联?STM32F4有如下说明:

技术分享

即通过配置寄存器SYSCFG_EXTICRx,可以实现GPIO与EXTI的映射,参考stm32f4xx_syscfg.c  Example:

SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);

 

接下来就是需要初始化EXTI相关的寄存器,同样最后也是调用EXTI_Init函数对EXTI寄存器进行初始化。

1    // EXTI_DeInit();
2     EXTI_KEY1_InitStruct.EXTI_Line     = EXTI_Line0;
3     EXTI_KEY1_InitStruct.EXTI_Trigger  = EXTI_Trigger_Rising;
4     EXTI_KEY1_InitStruct.EXTI_Mode     = EXTI_Mode_Interrupt;
5     EXTI_KEY1_InitStruct.EXTI_LineCmd  = ENABLE;
6     
7     /*Initiallize the EXTI*/
8     EXTI_Init(&EXTI_KEY1_InitStruct);

之后进行NVIC初始化,NVIC是嵌套向量中断控制器,掌管着包括内核异常(EXCEPTION)和外部中断(INTERRPUT)在内的相关功能。其中初始化部分,主要包括:确定中断源,确定抢占优先级,确定子优先级,是否使能NVIC_IRQChannel中指定的中断源。 

@note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() function should be called before NVIC_Init() function.

1     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
2     
3     NVIC_InitStruct ->NVIC_IRQChannel                   = EXTI0_IRQn;
4     NVIC_InitStruct ->NVIC_IRQChannelPreemptionPriority = 1;
5     NVIC_InitStruct ->NVIC_IRQChannelSubPriority        = 1;
6     NVIC_InitStruct ->NVIC_IRQChannelCmd                = ENABLE;
7 
8     /* 调用固件库NVIC初始化函数 - misc.c */    
9     NVIC_Init(NVIC_InitStruct);

最后需要装stm32f4xx_it.c中编写相应的ISR

 1 /**
 2   * @brief  This function handles EXTI0 Handler
 3   * @param  None
 4   * @retval None
 5   */ 
 6 void EXTI0_IRQHandler(void){
 7     if(EXTI_GetITStatus(EXTI_Line0) != RESET){
 8         LED1_TOGGLE;   
 9         EXTI_ClearITPendingBit(EXTI_Line0);
10     }
11 }

 

附:bsp_exti.c

  1 #include "bsp_exti.h"
  2 #include "stm32f4xx.h"
  3 
  4 /**
  5 *   Four Steps to Config A Key Related EXTI Interrupt
  6 *       S1: Initiallize the GPIOA, PA0
  7 *       S2:
  8 *       S3:
  9 *       S4:
 10 *
 11 */
 12 
 13 
 14 /**
 15 * @brief  S1:   Initiallize the KEY1: PA0.
 16   *             Initiallize the Key2: PC13
 17   * 
 18   * @note   .
 19   *      
 20   * @note   .
 21   *   
 22   * @param  NONE
 23   *          This parameter can be one of the following values:
 24   *            @arg 
 25   *            @arg 
 26   *            
 27   * @retval None
 28   */
 29 void EXTI_KEY_Config(void){
 30         EXTI_InitTypeDef EXTI_KEY1_InitStruct;
 31         GPIO_InitTypeDef GPIO_InitStructure;
 32 
 33         /*?a??KEY1, KEY2 ?à1?μ?GPIOíaéèê±?ó*/
 34         RCC_AHB1PeriphClockCmd (KEY1_GPIO_CLK, ENABLE); 
 35         RCC_AHB1PeriphClockCmd (KEY2_GPIO_CLK, ENABLE);    
 36         RCC_APB2PeriphClockCmd (RCC_APB2Periph_SYSCFG, ENABLE); 
 37     
 38     /*S3: Initiallize NVIC for EXTI0*/
 39         EXTI_NVIC_Config();
 40 
 41         /*????òa????μ?GPIOòy??*/                                                               
 42         GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;    
 43         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;   
 44         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 45 
 46         /*μ÷ó??aoˉêy£?ê1ó?é???????μ?GPIO_InitStructure3?ê??ˉGPIO*/
 47         GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);     
 48         
 49         /*  Init PC13 for KEY2*/
 50         GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;    
 51         GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);         
 52 
 53 /*
 54  * Set the SYSCFG_EXTICR1:  Connects PA0  with EXTI0
 55  *                          Connects PC13 with EXTI13
 56 */ 
 57     SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);
 58     SYSCFG_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE);
 59 
 60 /*S2: Initiallize the EXTI for KEY1 which connects to PA0*/
 61 
 62    // EXTI_DeInit();
 63     EXTI_KEY1_InitStruct.EXTI_Line     = EXTI_Line0;
 64     EXTI_KEY1_InitStruct.EXTI_Trigger  = EXTI_Trigger_Rising;
 65     EXTI_KEY1_InitStruct.EXTI_Mode     = EXTI_Mode_Interrupt;
 66     EXTI_KEY1_InitStruct.EXTI_LineCmd  = ENABLE;
 67     
 68     /*Initiallize the EXTI*/
 69     EXTI_Init(&EXTI_KEY1_InitStruct);
 70 
 71    // EXTI_DeInit();
 72     EXTI_KEY1_InitStruct.EXTI_Line     = EXTI_Line13;
 73     EXTI_KEY1_InitStruct.EXTI_Trigger  = EXTI_Trigger_Falling;
 74 
 75     EXTI_KEY1_InitStruct.EXTI_LineCmd  = ENABLE;
 76     EXTI_Init(&EXTI_KEY1_InitStruct);
 77     
 78 }/*END --EXTI_KEY_Config--*/
 79 
 80 
 81 /**
 82   * @brief  S3: Initiallize the NVIC in order to handle the interrupt
 83   * 
 84   * @note   .1 ê1?ü?D?????ó£¨í¨3£óéíaéè?à1???′??÷éè??£?
 85   *         .2 ?????D??ó??è??·?×飨NVIC_IPRX, SCB->AIRCR£?
 86   *         .3 3?ê??ˉNVIC_InitTypeDef
 87   *         .4 ±àD′ISR
 88   * @note   .
 89   *   
 90   * @param  NONE
 91   *          This parameter can be one of the following values:
 92   *            @arg 
 93   *            @arg 
 94   *            
 95   * @retval None
 96   */
 97 static void EXTI_NVIC_Config(void){
 98     
 99     NVIC_InitTypeDef NVIC_INIT_S;
100     NVIC_InitTypeDef *NVIC_InitStruct = &NVIC_INIT_S;
101     
102     /* .2 */
103     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
104     
105     NVIC_InitStruct ->NVIC_IRQChannel                   = EXTI0_IRQn;
106     NVIC_InitStruct ->NVIC_IRQChannelPreemptionPriority = 1;
107     NVIC_InitStruct ->NVIC_IRQChannelSubPriority        = 1;
108     NVIC_InitStruct ->NVIC_IRQChannelCmd                = ENABLE;
109 
110     /* .3 */    
111     NVIC_Init(NVIC_InitStruct);
112     
113     /*Following is for KEY2 PC13*/
114     NVIC_InitStruct ->NVIC_IRQChannel                   = EXTI15_10_IRQn;
115     NVIC_Init(NVIC_InitStruct);
116 }
117 
118 /**
119   * @brief  
120   * 
121   * @note   .
122   *      
123   * @note   .
124   *   
125   * @param  NONE
126   *          This parameter can be one of the following values:
127   *            @arg 
128   *            @arg 
129   *            
130   * @retval None
131   */

 

以上是关于《零死角玩转STM32》-17-EXTI外部中断/事件控制器的主要内容,如果未能解决你的问题,请参考以下文章

《零死角玩转STM32》-18-SysTick系统滴答定时器

第40章 CAN—通讯实验—零死角玩转STM32-F429系列

stm32固件库SPI操作

stm32 外部中断打断PWM

stm32 外部中断 能读gpio值吗

stm32外部按键中断无法退出中断问题