STM32F407 NVIC 中斷優先級管理 個人筆記


內嵌向量中斷控制器:Nested Vectored Interrupt Controller (NVIC)
設置中斷向量的優先級並使能。

響應優先級& 搶占優先級

搶占優先級:一個中斷A還在處理時,另一個中斷B發生,B能否先處理? 答:如果B搶占優先級高就行。
響應優先級:搶占優先級相同時,中斷A和中斷B同時發生時,先處理哪個? 答:響應優先級高的哪個。
而搶占優先級相同的中斷,高優先級的響應優先級不可以打斷低響應優先級的中斷。

中斷優先級組

是指在寄存器SCB->AIRCR中,配置:
4個位當中,幾位是搶占優先級,幾位是響應優先級

注意:設置好后不要再改了!以免造成混亂

相關庫函數

NVIC相關的庫函數在FWLIB的misc.c中

中斷優先級分組函數

(一般只調用一次!)
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
例如:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

中斷初始化函數

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
其中 NVIC_InitTypeDef 是一個結構體,我們可以看看結構體的成員變量:

typedef struct  
{  
uint8_t NVIC_IRQChannel;  
uint8_t NVIC_IRQChannelPreemptionPriority;  
uint8_t NVIC_IRQChannelSubPriority;  
FunctionalState NVIC_IRQChannelCmd;  
} NVIC_InitTypeDef;  

NVIC_InitTypeDef 結構體中間有三個成員變量,這三個成員變量的作用是:

NVIC_IRQChannel:定義初始化的是哪個中斷,這個我們可以在 stm32f4xx.h 中定義的枚舉類 型 IRQn
的成員變量中可以找到每個中斷對應的名字。例如串口 1 對應 USART1_IRQn。
NVIC_IRQChannelPreemptionPriority:定義這個中斷的搶占優先級別。
NVIC_IRQChannelSubPriority:定義這個中斷的響應優先級別。
NVIC_IRQChannelCmd:該中斷通道是否使能。

比如我們要使能串口 1 的中斷,同時設置搶占優先級為 1,響應優先級位 2,初始化的方法是:

NVIC_InitTypeDef NVIC_InitStructure;;  
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中斷  
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 搶占優先級為 1  
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 響應優先級位 2  
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能  
NVIC_Init(&NVIC_InitStructure); //根據上面指定的參數初始化 NVIC 寄存器

編程步驟

最簡單的應用中,只要

  1. 設置分組
  2. 外設中斷使能(函數名在外設的頭文件中有)
  3. 初始化
  4. 寫中斷服務函數(函數名在setup巴拉巴拉中定義)
    即可:
//1.
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //可能在主函數
//2.
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);             //可能在初始化函數中
//3.
NVIC_InitTypeDef NVIC_InitStructure;     / /可能在初始化函數
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中斷  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 搶占優先級為 1  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 響應優先級位 2  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能  
    NVIC_Init(&NVIC_InitStructure); //根據上面指定的參數初始化 NVIC 寄存器
//4.中斷服務函數
void USART1_IRQHandler(void)
{
}

上面是一些常用的東西,下面是其他一些有的沒的

支持的中斷數量

  • CM4內核支持256個中斷,其中包含了16個內核中斷和240個外部中斷,並且具有256級的可編程中斷設置。
  • STM32F4並沒有使用CM4內核的全部東西,而是只用了它的一部分。
    STM32F40xx/STM32F41xx總共有92個中斷。
    STM32F42xx/STM32F43xx則總共有96個中斷
  • STM32F40xx/STM32F41xx的92個中斷里面,包括10個內核中斷和82個可屏蔽中斷,具有16級可編程的中斷優先級,而我們常用的就是這82個可屏蔽中斷。

中斷設置相關的寄存器

__IO uint8_t  IP[240]; //中斷優先級控制的寄存器組

__IO uint32_t ISER[8]; //中斷使能寄存器組

__IO uint32_t ICER[8]; //中斷失能寄存器組

__IO uint32_t ISPR[8]; //中斷掛起寄存器組

__IO uint32_t ICPR[8]; //中斷解掛寄存器組

__IO uint32_t IABR[8]; //中斷激活標志位寄存器組

中斷優先級控制寄存器組:IP[240]

Interrupt Priority Registers
240個8位寄存器
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
例如:NVIC_Init(&NVIC_InitStructure);

中斷使能寄存器組:ISER[8]

8個32位寄存器(CM4內核支持256個中斷)
每個位控制一個中斷的使能
STM32F40x只有82個可屏蔽中斷,所以只使用了其中的ISER[0]~ISER[2]。

ISER[0]的bit031分別對應中斷0-31
ISER[1]的bit0-27對應中斷32-63;
ISER[2]的bit0-17對應中斷64~81;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM