首页 > 技术文章 > stm32寄存器版学习笔记03 外部中断

kuotian 2016-05-25 15:02 原文

  stm32的每个I/O口都可以作为中断输入,要把I/O口设置为外部中断输入,必须将I/O口设置为上拉/下拉输入 或 浮空输入(但浮空的时候外部一定要带上拉或下拉电阻,否则可能导致 中断不停的触发),干扰大时,上拉/下拉输入模式也建议使用外部上拉/下拉电阻。

1.设置外部中断 的步骤

①初始化I/O口为输入

  参见 stm32寄存器版学习笔记01 GPIO口的配置

②开启I/O口复用时钟, 设置I/O口与中断线的映射关系

  这一步在函数void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 中已经封装好可直接调用。(有详细说明 在第2点)

  关于I/O口时钟复用

    APB2外设时钟使能寄存器(RCC_APB2ENR)

0位 I/O复用时钟使能

  Eg:RCC->APB2ENR|=0x01;//使能io复用时钟(已封装在Ex_NVIC_Config函数中)

③开启与该I/O口相对的线上中断/事件,设置触发条件

  stm32可以配置成上升沿触发、下降沿触发或任意电平变化触发。

  这一步封装在函数void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 中,可以直接调用。(有详细说明 在第2点)

typedef struct
{
  __IO uint32_t IMR;         //中断屏蔽寄存器
  __IO uint32_t EMR;         //事件屏蔽寄存器
  __IO uint32_t RTSR;        //上升沿触发选择寄存器
  __IO uint32_t FTSR;        //下降沿触发选择寄存器
  __IO uint32_t SWIER;       //软件中断事件寄存器
  __IO uint32_t PR;          //挂起寄存器
} EXTI_TypeDef;

  Eg:Ex_NVIC_Config(GPIO_A,0,RTIR); //设置PA0上升沿触发

         Ex_NVIC_Config(GPIO _C,13,FTIR);//设置PC13下降沿触发

     可以同时设置上升沿触发和下降沿触发,即任意电平变化触发

 

④配置中断分组(NVIC),并使能中断

  只有配置了NVIC的设置并开启才能被执行,否则不执行到中断服务函数中去。

  这一步封装在函数void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) 里面可以直接调用。 (在第3点 详细介绍)

  EG:MY_NVIC_Init(2,2,EXTI0_IRQn,2); //抢占2,子优先级2,组2

     MY_NVIC_Init(2,1,EXTI9_5_IRQn,2); //抢占2,子优先级1,组2

注意:stm32的外部中断0-4都有单独的中断服务函数,但是从5开始就没有单独的服务函数了,而是多个中断共用一个服务函数,比如外部中断5-9的中断服务函数为void EXTI9_5_IRQHandler(void),外部中断10-15的中断服务函数为void EXTI15_10_IRQHandler(void).

         每一位对应中断 from stm32f10x.h

⑤编写中断服务函数

  Eg://外部中断9~5服务程序

    void EXTI9_5_IRQHandler(void)
    {
      //add your code
      EXTI->PR=1<<5; //清除LINE5上的中断标志位
    }

2. 关于void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM)函数

 1 //外部中断配置函数
 2 //只针对GPIOA~G;不包括PVD,RTC和USB唤醒这三个
 3 //参数:
 4 //GPIOx:0~6,代表GPIOA~G
 5 //BITx:需要使能的位;
 6 //TRIM:触发模式,1,下升沿;2,上降沿;3,任意电平触发
 7 //该函数一次只能配置1个IO口,多个IO口,需多次调用
 8 //该函数会自动开启对应中断,以及屏蔽线           
 9 void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 
10 {
11     u8 EXTADDR;
12     u8 EXTOFFSET;
13     EXTADDR=BITx/4;//得到中断寄存器组的编号
14     EXTOFFSET=(BITx%4)*4; 
15     RCC->APB2ENR|=0x01;//使能io复用时钟             
16     AFIO->EXTICR[EXTADDR]&=~(0x000F<<EXTOFFSET);//清除原来设置!!!
17     AFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;//EXTI.BITx映射到GPIOx.BITx 
18     //自动设置
19     EXTI->IMR|=1<<BITx;//  开启line BITx上的中断
20     //EXTI->EMR|=1<<BITx;//不屏蔽line BITx上的事件 (如果不屏蔽这句,在硬件上是可以的,但是在软件仿真的时候无法进入中断!)
21      if(TRIM&0x01)EXTI->FTSR|=1<<BITx;//line BITx上事件下降沿触发
22     if(TRIM&0x02)EXTI->RTSR|=1<<BITx;//line BITx上事件上升降沿触发
23 }     

 

