STM32的NVIC和中斷的總結(jié)
前言:
1.要想學(xué)習(xí)STM32中斷,要先掌握STM32對(duì)優(yōu)先級(jí)的定義;
2.有51單片機(jī)開(kāi)發(fā)經(jīng)驗(yàn)會(huì)比較容易理解中斷優(yōu)先級(jí);
3.本篇博文基于STM32F103ZET6芯片和3.5.0標(biāo)準(zhǔn)庫(kù)編寫;
4.本篇博文從寄存器入手,最終實(shí)現(xiàn)編程的步驟;如有不足之處,還請(qǐng)前輩多多指教;
一 基礎(chǔ)知識(shí)
1. cortex-m3支持256個(gè)中斷,其中包含了16個(gè)內(nèi)核中斷,240個(gè)外部中斷。(本博文只介紹60個(gè)外部可屏蔽中斷)
2. stm32只有84個(gè)中斷,包括16個(gè)內(nèi)核中斷和68個(gè)可屏蔽中斷
3. stm32f103上只有60個(gè)可屏蔽中斷,f107上才有68個(gè)中斷
4.先占優(yōu)先級(jí)也就是搶占優(yōu)先級(jí),概念等同于51單片機(jī)中的中斷。假設(shè)有兩中斷先后觸發(fā),已經(jīng)在執(zhí)行的中斷先占優(yōu)先級(jí)如果沒(méi)有后觸發(fā)的中斷 先占優(yōu)先級(jí)更高,就會(huì)先處理先占優(yōu)先級(jí)高的中斷。也就是說(shuō)又有較高的先占優(yōu)先級(jí)的中斷可以打斷先占優(yōu)先級(jí)較低的中斷。這是實(shí)現(xiàn)中斷嵌套的基礎(chǔ)。
次占優(yōu)先級(jí),也就是響應(yīng)優(yōu)先級(jí),只在同一先占優(yōu)先級(jí)的中斷同時(shí)觸發(fā)時(shí)起作用,先占優(yōu)先級(jí)相同,則優(yōu)先執(zhí)行次占優(yōu)先級(jí)較高的中斷。次占優(yōu)先級(jí)不會(huì)造成中斷嵌套。 如果中斷的兩個(gè)優(yōu)先級(jí)都一致,則優(yōu)先執(zhí)行位于中斷向量表中位置較高的中斷。
NVIC是什么?
嵌套向量中斷控制器;用于為中斷分組,從而分配搶占優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí);
分組的方式有兩種:
(1)Cortex-m3內(nèi)核提供了一種3位寬度的PRIGROUP數(shù)據(jù)區(qū),用于指示一個(gè)8位數(shù)據(jù)序列中的小數(shù)點(diǎn)的位置,從而表示中斷優(yōu)先級(jí)的分組。見(jiàn)下表:
(2)而實(shí)際上STM32并沒(méi)有用到這么多中斷,所以在分組上只分了5個(gè)組,并且表示方法有所不同;見(jiàn)下表:
我們?cè)趹?yīng)用當(dāng)中只會(huì)用到STM32的分組(5組)方式,所以下面著重于5組分組方式;
二 中斷向量表 (STM32F10x系列)
(圖片來(lái)自STM32使用手冊(cè),只需看,不需要熟記,知道大概這么多中斷就好)
三 配置中斷相關(guān)寄存器
/*cortex-m3內(nèi)核分組方式(8組)結(jié)構(gòu)體表達(dá)方式:*/typedefstruct{__IOuint32_tISER[8];中斷使能設(shè)置寄存器/*!<偏移量:0x000InterruptSetEnableRegister*/uint32_tRESERVED0[24];__IOuint32_tICER[8];中斷清除使能寄存器/*!<偏移量:0x080InterruptClearEnableRegister*/uint32_tRSERVED1[24];__IOuint32_tISPR[8];中斷掛起設(shè)置寄存器/*!<偏移量:0x100InterruptSetPendingRegister*/uint32_tRESERVED2[24];__IOuint32_tICPR[8];中斷清除掛起寄存器/*!<偏移量:0x180InterruptClearPendingRegister*/uint32_tRESERVED3[24];__IOuint32_tIABR[8];中斷激活狀態(tài)位寄存器/*!<偏移量:0x200InterruptActivebitRegister*/uint32_tRESERVED4[56];__IOuint8_tIP[240];中斷優(yōu)先級(jí)寄存器/*!<偏移量:0x300InterruptPriorityRegister(8Bitwide)*/uint32_tRESERVED5[644];軟件觸發(fā)方式寄存器__Ouint32_tSTIR;/*!<偏移量:0xE00SoftwareTriggerInterruptRegister*/}NVIC_Type;12345678910111213141516171819
/*STM32分組(5組)方式結(jié)構(gòu)體表達(dá)方式typedefstruct{vu32ISER[2];u32RESERVED0[30];vu32ICER[2];u32RSERVED1[30];vu32ISPR[2];u32RESERVED2[30];vu32ICPR[2];u32RESERVED3[30];vu32IABR[2];u32RESERVED4[62];vu32IPR[15];}NVIC_TypeDef;*/1234567891011121314151617
以上寄存器介紹:
對(duì)一些概念的解釋:
1. 掛起:當(dāng)置位中斷掛起寄存器的時(shí)候,相應(yīng)的中斷將會(huì)被掛起,這是這個(gè)中斷將不會(huì)立即執(zhí)行,而是等待可執(zhí)行的時(shí)候再執(zhí)行;比如高低級(jí)別的中斷同時(shí)產(chǎn)生,就先掛起低級(jí)別的中斷,等高級(jí)別的中斷執(zhí)行完畢,解除并執(zhí)行低級(jí)中斷;
2. 對(duì)中斷優(yōu)先級(jí)控制寄存器的解釋
推薦去觀看一位前輩的博客:
http://blog.csdn.net/DLUTXIE/article/details/7059184?locationNum=4&fps=1
四 編程步驟
(1)選擇優(yōu)先級(jí)分組
/*
1. 此函數(shù)在庫(kù)文件misc.h文件下;
2. 參數(shù)可參照下面圖片:
3. 功能:選擇分組方式;
*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
栗子:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//搶占優(yōu)先級(jí)可選0~3,響應(yīng)優(yōu)先級(jí)可選0~3;
(2)選擇,配置,并使能中斷
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //選擇EXTI2中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //搶占優(yōu)先級(jí)為2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //響應(yīng)優(yōu)先級(jí)為2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能EXTI2中斷;
NVIC_Init(&NVIC_InitStructure); //初始化以上參數(shù);
(3)寫出相應(yīng)中斷函數(shù)
栗子:
void EXTI2_IRQHandler(void)
{
//邏輯代碼;
EXTI_ClearITPendingBit(EXTI_Line2);
}