ARM? Cortex?-M0+ 內核的嵌套向量中斷控制器 (NVIC),用于管理中斷和異常。NVIC和處理器內核緊密相連,可以實現低延遲的異常和中斷處理。處理器支持最多32個中斷請求 (IRQ)輸入,支持多個內部異常。
主要特性
? 16個內部異常
? 32個可屏蔽外部中斷
? 4個可編程的優先級
? 低延時的異常和中斷處理
? 支持中斷嵌套
? 中斷向量表重映射
本文介紹了處理器的 32 個外部中斷請求(IRQ0 ~ IRQ31),處理器內部異常的具體情況請參考“ARM? Cortex?-M0+Technical Reference Manual”與“ARM? v6-M Architecture Reference Manual”。
中斷優先級
外部中斷可設置 4 級優先級,最高優先級為“0”,最低優先級為“3”,默認值為“0”。當處理器正在執行一個中斷處理程序時,如果出現一個更高優先級的中斷,那么這個中斷就被搶占。如果出現的中斷的優先級和正在處理的中斷的優先級相同或更低,這個中斷就不會被搶占,但是新中斷的狀態就變為掛起。如果多個掛起的中斷具有相同的優先級,中斷編號越小的掛起中斷優先處理。例如,如果IRQ[0]和IRQ[1]均掛起時,并且兩者的優先級相同,那么先處理 IRQ[0]。
中斷向量表
ARM? Cortex?-M0+ 響應中斷時,處理器自動從存儲器的中斷向量表中取出中斷服務程序 ( ISR )的起始地址。中斷向量表包括主棧指針(MSP)的初始值,內部異常和外部中斷的服務程序入口地址。每個中斷向量占用1個字(4 字節),中斷向量的存儲地址為向量編號乘以4,下面的是CW32L083的中斷向量表。
CW32L083由于部分外設的中斷復用一個IRQ中斷源,在中斷服務程序中應先檢查中斷標志位,以確定產生中斷的外設。NMI在CW32L083中未使用。HSE 、LSE 時鐘信號起振失敗和 LSI、LSE、HSIOSC、HSE、PLL 時鐘信號穩定對應 RCC 全局中斷。HSE 或 LSE 時鐘信號在運行中失效對應 FAULT 中斷。
中斷寄存器的相關配置
1.中斷的使能、掛起、清除掛起
ARM? Cortex-M0+處理器支持最多32個外部中斷源,分別對應中斷使能設置寄存器NIVC_ISER的32個使能位,和中斷使能清除寄存器NVIC_ICER的32個禁止位。將使能位置1,允許中斷;將禁止位置1,禁止中斷。上文中NVIC中斷使能僅針對處理器 NVIC而言,外設的中斷是否使能,還受相應外設的中斷控制寄存器控制。
而在中斷發生的時候,如果系統正在處理相同優先級的或者更高優先級的中斷,系統將不會立馬的處理這個中斷,而是將這個中斷的狀態設置為掛起,保存在中斷掛起狀態寄存器中,在處理器未進去此中斷處理之前,如果沒有手動清除掛起狀態,這個狀態會一直有效,等處理器進入中斷處理的時候,硬件會自動清除相應的中斷掛起狀態。也可以通過設置中斷掛起設置寄存器NVIC_ISPR的對應位,將此中斷的狀態設置為掛起狀態,如果系統沒有正在處理與之相同優先級或更高優先級的中斷,此中斷將被立即響應并處理。可以通過設置中斷掛起清除寄存器NVIC_ICPR的對應位,將此中斷的狀態設置為掛起清除狀態。
2.中斷的優先級、中斷屏蔽
中斷優先級控制寄存器NVIC_IPR0 ~ NVIC_IPR7,用于設置IRQ0~IRQ31 的中斷優先級,每個中斷源使用8位,在CW32L083中僅使用了高兩位,最多可設置4個中斷優先級。
在某些特殊場合,需要禁止所有中斷,可以使用中斷屏蔽寄存器PRIMASK實現。PRIMASK只有最低1位有效,將此位置1,除了NMI和硬件錯誤異常之外的所有外部中斷和異常都被禁止;清0后,允許響應中斷和異常。該位復位后默認為0。
按鍵中斷檢測實驗分析
以CW32L083評估板為例,按鍵連接至CW32L083的PA4、PA5端口,LED連接至PC2、PC3接口。按鍵按下將產生中斷,在中斷服務程序中進行LED翻轉。
int32_t main(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA的配置時鐘 __RCC_GPIOC_CLK_ENABLE(); // 使能GPIOC的配置時鐘 //按鍵GPIO初始化 GPIO_InitStruct.IT = GPIO_IT_RISING | GPIO_IT_FALLING; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pins =GPIO_PIN_4 | GPIO_PIN_5; GPIO_Init(CW_GPIOA, &GPIO_InitStruct); //LED的GPIO初始化 GPIO_InitStruct.IT = GPIO_IT_NONE; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pins =GPIO_PIN_2 | GPIO_PIN_3; GPIO_Init(CW_GPIOC, &GPIO_InitStruct); //配置中斷濾波 GPIO_ConfigFilter(CW_GPIOA, bv4, GPIO_FLTCLK_RC150K); //清除PA4、PA5中斷標志并使能NVIC GPIOA_INTFLAG_CLR(bv4| bv5); NVIC_EnableIRQ(GPIOA_IRQn); __enable_irq(); //---------------------------------------------------------------------- //相關程序在中斷服務GPIOA_IRQHandler中進行處理 while (1) { } } //GPIOA的中斷服務函數 void GPIOA_IRQHandlerCallback(void) { if (CW_GPIOA->ISR_f.PIN4) { GPIOA_INTFLAG_CLR(bv4);清除PA04的中斷標志位 PC03_TOG(); } if (CW_GPIOA->ISR_f.PIN5) { GPIOA_INTFLAG_CLR(bv5);//清除PA05的中斷標志位 PC02_TOG(); } }
由上面代碼可以看到,如果按下KEY1(PA04),LED1(PC03)的狀態會翻轉,如果松開按鍵,LED1又會翻轉一次。在每次執行中斷函數的時候,需要清除中斷標志位即GPIOA_INTFLAG_CLR(bv4)。
-
微控制器
+關注
關注
48文章
7575瀏覽量
151714 -
單片機
+關注
關注
6040文章
44592瀏覽量
636812 -
mcu
+關注
關注
146文章
17196瀏覽量
351887
發布評論請先 登錄
相關推薦
評論