① EXTADDR 为计算的中段寄存器组号。AFIO->EXTICR[EXTADDR]。

    EXTOFFSET 为偏移地址,就是设置配置寄存器的第几位。

  外部中断配置寄存器1(AFIO_EXTICR1)

 

  外部中断配置寄存器2(AFIO_EXTICR2)

  外部中断配置寄存器3(AFIO_EXTICR3)

  外部中断配置寄存器4(AFIO_EXTICR4)

 

②中断屏蔽寄存器(EXTI_IMR)

  Eg:EXTI->IMR|=1<<BITx;// 开启line BITx上的中断

关于 line x

  

 

 

 

 

 

 

 

 

  事件屏蔽寄存器(EXTI_EMR)

 

  上升沿触发选择寄存器(EXTI_RTSR)

 

  下降沿触发选择寄存器(EXTI_FTSR)

Eg://TRIM:触发模式,1,下升沿;2,上降沿;3,任意电平触发

if(TRIM&0x01)EXTI->FTSR|=1<<BITx;//line BITx上事件下降沿触发
if(TRIM&0x02)EXTI->RTSR|=1<<BITx;//line BITx上事件上升降沿触发

TRIM = 3,即同时设置上升沿和下降沿触发,即任意电平变化触发。

  软件中断事件寄存器(EXTI_SWIER)

 

  挂起寄存器(EXTI_PR)

 

3. 关于void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) 函数

 1 //设置向量表偏移地址
 2 //NVIC_VectTab:基址
 3 //Offset:偏移量             
 4 void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)     
 5 {             
 6     SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//设置NVIC的向量表偏移寄存器
 7     //用于标识向量表是在CODE区还是在RAM区
 8 }
 9 //设置NVIC分组
10 //NVIC_Group:NVIC分组 0~4 总共5组            
11 void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)     
12 { 
13     u32 temp,temp1;      
14     temp1=(~NVIC_Group)&0x07;//取后三位
15     temp1<<=8;
16     temp=SCB->AIRCR;  //读取先前的设置
17     temp&=0X0000F8FF; //清空先前分组
18     temp|=0X05FA0000; //写入钥匙
19     temp|=temp1;       
20     SCB->AIRCR=temp;  //设置分组                                 
21 }
22 //设置NVIC 
23 //NVIC_PreemptionPriority:抢占优先级
24 //NVIC_SubPriority       :响应优先级
25 //NVIC_Channel           :中断编号
26 //NVIC_Group             :中断分组 0~4
27 //注意优先级不能超过设定的组的范围!否则会有意想不到的错误
28 //组划分:
29 //组0:0位抢占优先级,4位响应优先级
30 //组1:1位抢占优先级,3位响应优先级
31 //组2:2位抢占优先级,2位响应优先级
32 //组3:3位抢占优先级,1位响应优先级
33 //组4:4位抢占优先级,0位响应优先级
34 //NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先       
35 void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)     
36 { 
37     u32 temp;    
38     MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
39     temp=NVIC_PreemptionPriority<<(4-NVIC_Group);      
40     temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
41     temp&=0xf;//取低四位  
42     NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);//使能中断位(要清除的话,相反操作就OK) 
43     NVIC->IP[NVIC_Channel]|=temp<<4;//设置响应优先级和抢断优先级                                    
44 } 

 

  在Cortex-M3内核支持256个中断(16个内核中断,240外部中断),并且具有256级的可编程中断设置。stm32并没有使用Cortex-M3内核全部配设。stm32有84个中断(16个内核中断,68可屏蔽中断),具有16级可编程的中断优先级。68可屏蔽中断在stm32f103系列上只有60个。

 1 /* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
 2 typedef struct
 3 {
 4  
 5   __IO uint32_t ISER[8];                      /*!< Interrupt Set Enable Register            */
 6        uint32_t RESERVED0[24];
 7   __IO uint32_t ICER[8];                      /*!< Interrupt Clear Enable Register          */
 8        uint32_t RSERVED1[24];
 9   __IO uint32_t ISPR[8];                      /*!< Interrupt Set Pending Register           */
