每一個外部中斷都有一個對應的優先級寄存器,Cortex-M0中NVIC-IPR共有8個寄存器,而每個寄存器管理4個IRQ中斷,所以M0的IRQ中斷源最多只支持32個,再加上16個內核中斷,也就是說M0最多48個中斷源。
Cortex-M0采用Armv6-M架構,優先級寄存器配置位有8位,但是有效位只有最高2位,這個地方很多人使用了Cortex-M3后一直也認為Cortex-M0也是最高3或4位有效位,在arm官方資料中有對比兩個版本的差別。因此Cortex-M0可編程優先級有4個,加上3個固定的優先級(復位、NMI、HardFault),Cortex-M0總共有7個中斷優先級。
Cortex-M0內核的中斷優先級寄存器是以最高位(MSB)對齊的,并且只支持字傳輸,每次訪問都會同時涉及4個中斷優先級寄存器。見下圖:
因為Bit0 - Bit5沒有使用,所以如果沒有進行寫操作讀出都為0。
由于不同的 Cortex-M 系列,其中斷優先級是不一樣的,所以在 CMSIS 庫中的頭文件中可以查看優先級的數量 \_\_NVIC\_PRIO\_BITS。
中斷優先級寄存器的編程應該在中斷使能之前,其通常是在程序開始時完成的。arm官方資料提示應該避免在中斷使能之后改變中斷優先級,因為這種情況的結果在ARMv6-M系統結構是不可預知的,并且不被Cortex-M0處理器支持。Cortex-M3/M4處理器的情況又有所不同,他們都支持中斷優先級的動態切換。Cortex-M3處理器和Cortex-M0處理器的另外一個區別是,Cortex-M3訪問中斷優先級寄存器時支持字節或半字傳輸,因此可以每次只設置一個寄存器。如果需要改變優先級,程序中需要關閉中斷后再重新設置中斷優先級寄存器。
在 Cortex-M內核中,一個中斷的優先級數值越低,邏輯優先級卻越高。比如,中斷優先級為2的中斷可以搶占中斷優先級為3的中斷,但反過來就不行。換句話說,中斷優先級2比中斷優先級3的優先級更高。
Cortex-M0處理器對中斷嵌套的支持無需任何軟件干預,如果MCU已經在運行一個中斷,而有了新的更高優先級的中斷請求,正在運行的中斷將會被暫停,轉而執行更高優先級的中斷,高優先級中斷執行完成后又回到原來的低優先級中斷。如果出現兩個同一優先級的中斷,則是判斷誰開始發起中斷請求,MCU會先執行同一優先級中首先發起請求的中斷。
MM32F0130系列中斷向量表:
typedefenumIRQn{ NonMaskableInt_IRQn=-14,///2?Non?Maskable?Interrupt ????HardFault_IRQn??????????????????=?-13,??????????????????????????????????///3?Cortex-M0?Hard?Fault?Interrupt ????MemoryManagement_IRQn???????????=?-12,??????????????????????????????????///4?Cortex-M0?Memory?Management?Interrupt ????BusFault_IRQn???????????????????=?-11,??????????????????????????????????///5?Cortex-M0?Bus?Fault?Interrupt ????UsageFault_IRQn?????????????????=?-10,??????????????????????????????????///6?Cortex-M0?Usage?Fault?Interrupt ????SVC_IRQn????????????????????????=?-5,???????????????????????????????????///11?Cortex-M0?SV?Call?Interrupt ????DebugMonitor_IRQn???????????????=?-4,???????????????????????????????????///12?Cortex-M0?Debug?Monitor?Interrupt ????PendSV_IRQn?????????????????????=?-2,???????????????????????????????????///14?Cortex-M0?Pend?SV?Interrupt ????SysTick_IRQn????????????????????=?-1,???????????????????????????????????///15?Cortex-M0?System?Tick?Interrupt ????WWDG_IWDG_IRQn??????????????????=?0,????????????????????????????????????///
設置中斷優先級的流程:先讀一個字,再修改對應字節,最后整個字寫回。
1.1 C代碼
void__NVIC_SetPriority() { unsignedlongtemp;//定義一個臨時變量 temp=*(volatileunsignedlong)(0xE000E400);//讀取IRP0值 temp&=(0xFF00FFFF|(0xC0<16));????????????//修改中斷#2優先級為0xC0 ????*(volatile?unsigned?long)(0xE000E400)?=?temp;?//設置IPR0 }
1.2 匯編代碼
在程序中可以一次設置多個中斷優先級。
void__NVIC_SetPriority() { LDRR0,=0xE000E100;//設置使能中斷寄存器地址 MOVSR1,#0x4;//中斷#2 STRR1,[R0];//使能#2中斷 LDRR0,=0xE000E200;//設置掛起中斷寄存器地址 MOVSR1,#0x4;//中斷#2 STRR1,[R0];//掛起#2中斷 LDRR0,=0xE000E280;//設置清除中斷掛起寄存器地址 MOVSR1,#0x4;//中斷#2 STRR1,[R0];//清除#2的掛起狀態 }
1.3 CMSIS標準設備驅動函數
//設置中斷優先級 __STATIC_INLINEvoid__NVIC_SetPriority(IRQn_TypeIRQn,uint32_tpriority) { if((int32_t)(IRQn)>=0){ NVIC->IP[_IP_IDX(IRQn)]=((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]&~(0xFFUL<SHP[_SHP_IDX(IRQn)]=((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)]&~(0xFFUL<
這里的參數IRQn為中斷ID號,可以為負,也可以為正。當IRQn為負時,設置系統異常的優先級,當IRQn大于等于0時,設置外設中斷優先級,芯片廠商會提供中斷向量表IRQn\_Type,應用層只需要調用即可;priority是0、1、2、3,函數內部會自動移位到對應的優先級最高2位。
方法一: voidNVIC_SetPriority(TIM1_CC_IRQn,3);//設置#14中斷的優先級為0xC0 方法二: voidNVIC_Config(void) {NVIC_InitTypeDefNVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority=3; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); }
設置好中斷優先級后,用戶還可以讀取當前已經設置的中斷優先級。
審核編輯 :李倩
-
寄存器
+關注
關注
31文章
5317瀏覽量
120006 -
Cortex-M0
+關注
關注
4文章
124瀏覽量
38640
原文標題:技術分享 | Cortex-M0中斷控制和系統控制(二)
文章出處:【微信號:Ithingedu,微信公眾號:安芯教育科技】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論