默認SysTick中斷優先級
1 //core_cm4.h 2 3 __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) 4 { 5 if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); } /* Reload value impossible */ 6 7 SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ 8 NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ 9 SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ 10 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | 11 SysTick_CTRL_TICKINT_Msk | 12 SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ 13 return (0UL); /* Function successful */ 14 }
第8行設置了SysTick中斷的優先級,
#define __NVIC_PRIO_BITS 4 /*!< STM32F4XX uses 4 Bits for the Priority Levels */
在看NVIC_SetPriority函數:NVIC_SetPriority對中斷分了類,分內核中斷和外設中斷,內核外設中斷枚舉值小於0,普通外設>=0。其中,SysTick_IRQn = -1。
1 __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) 2 { 3 if((int32_t)IRQn < 0) { 4 SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); 5 } 6 else { 7 NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); 8 } 9 }
因為SysTick屬於內核外設,跟普通外設的中斷優先級有些區別,並沒有搶占優先級和子優先級的說法。在STM32F4中,內核外設的中斷優先級由內核SCB這個外設的寄存器:SHPRx(x=1.2.3)來配置。有關SHPRx寄存器的詳細描述可參考《Cortex-M4內核編程手冊》4.4.8章節。下面我們簡單介紹下這個寄存器。
SPRH1-SPRH3是一個32位的寄存器,但是只能通過字節訪問,每8個字段控制着一個內核外設的中斷優先級的配置。在STM32F4中,只有位7:4這高四位有效,低四位沒有用到,所以內核外設的中斷優先級可編程為:0~15,只有16個可編程優先級,數值越小,優先級越高。如果軟件優先級配置相同,那就根據他們在中斷向量表里面的位置編號來決定優先級大小,編號越小,優先級越高。
在SysTick_Config中,配置優先級為(1UL << __NVIC_PRIO_BITS) - 1UL),其中宏__NVIC_PRIO_BITS為4,那計算結果就等於15,可以看出SysTick此時設置的優先級在內核外設中是最低的。
SysTick和外設中斷的優先級大小
但是,問題來了,如果我同時使用了systick和片上外設呢?而且片上外設也剛好需要使用中斷,那systick的中斷優先級跟外設的中斷優先級怎么設置?會不會因為systick是內核里面的外設,所以它的中斷優先級就一定比內核之外的外設的優先級高?
從《STM32中斷應用概覽》這章我們知道,外設在設置中斷優先級的時候,首先要分組,然后設置搶占優先級和子優先級。而systick這類內核的外設在配置的時候,只需要配置一個寄存器即可,取值范圍為0~15。既然配置方法不同,那如何區分兩者的優先級?下面舉例說明。
比如配置一個外設的中斷優先級分組為2,搶占優先級為1,子優先級也為1,systick的優先級為固件庫默認配置的15。當我們比較內核外設和片上外設的中斷優先級的時候,我們只需要抓住NVIC的中斷優先級分組不僅對片上外設有效,同樣對內核的外設也有效。我們把systick的優先級15轉換成二進制值就是1111(0b),又因為NVIC的優先級分組2,
那么前兩位的11(0b)就是3,后兩位的11(0b)也是3。無論從搶占還是子優先級都比我們設定的外設的優先級低。
如果當兩個的軟件優先級都配置成一樣,那么就比較他們在中斷向量表中的硬件編號,編號越小,優先級越高。