《零死角玩转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   */
时间: 2024-10-23 12:58:59

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

第17章 EXTI—外部中断/事件控制器

上一章节我们已经详细介绍了NVIC,对STM32F7xx中断管理系统有个全局的了解,我们这章的内容是NVIC的实例应用,也是STM32F7xx控制器非常重要的一个资源.学习本章时,配合<STM32F76xxx参考手册>系统配置控制器以及中断和事件章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分. 特别说明,本书内容是以STM32F767xx系列控制器资源讲解. 17.1  EXTI简介 外部中断/事件控制器(EXTI)管理了控制器的25个中断/事件线.每个中断/事件线都对应有一个边沿检测

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

参考资料:<STM32F4XX内核参考手册>:4.4.8-SHPRX(System Handler Priority Register)与4.5- System Tick Timer. 1. 简介 SysTick是一个24Bit的系统定时器,属于CM4内核的外设,相关寄存器与部分库函数中core_cm4.h中定义.SysTick一般用于操作系统,用于产生时基,维持OS的心跳. 如下所示:当计数器被使能(STC_CTRL: Bit0-ENABLE)并且计数器到0时,STK_LOAD中的预设值会被

《零死角玩转STM32》中的C语言之指针

关于Pointer,一定要杜绝"野指针"!下面的代码中定义了一个指向NVIC_InitTypeDef结构体类型的指针,但是并没有用"一块内存地址"来初始化该指针,因此是一个野指针! 由于没有被初始化,该指针可能指向内存的任何地方,包括0X00000000,由此带来的后果是对该指针的一切间接引用都是非法的,很有可能修改内存中代码区/数据区的数据.一定要杜绝使用这种指针! static void EXTI_NVIC_Config(void){ NVIC_InitType

第12章 GPIO输入-按键检测—零死角玩转STM32-F429系列

第12章 ????GPIO输入-按键检测 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ? 本章参考资料:<STM32F4xx参考手册>.库帮助文档<stm32f4xx_dsp_stdperiph_lib_um.chm>. 按键检测使用到GPIO外设的基本输入功能,本章中不再赘述GPIO外设的概念,如您忘记了,可重读前面"GPIO框图剖析"小

第14章 启动文件详解—零死角玩转STM32-F429系列

第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料<STM32F4xx 中文参考手册>第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表:MDK中的帮助手册—ARM Development Tools:用来查询ARM的汇编指令和编译器相关的指令. 14.1 启动文件简介 启动文件由汇编编写,是

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

第40章     CAN-通讯实验 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料:<STM32F4xx 中文参考手册2>.<STM32F4xx规格书>.库帮助文档<stm32f4xx_dsp_stdperiph_lib_um.chm>. 若对CAN通讯协议不了解,可先阅读<CAN总线入门>.<CAN-bus规范>

第9章 初识STM32固件库—零死角玩转STM32-F429系列

第9章 ????初识STM32固件库 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ? 本章参考资料:<STM32F4xx参考手册>.<STM32F4xx规格书>.<Cortex-M3权威指南>, STM32标准库帮助文档:<stm32f4xx_dsp_stdperiph_lib_um.chm>. 在上一章中,我们构建了几个控制GPIO外

第11章 GPIO输出-使用固件库点亮LED—零死角玩转STM32-F429系列

第11章 ????GPIO输出-使用固件库点亮LED 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ? 本章参考资料:<STM32F4xx参考手册>.库帮助文档<stm32f4xx_dsp_stdperiph_lib_um.chm>. 利用库建立好的工程模板,就可以方便地使用STM32标准库编写应用程序了,可以说从这一章我们才开始迈入STM32开发的大门. LE

第8章 自己写库-构建库函数雏形—零死角玩转STM32-F429系列

第8章 ????自己写库-构建库函数雏形 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ? 本章参考资料:<STM32F4xx 中文参考手册>.<STM32F429规格书> 虽然我们上面用寄存器点亮了 LED,乍看一下好像代码也很简单,但是我们别侥幸以后就可以一直用寄存器开发.在用寄存器点亮 LED 的时候,我们会发现 STM32 的寄存器都是 32 位的,每次