stm32的每個I/O口都可以作為中斷輸入,要把I/O口設置為外部中斷輸入,必須將I/O口設置為上拉/下拉輸入 或 浮空輸入(但浮空的時候外部一定要帶上拉或下拉電阻,否則可能導致 中斷不停的觸發),干擾大時,上拉/下拉輸入模式也建議使用外部上拉/下拉電阻。
1.設置外部中斷 的步驟
①初始化I/O口為輸入
②開啟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;
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 }

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 }
根據中斷分組情況來設置 中斷優先級控制寄存器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 }