一、NVIC 介紹
NVIC 英文全稱是 Nested Vectored Interrupt Controller,中文意思就是嵌套向量中斷控制器,它屬於 M3 內核的一個外設,控制着芯片的中斷相關功能。由於 ARM 給 NVIC 預留了非常多的功能,但對於使用 M3 內核設計芯片的公司可能就不需要這么多功能,於是就需要在 NVIC 上裁剪。ST 公司的 STM32F103 芯片內部中斷數量就是 NVIC 裁剪后的結果。上面說到 NVIC 控制着芯片的中斷相關功能,那么肯定有很多對應的寄存器,在固件庫 core_cm3.h 文件內定義了一個 NVIC 結構體,里面定義了相關寄存器,
這里對第二步進行解釋:
如下:
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) */
14 uint32_t RESERVED5[644]; 15 __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */
16 } NVIC_Type;
在配置中斷時,我們通常使用的只有 ISER、 ICER 和 IP 這三個寄存器,ISER 是中斷使能寄存器,ICER 是中斷清除寄存器,IP 是中斷優先級寄存器。
二、中斷配置
要使用中斷我們就需要先配置它,通常都需經過這幾步:
(1)使能外設某個中斷,這個具體是由外設相關中斷使能位來控制,比如定時器有溢出中斷,這個可由定時器的控制寄存器中相應中斷使能位來控制。
(2)設置中斷優先級分組,初始化 NVIC_InitTypeDef 結構體,設置搶占優先級和響應優先級,使能中斷請求。
(3)編寫中斷服務函數
配置好中斷后如果有觸發,即會進入中斷服務函數,那么中斷服務函數也有固定的函數名,可以在 startup_stm32f10x_hd.s 啟動文件查看,啟動文件提供的只是一個中斷服務函數名,具體實現什么功能還需要我們自己編寫,可以將中斷服務函數放在 stm32f10x_it.c 文件內,也可以放在自己的應用程序中。通常我們把中斷函數放在應用程序中。這里提醒一下大家,不要任意修改中斷服務函數名,因為啟動文件內中斷服務函數名已經固定,如果要修改,你還必須在啟動文件內把原中斷函數修改。
NVIC_InitTypeDef 結構體如下:
1 typedef struct
2 { 3 uint8_t NVIC_IRQChannel;
4 uint8_t NVIC_IRQChannelPreemptionPriority;
5 uint8_t NVIC_IRQChannelSubPriority;
6 FunctionalState NVIC_IRQChannelCmd;
7 } NVIC_InitTypeDef;
下面我們對 NVIC_InitTypeDef 結構體成員進行一下簡單介紹。
1.NVIC_IRQChannel:中斷源的設置,不同的外設中斷,中斷源不一樣,自然名字也不一樣,所以名字不能寫錯,否則不會進入中斷。中斷源放在stm32f10x.h 文件的 IRQn_Type 結構體內,由於內容太多,這里就不復制所有中斷源,只截取一部分,如下:
1 typedef enum IRQn 2 { 3 //Cortex-M3 處理器異常編號
4 NonMaskableInt_IRQn = -14, 5 MemoryManagement_IRQn = -12, 6 BusFault_IRQn = -11, 7 UsageFault_IRQn = -10, 8 SVCall_IRQn = -5, 9 DebugMonitor_IRQn = -4, 10 PendSV_IRQn = -2
11 。。。。。 12 }IRQn_Type;
2.NVIC_IRQChannelPreemptionPriority:搶占優先級,具體的值要根據優先級分組來確定,可以參考前面中斷優先級分組內容。
3.NVIC_IRQChannelSubPriority:響應優先級,具體的值要根據優先級分組來確定,可以參考前面中斷優先級分組內容。
4.NVIC_IRQChannelCmd:中斷使能/失能設置,使能配置為 ENABLE,失能配置為 DISABLE。