10        uint32_t RESERVED2[24];
11   __IO uint32_t ICPR[8];                      /*!< Interrupt Clear Pending Register         */
12        uint32_t RESERVED3[24];
13   __IO uint32_t IABR[8];                      /*!< Interrupt Active bit Register            */
14        uint32_t RESERVED4[56];
15   __IO uint8_t  IP[240];                      /*!< Interrupt Priority Register, 8Bit wide   */
16        uint32_t RESERVED5[644];
17   __O  uint32_t STIR;                         /*!< Software Trigger Interrupt Register      */
18  
19 }  NVIC_Type;

中断的使能与除能

ISER[8]:Interrupt Set-Enable Registers 中断使能寄存器  

  Cortex-M3内核支持256个中断,8个32位寄存器控制。stm32只用了前68位。ISER[0]的bit0~31对于中断0~31,ISER[1]的bit0~31对于中断32~63,ISER[2]的bit0~3对应中断64~67;要使能某个中断,必须设置相应的ISER位为1,是该中断被使能。

  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 
 33 #ifdef STM32F10X_LD
 34   ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
 35   USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
 36   USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
 37   CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
 38   CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
 39   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
 40   TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
 41   TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
 42   TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
 43   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
 44   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
 45   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
 46   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
 47   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
 48   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
 49   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
 50   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
 51   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
 52   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
 53   USBWakeUp_IRQn              = 42      /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */    
 54 #endif /* STM32F10X_LD */  
 55 
 56 #ifdef STM32F10X_LD_VL
 57   ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
 58   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
 59   TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
 60   TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
 61   TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
 62   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
 63   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
 64   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
 65   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
 66   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
 67   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
 68   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
 69   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
 70   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
 71   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
 72   CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
 73   TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
 74   TIM7_IRQn                   = 55      /*!< TIM7 Interrupt                                       */       
 75 #endif /* STM32F10X_LD_VL */
 76 
 77 #ifdef STM32F10X_MD
 78   ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
 79   USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
 80   USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
 81   CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
 82   CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
 83   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
 84   TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
 85   TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
 86   TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
 87   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
 88   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
 89   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
 90   TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
 91   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
 92   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
 93   I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
 94   I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
 95   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
 96   SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
 97   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
 98   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
 99   USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
