【STM32F407開發板用戶手冊】第21章 STM32F407的NVIC中斷分組和配置(重要)

最新教程下載:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93255php

第21章       STM32F407的NVIC中斷分組和配置(重要)

本章節爲你們講解STM32F407的中斷優先級配置。此章節很是重要,初學者常常在這裏犯迷糊,所以頗有必要整明白。函數

21.1 NVIC基礎知識ui

21.2 經常使用的NVIC APIspa

21.3 MDK中查看實際優先級配置調試

21.4 開關中斷code

21.5 總結blog

 

 

21.1 NVIC基礎知識

NVIC的全稱是Nested vectored interrupt controller,即嵌套向量中斷控制器。教程

對於M3/M4/M7內核的MCU,每一箇中斷的優先級都是用寄存器中的8位來設置的。8位的話就能夠設置2^8 = 256級中斷,實際中用不了這麼多,因此芯片廠商根據本身生產的芯片作出了調整。好比ST的STM32F1xx,F4xx和H7只使用了這個8位中的高四位[7:4],低四位取零,這樣2^4=16,只能表示16級中斷嵌套。開發

對於這個NVIC,有個重要的知識點就是優先級分組、搶佔優先級和子優先級。STM32F1xx,F4xx和H7都是隻使用了這個8位寄存器的高四位[7:4]。get

 

 從上面的表格能夠看出,STM32支持5種優先級分組。系統上電覆位後,默認使用的是優先級分組0,也就是沒有搶佔式優先級,只有子優先級。關於這個搶佔優先級和子優先級有幾點必定要說清楚。

  •   具備高搶佔式優先級的中斷能夠在具備低搶佔式優先級的中斷服務程序執行過程當中被響應,即中斷嵌套,或者說高搶佔式優先級的中斷能夠搶佔低搶佔式優先級的中斷的執行。
  •   在搶佔式優先級相同的狀況下,有幾個子優先級不一樣的中斷同時到來,那麼高子優先級的中斷優先被響應。
  •   在搶佔式優先級相同的狀況下,若是有低子優先級中斷正在執行,高子優先級的中斷要等待已被響應的低子優先級中斷執行結束後才能獲得響應,即子優先級不支持中斷嵌套。
  •   Reset、NMI、Hard Fault 優先級爲負數,高於普通中斷優先級,且優先級不可配置。
  •   初學者還有一個比較糾結的問題,就是系統中斷(好比:PendSV,SVC,SysTick)是否是必定比外部中斷(好比SPI,USART)要高。答案:不是的,它們是在同一個NVIC下面設置的。

 

掌握了這些基礎知識基本就夠用了。另外特別注意一點,配置搶佔優先級和子優先級,它們合併成的4bit數字的數值越小,優先級越高,這一點千萬不要搞錯了。

21.2 經常使用的NVIC API

下面將外設配置中常常用到的兩個函數作個說明。

  •   HAL_NVIC_SetPriority
  •   HAL_NVIC_EnableIRQ

 

21.2.1 函數HAL_NVIC_SetPriority

函數原型:

void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)

函數描述:

此函數主要用於設置中斷的搶佔優先級和子優先級。

函數參數:

  •   第1個參數IRQn是中斷號,由IRQn_Type定義的枚舉類型,原始定義在stm32f407x.h。
typedef enum
{
  /* 部分定義,其它省略未寫 */
  PendSV_IRQn                 = -2,    
  SysTick_IRQn                = -1,   
  DMA1_Stream3_IRQn           = 14,   
  DMA1_Stream4_IRQn           = 15,    
  DMA1_Stream5_IRQn           = 16,    
  DMA1_Stream6_IRQn           = 17,     
  ADC_IRQn                    = 18,    
} IRQn_Type;
  •   第2個參數PreemptPriority用於設置搶佔優先級,範圍0 - 15。
  •   第3個參數SubPriority用於設置子優先級,範圍0 -15。

使用舉例:

此函數的調用比較簡單,好比設置ADC中斷的搶佔優先級是1,子優先級是0,那麼此函數的設置就是:HAL_NVIC_SetPriority(ADC_IRQn, 1, 0)。

21.2.2 函數HAL_NVIC_EnableIRQ

函數原型:

void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)

函數描述:

此函數主要用於使能中斷。

函數參數:

  •   第1個參數IRQn是中斷號,由IRQn_Type定義的枚舉類型,原始定義在stm32f407x.h。
typedef enum
{
  /* 部分定義,其它省略未寫 */
  PendSV_IRQn                 = -2,    
  SysTick_IRQn                = -1,   
  DMA1_Stream3_IRQn           = 14,   
  DMA1_Stream4_IRQn           = 15,    
  DMA1_Stream5_IRQn           = 16,    
  DMA1_Stream6_IRQn           = 17,     
  ADC_IRQn                    = 18,    
} IRQn_Type;

注意事項:

調用此函數前要先調用優先級分組設置函數NVIC_PriorityGroupConfig,而這個函數會在HAL_Init裏面被調用。函數基本都會在main函數裏面優先被調用,因此保證HAL_Init優先被調用便可。

使用舉例:

此函數的調用比較省事,好比使能ADC中斷,那麼此函數的設置就是:

HAL_NVIC_EnableIRQ (ADC_IRQn, )。

21.3 MDK中查看實際優先級配置

若是想查看配置的外設優先級是否正確設置了,MDK進入調試狀態後,先點擊全速運行,而後查看以下調試組件:

 

彈出以下窗口,在這個窗口裏面就能夠查看實際優先級了,好比滴答定時器Systick的優先級就是240,即240>>4 = 15。

 

21.4 開關中斷

V6開發板的BSP驅動包在bsp.h文件裏面對開關中斷作了一個宏定義:

/* 開關全局中斷的宏 */
#define ENABLE_INT()    __set_PRIMASK(0)    /* 使能全局中斷 */
#define DISABLE_INT()    __set_PRIMASK(1)    /* 禁止全局中斷 */

__set_PRIMASK就是對寄存器primask作的開關設置,以下表所示:

 

 對於寄存器basepri咱們舉一個例子,幫助你們理解。比咱們配置寄存器basepri(對於STM32F407,範圍0-255)的數值爲16,全部優先級數值大於等於16的中斷都會被關閉,優先級數值小於16的中斷不會被關閉。但0比較特殊,對寄存器basepri寄存器賦值0,那麼被關閉的中斷會被打開。

21.5 總結

最後,咱們再強調一下,在NVIC分組爲4的狀況下,搶佔優先級可配置範圍是0-15,那麼數值越小,搶佔優先級的級別越高,即0表明最高優先級,15表明最低優先級。

相關文章
相關標籤/搜索