zoukankan      html  css  js  c++  java
  • STM32(五)- NVIC与EXTI

    一、NVIC

                           中断结构框图

    向量表

    中断类型:

    (1)系统异常,体现在内核水平

    (2)外部中断,体现在外设水平

    NVIC:嵌套向量中断控制器,控制整个芯片中断相关的功能,跟内核紧密耦合管理包括内核和片上所有外设的中断相关功能。内核外设。各芯片厂商在设计芯片是会对Cortex-M3内核里面的NVIC进行裁剪,去掉不需要部分,STM32的NVIC是Contex-M3d NVIC的一个子集。

    两个重要库文件:core_cm3.h(内核外设的寄存器定义)和misc.h

     1 typedef struct
     2 {
     3   __IO uint32_t ISER[8];                      /*!< Offset: 0x000  Interrupt Set Enable Register/中断使能寄存器 */
     4        uint32_t RESERVED0[24];                                   
     5   __IO uint32_t ICER[8];                      /*!< Offset: 0x080  Interrupt Clear Enable Register/中断清除寄存器 */
     6        uint32_t RSERVED1[24];                                    
     7   __IO uint32_t ISPR[8];                      /*!< Offset: 0x100  Interrupt Set Pending Register/中断使能悬起寄存器 */
     8        uint32_t RESERVED2[24];                                   
     9   __IO uint32_t ICPR[8];                      /*!< Offset: 0x180  Interrupt Clear Pending Register/中断清除悬起寄存器 */
    10        uint32_t RESERVED3[24];                                   
    11   __IO uint32_t IABR[8];                      /*!< Offset: 0x200  Interrupt Active bit Register/中断有效位寄存器           */
    12        uint32_t RESERVED4[56];                                   
    13   __IO uint8_t  IP[240];                      /*!< Offset: 0x300  Interrupt Priority Register (8Bit wide)/中断优先级寄存器(8位) */
    14        uint32_t RESERVED5[644];                                  
    15   __IO  uint32_t STIR;                         /*!< Offset: 0xE00  Software Trigger Interrupt Register/软件触发中断寄存器 */
    16 }  NVIC_Type;                 

     注:配置中断时,一般只用ISER(使能中断)、ICER(失能中断)、IP(设置中断优先级)

     优先级和优先级分组

    中断优先级分组库函数

    优先级分组真值表

    中断编程

     配置每个中断时,一般有三个编程要点:

    1、使能某个外设中断,这个具体由每个外设的相关中断使能位控制。参照中断向量表配置

    2、初始化NVIC_InitTypeDef结构体,配置中断源,配置中断优先级分组,设置抢占优先级和子优先级,使能中断请求。NVIC_InitTypeDef结构体在固件库头文件misc.h中定义。

    NVIC_InitTypeDef结构体成员变量分析:

    (1)NVIC_IRQChannel:配置中断源,不同中断的中断源是不一样的。参考stm32f10x.h头文件里的IRQn_Type结构体定义,该结构体包含了所有的中断源。

     1 typedef enum IRQn
     2 {
     3 /******  Cortex-M3 Processor Exceptions Numbers ***************************************************/
     4   NonMaskableInt_IRQn         = -14,    /*!< 2 Non Maskable Interrupt                             */
     5   MemoryManagement_IRQn       = -12,    /*!< 4 Cortex-M3 Memory Management Interrupt              */
     6   BusFault_IRQn               = -11,    /*!< 5 Cortex-M3 Bus Fault Interrupt                      */
     7   UsageFault_IRQn             = -10,    /*!< 6 Cortex-M3 Usage Fault Interrupt                    */
     8   SVCall_IRQn                 = -5,     /*!< 11 Cortex-M3 SV Call Interrupt                       */
     9   DebugMonitor_IRQn           = -4,     /*!< 12 Cortex-M3 Debug Monitor Interrupt                 */
    10   PendSV_IRQn                 = -2,     /*!< 14 Cortex-M3 Pend SV Interrupt                       */
    11   SysTick_IRQn                = -1,     /*!< 15 Cortex-M3 System Tick Interrupt                   */
    12 
    13 /******  STM32 specific Interrupt Numbers *********************************************************/
    14   WWDG_IRQn                   = 0,      /*!< Window WatchDog Interrupt                            */
    15   PVD_IRQn                    = 1,      /*!< PVD through EXTI Line detection Interrupt            */
    16   TAMPER_IRQn                 = 2,      /*!< Tamper Interrupt                                     */
    17   RTC_IRQn                    = 3,      /*!< RTC global Interrupt                                 */
    18   FLASH_IRQn                  = 4,      /*!< FLASH global Interrupt                               */
    19   RCC_IRQn                    = 5,      /*!< RCC global Interrupt                                 */
    20   EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                                 */
    21   EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                                 */
    22   EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                                 */
    23   EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                                 */
    24   EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                                 */
    25   DMA1_Channel1_IRQn          = 11,     /*!< DMA1 Channel 1 global Interrupt                      */
    26   DMA1_Channel2_IRQn          = 12,     /*!< DMA1 Channel 2 global Interrupt                      */
    27   DMA1_Channel3_IRQn          = 13,     /*!< DMA1 Channel 3 global Interrupt                      */
    28   DMA1_Channel4_IRQn          = 14,     /*!< DMA1 Channel 4 global Interrupt                      */
    29   DMA1_Channel5_IRQn          = 15,     /*!< DMA1 Channel 5 global Interrupt                      */
    30   DMA1_Channel6_IRQn          = 16,     /*!< DMA1 Channel 6 global Interrupt                      */
    31   DMA1_Channel7_IRQn          = 17,     /*!< DMA1 Channel 7 global Interrupt                      */
    32 #ifdef STM32F10X_HD
    33   ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
    34   USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
    35   USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
    36   CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
    37   CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
    38   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
    39   TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
    40   TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
    41   TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
    42   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
    43   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
    44   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
    45   TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
    46   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
    47   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
    48   I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
    49   I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
    50   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
    51   SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
    52   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
    53   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
    54   USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
    55   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
    56   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
    57   USBWakeUp_IRQn              = 42,     /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
    58   TIM8_BRK_IRQn               = 43,     /*!< TIM8 Break Interrupt                                 */
    59   TIM8_UP_IRQn                = 44,     /*!< TIM8 Update Interrupt                                */
    60   TIM8_TRG_COM_IRQn           = 45,     /*!< TIM8 Trigger and Commutation Interrupt               */
    61   TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare Interrupt                       */
    62   ADC3_IRQn                   = 47,     /*!< ADC3 global Interrupt                                */
    63   FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                */
    64   SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                */
    65   TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
    66   SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
    67   UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
    68   UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
    69   TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
    70   TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
    71   DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
    72   DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
    73   DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
    74   DMA2_Channel4_5_IRQn        = 59      /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
    75 #endif /* STM32F10X_HD */  
    76 } IRQn_Type;

    (2)NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定。

    (3)NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定。

    (4)NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。操作的是NVIC_ISER和NVIC_ICER这两个寄存器。

     1 static void NVIC_Configuration(void)
     2 {
     3 NVIC_InitTypeDef NVIC_InitStructure;
     4 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);          /* 配置 NVIC 为优先级组 1 */
     5 NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;  /* 配置中断源:按键 1 */
     6 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/* 配置抢占优先级: 1 */
     7 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;       /* 配置子优先级: 1 */
     8 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          /* 使能中断通道 */
     9 NVIC_Init(&NVIC_InitStructure);
    10 }

     3、编写中断服务函数

    在启动文件 startup_stm32f10x_hd.s 中预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写, 为了方便管理我们把中断服务函数统一写在 stm32f10x_it.c 这个库文件中。关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。 

     二、EXTI

    EXTIExternal interrupt/event controller) —外部中断/事件控制器, 管理了控制器的 20
    个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿
    检测和下降沿的检测。 EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为
    中断或者事件,以及触发事件的属性。

    注:EXTI实际上主要就是为GPIO(PX0~PX15(X=A B C D E F G H I))服务的,除此之外还有PVD输出、RTC闹钟事件、USB唤醒事件、以太网唤醒事件(只适合互联型)

                                                                     EXTI功能图

    注:20个信号线路与EXTI的20个中断/事件线是对应的。EXTI两大功能:(1)产生中断(2)产生事件

    红色虚线:

    编号1是输入线输入线通过寄存器可设置为任意一个 GPIO,也可以是一些外设的事件,输入线一般是存在电平变化的信号。

    编号2 是一个边沿检测电路,它会根据上升沿触发选择寄存器(EXTI_RTSR)下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。

    边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号 1(逻辑1) 给编号 3 电路,否则输出无效信号0(逻辑0)

    编号 3 电路实际就是一个或门电路,一个输入来自编号 2 电路,另外一个输入来自软件中断事件寄存器(EXTI_SWIER)EXTI_SWIER 允许

    我们通过程序控制就可以启动中/事件线。这两个输入随便一个信号为有效信号 1就可以输出 1 给编号 4 和编号 6 电路。

    编号 4 电路是一个与门电路,一个输入是编号 3 电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR)如果 EXTI_IMR 设置为 1 时,最终编号 4 电路

    输出的信号才由编号 3 电路的输出信号决定,这样我们可以简单的控制 EXTI_IMR来实现是否产生中断的目的。编号 4 电路输出的信号会被保存到

    挂起寄存器(EXTI_PR)内,如果确定编号 4 电路输出为 1 就会把 EXTI_PR 对应位置 1

    编号 5 是将 EXTI_PR 寄存器内容输出到 NVIC 内,从而实现系统中断事件控制。

    绿色虚线:(它是一个产生事件的线路,最终输出一个脉冲信号)

    产生事件线路是在编号 3 电路之后与中断线路有所不同,之前电路都是共用的。

    编号6 电路是一个与门,一个输入来自编号 3 电路,另外一个输入来自事件屏蔽寄存器(EXTI_EMR)如果EXTI_EMR 设置为 1 时,最终编号 6 电路输出的信号

    才由编号 3 电路的输出信号决定,这样我们可以简单的控制 EXTI_EMR 来实现是否产生事件的目的。

    编号 7 是一个脉冲发生器电路,当编号 6 电路输出一个有效信号 1 时就会产生一个脉冲。

    编号 8 是一个脉冲信号,产生事件的线路的最终产物,这个脉冲信号可以给其他外设电路使用,比如定时器 TIM、模拟数字转换器 ADC 等,这样的脉冲信号一般用来触发 TIM 或者 ADC 开始转换。

    小结:产生中断的线路(红色)目的是把输入信号输入到 NVIC,进一步运行中断服务函数,实现功能,这是软件级的。

    而产生事件线路(绿色)目的就是传输一个脉冲信号给其他外设使用,是电路级别的信号传输,属于硬件级的。

    除此还需注意EXTI是挂在APB2总线上的。 

     

    EXTI有20个中断/事件线,GPIO设置为输入线占用16根线EXTI0~EXTI15,还有4根线用于特定的外设事件(由外设触发)。

     

    输入源选择,以EXTI0为例,EXTI0可以通过APIO的外部中断配置寄存器1(AFIO_EXTICR1)的EXTI0[3:0]为选择配置为PA0、PB0、PC0、PD0、PE0、PF0、PG0、PH0、PI0。

    EXTI初始化结构体

    标准库函数对每个外设都建立了一个初始化结构体,EXTI对应为EXTI_InitTypeDef,结构体成员用于设置外设工作参数(配置外设相应的寄存器),并由外设初始化配置函数调用。

    初始化结构体定义在 stm32f10x_exti.h 文件中,初始化库函数定义在 stm32f10x_exti.c 文件中,编程时我们可以结合这两个文件内注释使用。 

    EXTI_InitTypeDef成员变量分析:

    (1)EXTI_Line:EXTI中断/事件线选择。

    (2)EXTI_Mode:EXTI模式选择,产生中断(EXTI_Mode_Interrupt)或者产生事件(EXTI_Mode_Event)。

    (3)EXTI_Trigger:触发类型。EXTI 边沿触发事件,上升沿触发(EXTI_Trigger_Rising)、下降沿触发(EXTI_Trigger_Falling)、上升沿和下降沿都触发(EXTI_Trigger_Rising_Falling)。 

    (4)EXTI_LineCmd:控制是否使能EXTI线,使能 EXTI 线(ENABLE)、禁用(DISABLE)。 

    EXTI编程:

    (1)初始化用来产生中断的GPIO。

    (2)初始化EXTI。

    (3)配置NVIC。

    (4)编写中断服务函数。

    7

  • 相关阅读:
    iOS 苹果开发证书失效的解决方案(Failed to locate or generate matching signing assets)
    iOS NSArray数组过滤
    App Store2016年最新审核规则
    iOS 根据字符串数目,自定义Label等控件的高度
    iOS 证书Bug The identity used to sign the executable is no longer valid 解决方案
    Entity FrameWork 增删查改的本质
    EF容器---代理类对象
    Entity FrameWork 延迟加载本质(二)
    Entity FrameWork 延迟加载的本质(一)
    Entity FrameWork 增删查改
  • 原文地址:https://www.cnblogs.com/wuguangzong/p/10887611.html
Copyright © 2011-2022 走看看