100   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
101   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
102   USBWakeUp_IRQn              = 42      /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */  
103 #endif /* STM32F10X_MD */  
104 
105 #ifdef STM32F10X_MD_VL
106   ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
107   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
108   TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
109   TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
110   TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
111   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
112   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
113   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
114   TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
115   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
116   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
117   I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
118   I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
119   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
120   SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
121   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
122   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
123   USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
124   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
125   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
126   CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
127   TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
128   TIM7_IRQn                   = 55      /*!< TIM7 Interrupt                                       */       
129 #endif /* STM32F10X_MD_VL */
130 
131 #ifdef STM32F10X_HD
132   ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
133   USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
134   USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
135   CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
136   CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
137   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
138   TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
139   TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
140   TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
141   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
142   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
143   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
144   TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
145   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
146   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
147   I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
148   I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
149   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
150   SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
151   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
152   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
153   USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
154   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
155   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
156   USBWakeUp_IRQn              = 42,     /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
157   TIM8_BRK_IRQn               = 43,     /*!< TIM8 Break Interrupt                                 */
158   TIM8_UP_IRQn                = 44,     /*!< TIM8 Update Interrupt                                */
159   TIM8_TRG_COM_IRQn           = 45,     /*!< TIM8 Trigger and Commutation Interrupt               */
160   TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare Interrupt                       */
161   ADC3_IRQn                   = 47,     /*!< ADC3 global Interrupt                                */
162   FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                */
163   SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                */
164   TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
165   SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
166   UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
167   UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
168   TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
169   TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
170   DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
171   DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
172   DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
173   DMA2_Channel4_5_IRQn        = 59      /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
174 #endif /* STM32F10X_HD */  
175 
176 #ifdef STM32F10X_HD_VL
177   ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
178   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
179   TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
180   TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
181   TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
182   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
183   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
184   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
185   TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
186   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
187   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
188   I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
189   I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
190   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
191   SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
192   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
193   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
194   USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
195   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
196   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
197   CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
198   TIM12_IRQn                  = 43,     /*!< TIM12 global Interrupt                               */
199   TIM13_IRQn                  = 44,     /*!< TIM13 global Interrupt                               */
200   TIM14_IRQn                  = 45,     /*!< TIM14 global Interrupt                               */
201   TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
202   SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
203   UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
204   UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */  
205   TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
206   TIM7_IRQn                   = 55,     /*!< TIM7 Interrupt                                       */  
207   DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
208   DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
209   DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
210   DMA2_Channel4_5_IRQn        = 59,     /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
211   DMA2_Channel5_IRQn          = 60      /*!< DMA2 Channel 5 global Interrupt (DMA2 Channel 5 is 
212                                              mapped at position 60 only if the MISC_REMAP bit in 
213                                              the AFIO_MAPR2 register is set)                      */       
214 #endif /* STM32F10X_HD_VL */
215 
216 #ifdef STM32F10X_XL
217   ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
218   USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
219   USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
220   CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
221   CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
222   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
223   TIM1_BRK_TIM9_IRQn          = 24,     /*!< TIM1 Break Interrupt and TIM9 global Interrupt       */
224   TIM1_UP_TIM10_IRQn          = 25,     /*!< TIM1 Update Interrupt and TIM10 global Interrupt     */
225   TIM1_TRG_COM_TIM11_IRQn     = 26,     /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
226   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
227   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
228   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
229   TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
230   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
231   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
232   I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
233   I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
234   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
235   SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
236   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
237   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
238   USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
239   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
240   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
241   USBWakeUp_IRQn              = 42,     /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
242   TIM8_BRK_TIM12_IRQn         = 43,     /*!< TIM8 Break Interrupt and TIM12 global Interrupt      */
243   TIM8_UP_TIM13_IRQn          = 44,     /*!< TIM8 Update Interrupt and TIM13 global Interrupt     */
244   TIM8_TRG_COM_TIM14_IRQn     = 45,     /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
245   TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare Interrupt                       */
246   ADC3_IRQn                   = 47,     /*!< ADC3 global Interrupt                                */
247   FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                */
248   SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                */
249   TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
250   SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
251   UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
252   UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
253   TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
254   TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
255   DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
256   DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
257   DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
258   DMA2_Channel4_5_IRQn        = 59      /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
259 #endif /* STM32F10X_XL */  
260 
261 #ifdef STM32F10X_CL
262   ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
263   CAN1_TX_IRQn                = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
264   CAN1_RX0_IRQn               = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
265   CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
266   CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
267   EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
268   TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
269   TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
270   TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
271   TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
272   TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
273   TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
274   TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
275   I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
276   I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
277   I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
278   I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
279   SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
280   SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
281   USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
282   USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
283   USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
284   EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
285   RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
286   OTG_FS_WKUP_IRQn            = 42,     /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */
287   TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
288   SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
289   UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
290   UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
291   TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
292   TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
293   DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
294   DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
295   DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
296   DMA2_Channel4_IRQn          = 59,     /*!< DMA2 Channel 4 global Interrupt                      */
297   DMA2_Channel5_IRQn          = 60,     /*!< DMA2 Channel 5 global Interrupt                      */
298   ETH_IRQn                    = 61,     /*!< Ethernet global Interrupt                            */
299   ETH_WKUP_IRQn               = 62,     /*!< Ethernet Wakeup through EXTI line Interrupt          */
300   CAN2_TX_IRQn                = 63,     /*!< CAN2 TX Interrupt                                    */
301   CAN2_RX0_IRQn               = 64,     /*!< CAN2 RX0 Interrupt                                   */
302   CAN2_RX1_IRQn               = 65,     /*!< CAN2 RX1 Interrupt                                   */
303   CAN2_SCE_IRQn               = 66,     /*!< CAN2 SCE Interrupt                                   */
304   OTG_FS_IRQn                 = 67      /*!< USB OTG FS global Interrupt                          */
305 #endif /* STM32F10X_CL */     
306 } IRQn_Type;
每一位对应中断 from stm32f10x.h

ICER[8]: Interrupt Clear-Enable Registers 中断除能寄存器

  专门设置一个ICER来清除中断位,而不是向ISER写0来清除,是因为NVIC的这些寄存器都是写1有效,写0无效。

 

中断的悬起与解悬

 

ISPR[8]: Interrupt Set-Pending Registers 中断挂起控制寄存器
  通过置1可以将正在进行的中断挂起,而执行同级,或更高级别的中断,写0无效。

ICPR[8]: Interrupt Clear-Pending Registers 中断解挂控制寄存器

  通过置1可以将挂起的中断解挂,写0无效。

 

IABR[8]: Interrupt Active Bit Registers 中断激活标志位寄存器

  对应位代表和ISER一样,如果为1,代表中断正在被执行。只读寄存器,通过读取它知道当前在执行的中断是哪个。中断执行完由硬件清0。

