STM32中斷管理函數(shù)
級(jí)的可編程中斷設(shè)置。但STM32 并沒有使用CM3 內(nèi)核的全部東西,而是只用了它的一部分。
STM32 有76 個(gè)中斷,包括16 個(gè)內(nèi)核中斷和60 個(gè)可屏蔽中斷,具有16 級(jí)可編程的中斷優(yōu)先級(jí)。
而我們常用的就是這60 個(gè)可屏蔽中斷,所以我們就只針對(duì)這60 個(gè)可屏蔽中斷進(jìn)行介紹。
在 MDK 內(nèi),與NVIC相關(guān)的寄存器,MDK 為其定義了如下的結(jié)構(gòu)體:
typedef struct
{
vu32 ISER[2];
u32 RESERVED0[30];
vu32 ICER[2];
u32 RSERVED1[30];
vu32 ISPR[2];
u32 RESERVED2[30];
vu32 ICPR[2];
u32 RESERVED3[30];
vu32 IABR[2];
u32 RESERVED4[62];
vu32 IPR[15];
} NVIC_TypeDef;
STM32 的中斷在這些寄存器的控制下有序的執(zhí)行的。了解這些中斷寄存器,你才能方便的
使用STM32 的中斷。下面重點(diǎn)介紹這幾個(gè)寄存器:
ISER[2]:ISER 全稱是:Interrupt Set-Enable Registers,這是一個(gè)中斷使能寄存器組。上面
說了STM32 的可屏蔽中斷只有60 個(gè),這里用了2 個(gè)32 位的寄存器,總共可以表示64 個(gè)中斷。
而STM32 只用了其中的前60 位。ISER[0]的bit0~bit31 分別對(duì)應(yīng)中斷0~31。ISER[1]的bit0~27
對(duì)應(yīng)中斷32~59;這樣總共60 個(gè)中斷就分別對(duì)應(yīng)上了。你要使能某個(gè)中斷,必須設(shè)置相應(yīng)的ISER
位為1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、IO 口映射等設(shè)置才算是
一個(gè)完整的中斷設(shè)置)。具體每一位對(duì)應(yīng)哪個(gè)中斷,請(qǐng)參考stm32f10x_nvic..h 里面的第36 行處。
ICER[2]:全稱是:Interrupt Clear-Enable Registers,是一個(gè)中斷除能寄存器組。該寄存器組
與ISER 的作用恰好相反,是用來清除某個(gè)中斷的使能的。其對(duì)應(yīng)位的功能,也和ICER 一樣。
這里要專門設(shè)置一個(gè)ICER 來清除中斷位,而不是向ISER 寫0 來清除,是因?yàn)镹VIC 的這些寄
存器都是寫1 有效的,寫0 是無效的。具體為什么這么設(shè)計(jì),請(qǐng)看《CM3 權(quán)威指南》第125 頁(yè),
NVIC 概覽一章。
ISPR[2]:全稱是:Interrupt Set-Pending Registers,是一個(gè)中斷掛起控制寄存器組。每個(gè)位
對(duì)應(yīng)的中斷和ISER 是一樣的。通過置1,可以將正在進(jìn)行的中斷掛起,而執(zhí)行同級(jí)或更高級(jí)別
的中斷。寫0 是無效的。
ICPR[2]:全稱是:Interrupt Clear-Pending Registers,是一個(gè)中斷解掛控制寄存器組。其作
用與ISPR 相反,對(duì)應(yīng)位也和ISER 是一樣的。通過設(shè)置1,可以將掛起的中斷接掛。寫0 無效。
IABR[2]:全稱是:Active Bit Registers,是一個(gè)中斷激活標(biāo)志位寄存器組。對(duì)應(yīng)位所代表
的中斷和ISER 一樣,如果為1,則表示該位所對(duì)應(yīng)的中斷正在被執(zhí)行。這是一個(gè)只讀寄存器,
通過它可以知道當(dāng)前在執(zhí)行的中斷是哪一個(gè)。在中斷執(zhí)行完了由硬件自動(dòng)清零。
IPR[15]:全稱是:Interrupt Priority Registers,是一個(gè)中斷優(yōu)先級(jí)控制的寄存器組。這個(gè)寄
存器組相當(dāng)重要!STM32 的中斷分組與這個(gè)寄存器組密切相關(guān)。IPR 寄存器組由15 個(gè)32bit 的
寄存器組成,每個(gè)可屏蔽中斷占用8bit,這樣總共可以表示15*4=60 個(gè)可屏蔽中斷。剛好和
STM32 的可屏蔽中斷數(shù)相等。IPR[0]的[31~24],[23~16],[15~8],[7~0]分別對(duì)應(yīng)中中斷3~0,
依次類推,總共對(duì)應(yīng)60 個(gè)外部中斷。而每個(gè)可屏蔽中斷占用的8bit 并沒有全部使用,而是只
用了高4 位。這4 位,又分為搶占優(yōu)先級(jí)和子優(yōu)先級(jí)。搶占優(yōu)先級(jí)在前,子優(yōu)先級(jí)在后。而這
兩個(gè)優(yōu)先級(jí)各占幾個(gè)位又要根據(jù)SCB->AIRCR 中中斷分組的設(shè)置來決定。
這里簡(jiǎn)單介紹一下 STM32 的中斷分組:STM32 將中斷分為5 個(gè)組,組0~4。該分組的設(shè)
置是由SCB->AIRCR 寄存器的bit10~8 來定義的。具體的分配關(guān)系如下表所示:
所有的60 個(gè)中斷,每個(gè)中斷的中斷優(yōu)先寄存器的高四位中的最高3 位是搶占優(yōu)先級(jí),低1 位是
響應(yīng)優(yōu)先級(jí)。每個(gè)中斷,你可以設(shè)置搶占優(yōu)先級(jí)為0~7,響應(yīng)優(yōu)先級(jí)為1 或0。搶占優(yōu)先級(jí)的
級(jí)別高于響應(yīng)優(yōu)先級(jí)。而數(shù)值越小所代表的優(yōu)先級(jí)就越高。
結(jié)合實(shí)例說明一下:假定設(shè)置中斷優(yōu)先級(jí)組為2,然后設(shè)置中斷3(RTC 中斷)的搶占優(yōu)先級(jí)
為3,響應(yīng)優(yōu)先級(jí)為1。中斷6(外部中斷0)的搶占優(yōu)先級(jí)為4,響應(yīng)優(yōu)先級(jí)為0。中斷7(外
部中斷1)的搶占優(yōu)先級(jí)為3,響應(yīng)優(yōu)先級(jí)為0。那么這3 個(gè)中斷的優(yōu)先級(jí)順序?yàn)椋褐袛?>中
斷3>中斷6。
這里需要注意 2 點(diǎn):
如果兩個(gè)中斷的響應(yīng)優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí)都是一樣的話,則看哪個(gè)中斷先發(fā)生就先執(zhí)行。
高優(yōu)先級(jí)的搶占優(yōu)先級(jí)是可以打斷正在進(jìn)行的低搶占優(yōu)先級(jí)中斷的。而搶占優(yōu)先級(jí)相同的
中斷,高優(yōu)先級(jí)的響應(yīng)優(yōu)先級(jí)不可以打斷低響應(yīng)優(yōu)先級(jí)的中斷。上面例子中的中斷3 和中斷7
都可以打斷中斷6 的中斷。而中斷7 和中斷3 卻不可以相互打斷!
通過以上介紹,我們熟悉了 STM32 中斷設(shè)置的大致過程。接下來我們介紹如何使用函數(shù)
實(shí)現(xiàn)以上中斷設(shè)置,使得我們以后的中斷設(shè)置簡(jiǎn)單化。
第一個(gè)介紹的是NVIC 的分組函數(shù)MY_NVIC_PriorityGroupConfig,該函數(shù)的參數(shù)
NVIC_Group 為要設(shè)置的分組號(hào),可選范圍為0~4,總共5 組。如果參數(shù)非法,將可能導(dǎo)致不
//設(shè)置NVIC 分組
//NVIC_Group:NVIC 分組 0~4 總共5 組
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
u32 temp,temp1;
temp1=(~NVIC_Group)&0x07;//取后三位
temp=SCB->AIRCR; //讀取先前的設(shè)置
temp&=0X0000F8FF; //清空先前分組
temp|=0X05FA0000; //寫入鑰匙
temp|=temp1;
SCB->AIRCR=temp; //設(shè)置分組
}
通過前面的介紹,我們知道STM32 的5 個(gè)分組是通過設(shè)置SCB->AIRCR 的BIT[10:8]來實(shí)
現(xiàn)的,而通過2.7.2.1 的介紹我們知道SCB->AIRCR 的修改需要通過在高16 位寫入0X05FA 這
個(gè)密鑰才能修改的,故在設(shè)置AIRCR 之前,應(yīng)該把密鑰加入到要寫入的內(nèi)容的高16 位,以保
證能正常的寫入AIRCR。在修改AIRCR 的時(shí)候,我們一般采用讀->改->寫的步驟,來實(shí)現(xiàn)不
改變AIRCR 原來的其他設(shè)置。以上就是MY_NVIC_PriorityGroupConfig 函數(shù)設(shè)置中斷優(yōu)先級(jí)分
組的思路。
第 二 個(gè) 函 數(shù) 是NVIC 設(shè)置函數(shù)MY_NVIC_Init , 該函數(shù)有4 個(gè)參數(shù), 分別為:
NVIC_PreemptionPriority 、NVIC_SubPriority 、NVIC_Channel 、NVIC_Group 。第一個(gè)參數(shù)
NVIC_PreemptionPriority 為中斷搶占優(yōu)先級(jí)數(shù)值,第二個(gè)參數(shù)NVIC_SubPriority 為中斷子優(yōu)先
級(jí)數(shù)值,前兩個(gè)參數(shù)的值必須在規(guī)定范圍內(nèi),否則也可能產(chǎn)生意想不到的錯(cuò)誤。第三個(gè)參數(shù)
NVIC_Channel 為中斷的編號(hào)(范圍為0~59),最后一個(gè)參數(shù)NVIC_Group 為中斷分組設(shè)置(范
圍為0~4)。該函數(shù)代碼如下:
//設(shè)置NVIC
//NVIC_PreemptionPriority:搶占優(yōu)先級(jí)
//NVIC_SubPriority :響應(yīng)優(yōu)先級(jí)
//NVIC_Channel :中斷編號(hào)
//NVIC_Group :中斷分組 0~4
//注意優(yōu)先級(jí)不能超過設(shè)定的組的范圍!否則會(huì)有意想不到的錯(cuò)誤
//組劃分:
//組0:0 位搶占優(yōu)先級(jí),4 位響應(yīng)優(yōu)先級(jí)
//組1:1 位搶占優(yōu)先級(jí),3 位響應(yīng)優(yōu)先級(jí)
//組2:2 位搶占優(yōu)先級(jí),2 位響應(yīng)優(yōu)先級(jí)
//組3:3 位搶占優(yōu)先級(jí),1 位響應(yīng)優(yōu)先級(jí)
//組4:4 位搶占優(yōu)先級(jí),0 位響應(yīng)優(yōu)先級(jí)
//NVIC_SubPriority 和NVIC_PreemptionPriority 的原則是,數(shù)值越小,越優(yōu)先
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,
u8 NVIC_Group)
{
u32 temp;
u8 IPRADDR=NVIC_Channel/4; //每組只能存4 個(gè),得到組地址
u8 IPROFFSET=NVIC_Channel%4;//在組內(nèi)的偏移
IPROFFSET=IPROFFSET*8+4; //得到偏移的確切位置
MY_NVIC_PriorityGroupConfig(NVIC_Group);//設(shè)置分組
temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf;//取低四位
else NVIC->ISER[1]|=1<<(NVIC_Channel-32);
NVIC->IPR[IPRADDR]|=temp<
通過前面的介紹,我們知道每個(gè)可屏蔽中斷的優(yōu)先級(jí)的設(shè)置是在IPR 寄存器組里面的,每
個(gè)中斷占8 位,但只用了其中的4 個(gè)位,以上代碼就是根據(jù)中斷分組情況,來設(shè)置每個(gè)中斷對(duì)
應(yīng)的高4 位的數(shù)值的。當(dāng)然在該函數(shù)里面還引用了MY_NVIC_PriorityGroupConfig 這個(gè)函數(shù)來
設(shè)置分組。其實(shí)這個(gè)分組函數(shù)在每個(gè)系統(tǒng)里面只要設(shè)置一次就夠了,設(shè)置多次,則是以最后的
那一次為準(zhǔn)。但是只要多次設(shè)置的組號(hào)都是一樣,就沒事。否則前面設(shè)置的中斷會(huì)因?yàn)楹竺娼M
的變化優(yōu)先級(jí)會(huì)發(fā)生改變,這點(diǎn)在使用的時(shí)候要特別注意!一個(gè)系統(tǒng)代碼里面,所有的中斷分
組都要統(tǒng)一??!,以上代碼對(duì)要配置的中斷號(hào)默認(rèn)是開啟中斷的。也就是ISER 中的值設(shè)置為1
了。
相關(guān)推薦
技術(shù)專區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線
- 開關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論