本文針對(duì)CW32L083系列MCU,同系列產(chǎn)品亦可參考。
ARM? Cortex?-M0+ 內(nèi)核的嵌套向量中斷控制器 (NVIC),用于管理中斷和異常。NVIC和處理器內(nèi)核緊密相連,可以實(shí)現(xiàn)低延遲的異常和中斷處理。處理器支持最多32個(gè)中斷請(qǐng)求 (IRQ)輸入,支持多個(gè)內(nèi)部異常。
主要特性
? 16個(gè)內(nèi)部異常
? 32個(gè)可屏蔽外部中斷
? 4個(gè)可編程的優(yōu)先級(jí)
? 低延時(shí)的異常和中斷處理
? 支持中斷嵌套
? 中斷向量表重映射
本文介紹了處理器的 32 個(gè)外部中斷請(qǐng)求(IRQ0 ~ IRQ31),處理器內(nèi)部異常的具體情況請(qǐng)參考“ARM? Cortex?-M0+Technical Reference Manual”與“ARM? v6-M Architecture Reference Manual”。
中斷優(yōu)先級(jí)
外部中斷可設(shè)置 4 級(jí)優(yōu)先級(jí),最高優(yōu)先級(jí)為“0”,最低優(yōu)先級(jí)為“3”,默認(rèn)值為“0”。當(dāng)處理器正在執(zhí)行一個(gè)中斷處理程序時(shí),如果出現(xiàn)一個(gè)更高優(yōu)先級(jí)的中斷,那么這個(gè)中斷就被搶占。如果出現(xiàn)的中斷的優(yōu)先級(jí)和正在處理的中斷的優(yōu)先級(jí)相同或更低,這個(gè)中斷就不會(huì)被搶占,但是新中斷的狀態(tài)就變?yōu)閽炱稹H绻鄠€(gè)掛起的中斷具有相同的優(yōu)先級(jí),中斷編號(hào)越小的掛起中斷優(yōu)先處理。例如,如果IRQ[0]和IRQ[1]均掛起時(shí),并且兩者的優(yōu)先級(jí)相同,那么先處理 IRQ[0]。
中斷向量表
ARM? Cortex?-M0+ 響應(yīng)中斷時(shí),處理器自動(dòng)從存儲(chǔ)器的中斷向量表中取出中斷服務(wù)程序 ( ISR )的起始地址。中斷向量表包括主棧指針(MSP)的初始值,內(nèi)部異常和外部中斷的服務(wù)程序入口地址。每個(gè)中斷向量占用1個(gè)字(4 字節(jié)),中斷向量的存儲(chǔ)地址為向量編號(hào)乘以4,下面的是CW32L083的中斷向量表。
CW32L083由于部分外設(shè)的中斷復(fù)用一個(gè)IRQ中斷源,在中斷服務(wù)程序中應(yīng)先檢查中斷標(biāo)志位,以確定產(chǎn)生中斷的外設(shè)。NMI在CW32L083中未使用。HSE 、LSE 時(shí)鐘信號(hào)起振失敗和 LSI、LSE、HSIOSC、HSE、PLL 時(shí)鐘信號(hào)穩(wěn)定對(duì)應(yīng) RCC 全局中斷。HSE 或 LSE 時(shí)鐘信號(hào)在運(yùn)行中失效對(duì)應(yīng) FAULT 中斷。
中斷寄存器的相關(guān)配置
1.中斷的使能、掛起、清除掛起
ARM? Cortex-M0+處理器支持最多32個(gè)外部中斷源,分別對(duì)應(yīng)中斷使能設(shè)置寄存器NIVC_ISER的32個(gè)使能位,和中斷使能清除寄存器NVIC_ICER的32個(gè)禁止位。將使能位置1,允許中斷;將禁止位置1,禁止中斷。上文中NVIC中斷使能僅針對(duì)處理器 NVIC而言,外設(shè)的中斷是否使能,還受相應(yīng)外設(shè)的中斷控制寄存器控制。
而在中斷發(fā)生的時(shí)候,如果系統(tǒng)正在處理相同優(yōu)先級(jí)的或者更高優(yōu)先級(jí)的中斷,系統(tǒng)將不會(huì)立馬的處理這個(gè)中斷,而是將這個(gè)中斷的狀態(tài)設(shè)置為掛起,保存在中斷掛起狀態(tài)寄存器中,在處理器未進(jìn)去此中斷處理之前,如果沒(méi)有手動(dòng)清除掛起狀態(tài),這個(gè)狀態(tài)會(huì)一直有效,等處理器進(jìn)入中斷處理的時(shí)候,硬件會(huì)自動(dòng)清除相應(yīng)的中斷掛起狀態(tài)。也可以通過(guò)設(shè)置中斷掛起設(shè)置寄存器NVIC_ISPR的對(duì)應(yīng)位,將此中斷的狀態(tài)設(shè)置為掛起狀態(tài),如果系統(tǒng)沒(méi)有正在處理與之相同優(yōu)先級(jí)或更高優(yōu)先級(jí)的中斷,此中斷將被立即響應(yīng)并處理。可以通過(guò)設(shè)置中斷掛起清除寄存器NVIC_ICPR的對(duì)應(yīng)位,將此中斷的狀態(tài)設(shè)置為掛起清除狀態(tài)。
2.中斷的優(yōu)先級(jí)、中斷屏蔽
中斷優(yōu)先級(jí)控制寄存器NVIC_IPR0 ~ NVIC_IPR7,用于設(shè)置IRQ0~IRQ31 的中斷優(yōu)先級(jí),每個(gè)中斷源使用8位,在CW32L083中僅使用了高兩位,最多可設(shè)置4個(gè)中斷優(yōu)先級(jí)。
在某些特殊場(chǎng)合,需要禁止所有中斷,可以使用中斷屏蔽寄存器PRIMASK實(shí)現(xiàn)。PRIMASK只有最低1位有效,將此位置1,除了NMI和硬件錯(cuò)誤異常之外的所有外部中斷和異常都被禁止;清0后,允許響應(yīng)中斷和異常。該位復(fù)位后默認(rèn)為0。
按鍵中斷檢測(cè)實(shí)驗(yàn)分析
以CW32L083評(píng)估板為例,按鍵連接至CW32L083的PA4、PA5端口,LED連接至PC2、PC3接口。按鍵按下將產(chǎn)生中斷,在中斷服務(wù)程序中進(jìn)行LED翻轉(zhuǎn)。
int32_t main(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA的配置時(shí)鐘 __RCC_GPIOC_CLK_ENABLE(); // 使能GPIOC的配置時(shí)鐘 //按鍵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中斷標(biāo)志并使能NVIC GPIOA_INTFLAG_CLR(bv4| bv5); NVIC_EnableIRQ(GPIOA_IRQn); __enable_irq(); //---------------------------------------------------------------------- //相關(guān)程序在中斷服務(wù)GPIOA_IRQHandler中進(jìn)行處理 while (1) { } } //GPIOA的中斷服務(wù)函數(shù) void GPIOA_IRQHandlerCallback(void) { if (CW_GPIOA->ISR_f.PIN4) { GPIOA_INTFLAG_CLR(bv4);清除PA04的中斷標(biāo)志位 PC03_TOG(); } if (CW_GPIOA->ISR_f.PIN5) { GPIOA_INTFLAG_CLR(bv5);//清除PA05的中斷標(biāo)志位 PC02_TOG(); } }
由上面代碼可以看到,如果按下KEY1(PA04),LED1(PC03)的狀態(tài)會(huì)翻轉(zhuǎn),如果松開按鍵,LED1又會(huì)翻轉(zhuǎn)一次。在每次執(zhí)行中斷函數(shù)的時(shí)候,需要清除中斷標(biāo)志位即GPIOA_INTFLAG_CLR(bv4)。
-
微控制器
+關(guān)注
關(guān)注
48文章
7496瀏覽量
151087 -
單片機(jī)
+關(guān)注
關(guān)注
6032文章
44525瀏覽量
633268 -
mcu
+關(guān)注
關(guān)注
146文章
17019瀏覽量
350375
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論