IP[240]: Interrupt Priority Registers 中断优先级控制寄存器

  IP[67]~IP[0]分别对应中断67~0,每个可屏蔽中断占用8bit的高4位。这4位分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各站几个位根据SCB->AIRCR中的中断分组设置来决定。

 

  Eg:组设置为3,那么此时所有68个中断的每个中断的中断优先寄存器的高4位中最高3位是抢占优先级,低1位是响应优先级。每个中断可以设置抢占优先级0~7,响应优先级为0或1。数值越小,优先级越高。

 

高优先级的抢占优先级是可以打断正在进行的低优先级中断的;而抢占优先级相同的中断,高优先级的响应中断不可以打断低响应优先级的中断。

 1 //设置NVIC分组
 2 //NVIC_Group:NVIC分组 0~4 总共5组            
 3 void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)     
 4 { 
 5     u32 temp,temp1;      
 6     temp1=(~NVIC_Group)&0x07;//取后三位
 7     temp1<<=8;
 8     temp=SCB->AIRCR;  //读取先前的设置
 9     temp&=0X0000F8FF; //清空先前分组
10     temp|=0X05FA0000; //写入钥匙
11     temp|=temp1;       
12     SCB->AIRCR=temp;  //设置分组                                 
13 }
设置NVIC分组

 

 1 //设置NVIC 
 2 //NVIC_PreemptionPriority:抢占优先级
 3 //NVIC_SubPriority       :响应优先级
 4 //NVIC_Channel           :中断编号
 5 //NVIC_Group             :中断分组 0~4
 6 //注意优先级不能超过设定的组的范围!否则会有意想不到的错误
 7 //组划分:
 8 //组0:0位抢占优先级,4位响应优先级
 9 //组1:1位抢占优先级,3位响应优先级
10 //组2:2位抢占优先级,2位响应优先级
11 //组3:3位抢占优先级,1位响应优先级
12 //组4:4位抢占优先级,0位响应优先级
13 //NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先       
14 void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)     
15 { 
16     u32 temp;    
17     MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
18     temp=NVIC_PreemptionPriority<<(4-NVIC_Group);      
19     temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
20     temp&=0xf;//取低四位  
21     NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);//使能中断位(要清除的话,相反操作就OK) 
22     NVIC->IP[NVIC_Channel]|=temp<<4;//设置响应优先级和抢断优先级                                    
23 } 
设置NVIC MY_NVIC_Init

  根据中断分组情况来设置 中断优先级控制寄存器IP 其高四位。

  用MY_NVIC_PriorityGroupConfig函数分组

  开启中断,在ISER相应位置1

 

4.外部中断的应用

 

 1 //key--->led 外部中断
 2 //外部中断0服务程序
 3 void EXTI0_IRQHandler(void)
 4 {
 5     delay_ms(10);    //消抖
 6     if(WK_UP==1)    //WK_UP按键 
 7     {
 8         LED0=!LED0;
 9         LED1=!LED1;    
10     }         
11     EXTI->PR=1<<0;  //清除LINE0上的中断标志位  
12 }
13 //外部中断9~5服务程序
14 void EXTI9_5_IRQHandler(void)
15 {            
16     delay_ms(10);   //消抖             
17     if(KEY0==0)        //按键0
18     {
19         LED0=!LED0;
20     }
21      EXTI->PR=1<<5;     //清除LINE5上的中断标志位  
22 }
23 //外部中断15~10服务程序
24 void EXTI15_10_IRQHandler(void)
25 {            
26     delay_ms(10);   //消抖             
27     if(KEY1==0)        //按键1
28     {
29         LED1=!LED1;
30     }
31      EXTI->PR=1<<15; //清除LINE15上的中断标志位  
32 }
33 //外部中断初始化程序
34 //初始化PA0,PC5,PA15为中断输入.
35 void EXTI_Init(void)
36 {
37     KEY_Init();
38     Ex_NVIC_Config(GPIO_A,0,RTIR);         //上升沿触发
39     Ex_NVIC_Config(GPIO_C,5,FTIR);        //下降沿触发
40     Ex_NVIC_Config(GPIO_A,15,FTIR);        //下降沿触发
41 
42     MY_NVIC_Init(2,2,EXTI0_IRQn,2);        //抢占2,子优先级2,组2
43     MY_NVIC_Init(2,1,EXTI9_5_IRQn,2);      //抢占2,子优先级1,组2
44     MY_NVIC_Init(2,0,EXTI15_10_IRQn,2);    //抢占2,子优先级0,组2       
45 }

 

推荐阅读