一、前言
在之前的STM32的中斷系統(tǒng)理論基礎(chǔ)知識(shí)之基本原理及NVIC中,分別中斷的基本原理,中斷的管理機(jī)制和中斷的處理流程進(jìn)行了較為詳細(xì)的論述,讀者通過全篇的閱讀了解可以整體上對以圍繞NVIC為管理核心的STM32的中斷系統(tǒng)有一個(gè)初步的了解,明白中斷的一些基本概念以及STM32中斷系統(tǒng)的一個(gè)大致的工作流程。
這一篇主要對中斷系統(tǒng)相關(guān)的寄存器進(jìn)行相應(yīng)的分析介紹,適當(dāng)了解中斷系統(tǒng)寄存器的相關(guān)介紹,有助于加深對STM32內(nèi)核的中斷及異常的認(rèn)識(shí),明白中斷時(shí)的功能都是由哪些寄存器負(fù)責(zé)完成實(shí)現(xiàn)的,同時(shí)對后續(xù)介紹到的中斷相關(guān)配置及API函數(shù)的使用有很好的幫助。
二、 寄存器概述
圖1為STM32中斷系統(tǒng)寄存器的概述,總共可以分為3組不同的寄存器組。各個(gè)寄存器組下分別又有不同用于中斷控制的寄存器。它們都屬于STM32內(nèi)核上的寄存器。
(1)、NVIC作為內(nèi)嵌向量中斷控制器,控制著整個(gè)芯片中斷相關(guān)的功能,它跟內(nèi)核緊密耦合,是內(nèi)核里面的一個(gè)外設(shè)。但是各個(gè)芯片廠商在設(shè)計(jì)芯片的時(shí)候會(huì)對 Cortex-M3 內(nèi)核里面的 NVIC 進(jìn)行裁剪,把不需要的部分去掉,所以說 STM32的 NVIC 是Cortex-M3的 NVIC 的一個(gè)子集。它用于總體管理異常和中斷,因此提供了和中斷系統(tǒng)緊密相關(guān)的控制和狀態(tài)寄存器;
(2)、SCB為系統(tǒng)控制塊,SCB中包含了一些內(nèi)核系統(tǒng)控制相關(guān)的寄存器,同時(shí)也包含了關(guān)于中斷相關(guān)的,由于本篇主要介紹中斷系統(tǒng),因此這里就只針對SCB中關(guān)于中斷控制的寄存器功能進(jìn)行分析介紹;
(3)、而為了滿足一些代碼段不允許被中斷打斷,那么這段代碼就必須用關(guān)中斷的方式給保護(hù)起來的場合,STM32提供了中斷屏蔽寄存器,我們可以一次性把一堆必須要屏蔽的中斷進(jìn)行屏蔽。
圖1 中斷系統(tǒng)寄存器概述
三、 NVIC****寄存器組
NVIC控制器包含一系列寄存器組,STM32為其定義了如下的結(jié)構(gòu)體:
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register*/
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register*/
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register*/
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644];
__IO uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register*/
} NVIC_Type;
(1)、中斷使能寄存器ISER
Interrupt Set-Enable Registers,這是一個(gè)中斷使能寄存器組??偣灿?個(gè)uint32類型的寄存器,即ISER[8],上面說了 CM3 內(nèi)核支持 256 個(gè)中斷,這里用 8 個(gè)32位寄存器來控制,每個(gè)位控制一個(gè)中斷。但是例如STM32F103 的可屏蔽中斷只有 60 個(gè),所以對我們來說,有用的就是兩個(gè)(ISER[0]和 ISER[1]),總共可以表示 64 個(gè)中斷。而 STM32F103 只用了其中的前 60 位。ISER[0]的 bit0 ~ bit31 分別對應(yīng)中斷 0 ~ 31。ISER[1]的 bit0 ~ 27 對應(yīng)中斷 32~59;這樣總共 60 個(gè)中斷就分別對應(yīng)上了。你要使能某個(gè)中斷,必須設(shè)置相應(yīng)的 ISER 位為 1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、IO 口映射等設(shè)置才算是一個(gè)完整的中斷設(shè)置)。
圖2 中斷使能和中斷除能寄存器組
(2)、中斷除能寄存器ICER
Interrupt Clear-Enable Registers,是一個(gè)中斷除能寄存器組??偣灿?個(gè)uint32類型的寄存器,即ICER[8],該寄存器組與 ISER 的作用恰好相反,是用來清除某個(gè)中斷的使能的。其對應(yīng)位的功能,也和 ICER 一樣。這里要專門設(shè)置一個(gè) ICER 來清除中斷位,而不是向 ISER 寫 0 來清除,是因?yàn)镹VIC 的這些寄存器都是寫 1 有效的,寫 0 是無效的。
(3)、中斷掛起控制寄存器ISPR
Interrupt Set-Pending Registers,是一個(gè)中斷掛起控制寄存器組??偣灿?個(gè)uint32類型的寄存器,即ISPR[8],每個(gè)位對應(yīng)的中斷和 ISER 是一樣的。通過置 1,可以將正在進(jìn)行的中斷掛起,暫時(shí)停止執(zhí)行該中斷,而執(zhí)行同級(jí)或更高級(jí)別的中斷。寫 0 是無效的。
圖3 中斷掛起和中斷解掛寄存器組
(4) 、中斷解掛控制寄存器ICPR
Interrupt Clear-Pending Registers,是一個(gè)中斷解掛控制寄存器組。總共有8個(gè)uint32類型的寄存器,即ICPR[8],其作用與 ISPR 相反,將之前暫時(shí)停止執(zhí)行的中斷解掛,對應(yīng)位也和 ISER 是一樣的。通過設(shè)置 1,可以將掛起的中斷解掛。寫 0 無效。
(5)、中斷激活標(biāo)志位寄存器IABR
Interrupt Active Bit Registers,是一個(gè)中斷激活標(biāo)志位寄存器組??偣灿?個(gè)uint32類型的寄存器,即IABR[8],對應(yīng)位所代表的中斷和 ISER 一樣,如果為 1,則表示該位所對應(yīng)的中斷正在被執(zhí)行。這是一個(gè)只讀寄存器,通過它可以知道當(dāng)前在執(zhí)行的中斷是哪一個(gè)。在中斷執(zhí)行完了由硬件自動(dòng)清零。如果在中斷執(zhí)行過程中,發(fā)生了更高優(yōu)先級(jí)的中斷搶占,那么之前被搶占的中斷該標(biāo)志位依然是1。
圖4 中斷激活標(biāo)志位寄存器組
(6)、中斷優(yōu)先級(jí)控制寄存器IP
Interrupt Priority Registers,是一個(gè)中斷優(yōu)先級(jí)控制的寄存器組。總共有240個(gè)uint8類型的寄存器,即IP[240],這個(gè)寄存器組相當(dāng)重要!STM32 的中斷分組與這個(gè)寄存器組密切相關(guān)。IP 寄存器組由 240 個(gè) 8bit 的寄存器組成,每個(gè)可屏蔽中斷占用 8bit,這樣總共可以表示 240 個(gè)可屏蔽中斷。而 STM32 只用到了其中的前 60 個(gè)。IP[59] ~ IP[0]分別對應(yīng)中斷 59 ~ 0。而每個(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è)置來決定。
圖5 中斷優(yōu)先級(jí)控制寄存器組
(7)、軟件觸發(fā)中斷寄存器STIR
這個(gè)寄存器是利用軟件設(shè)置中斷編號(hào)的方式來觸發(fā)中斷發(fā)生,是一個(gè)uint32類型的寄存器,有效位為0~8。比如設(shè)置NVIC->STIR=3,則會(huì)觸發(fā)中斷3,需要注意的是,該寄存器無法觸發(fā)系統(tǒng)異常如NMI或Systick的。
圖6 軟件觸發(fā)中斷寄存器
四、 SCB****寄存器組
系統(tǒng)控制塊(SCB)是內(nèi)核外設(shè)的主要模塊之一,提供系統(tǒng)控制以及系統(tǒng)執(zhí)行信息,包括配置,控制,報(bào)告系統(tǒng)異常等。而SCB數(shù)據(jù)結(jié)構(gòu)中也包含了一些常用于中斷控制的寄存器。
(1) 、中斷控制和狀態(tài)寄存器ICSR
該寄存器的主要作用為:
a. 設(shè)置和清除系統(tǒng)異常的掛起狀態(tài),異常包括Systick、PendSV、NMI。這個(gè)功能和NVIC的中斷掛起控制寄存器ISPR和中斷解掛控制寄存器ICPR差不多;
b.通過讀取VECTACTIVE=>Vector Active域,可以確定當(dāng)前執(zhí)行的異常/中斷編號(hào),VECTACTIVE域和中斷程序狀態(tài)寄存器(IPSR)功能比較類似,IPSR包含了當(dāng)前正在執(zhí)行的中斷服務(wù)程序(ISR)編號(hào),只不過VECTACTIVE是用來讀Systick、PendSV、NMI這些異常狀態(tài)的。
圖7 中斷控制和狀態(tài)寄存器
注意:當(dāng)寫ICSR時(shí),如果:寫1到PENDSVSET位和寫1到PENDSVCLR位;寫1到PENDSTSET位和寫1到PENDSTCLR位;程序執(zhí)行的效果是不可預(yù)測的。該寄存器各個(gè)位域可以通過調(diào)試器讀取狀態(tài),但多數(shù)情況下只有掛起位用于應(yīng)用開發(fā)。
(2) 、向量偏移寄存器VTOR
由于CPU隨時(shí)都可能檢測到中斷信息,也就是說,CPU 隨時(shí)都可能執(zhí)行中斷處理程序,所以中斷處理程序必須一直存儲(chǔ)在內(nèi)存某段空間之中。中斷處理程序在內(nèi)存中的入口地址稱為中斷向量;而要確定中斷處理程序的入口地址,處理器利用了一種向量表機(jī)制:即中斷向量,必須存儲(chǔ)在對應(yīng)的中斷向量表表項(xiàng)中。采用向量表處理中斷,處理器會(huì)從存儲(chǔ)器的向量表中,自動(dòng)定位中斷的程序入口。
一般來說,程序啟動(dòng)后,將首先從“中斷向量表”取出復(fù)位中斷向量執(zhí)行復(fù)位中斷程序完成啟動(dòng)。而這張“中斷向量表”的起始地址是0x8000004,當(dāng)中斷來臨,STM32的內(nèi)部硬件機(jī)制亦會(huì)自動(dòng)將PC指針定位到“中斷向量表”處,并根據(jù)中斷源取出對應(yīng)的中斷向量執(zhí)行中斷服務(wù)程序。不過有些應(yīng)用可能需要在運(yùn)行時(shí)修改或定義向量表地址。為了進(jìn)行這種處理,M3/M4處理器實(shí)現(xiàn)了一種名為向量表重定位的特性。向量表重定位特性提供了一個(gè)名為向量表偏移寄存器(VTOR)的可編程寄存器。該寄存器將正在使用的存儲(chǔ)器的起始地址定義為向量表。
圖8 向量偏移寄存器
中斷向量表里的中斷跳轉(zhuǎn)地址在編譯后就定下來了,SCB->VTOR向量可動(dòng)態(tài)調(diào)整就是讓我們的程序運(yùn)行后還能改變向量的跳轉(zhuǎn)地址。方法就是:在RAM重建一個(gè)中斷向量表,在想改變的位置重新賦值新的跳轉(zhuǎn)地址。通過賦值向量表偏移數(shù)值SCB->VTOR = (uint32_t)__VECTOR_RAM,這樣下次異常發(fā)生時(shí),就直接跳到重新指定的RAM中斷向量表的首地址處,再匹配對應(yīng)的中斷向量。
(3) 、應(yīng)用中斷和復(fù)位控制寄存器AIRCR
該寄存器用于:
控制異常/中斷優(yōu)先級(jí)管理中的優(yōu)先級(jí)分組
提供系統(tǒng)的端信息(可以被軟件或調(diào)試器使用)
提供自復(fù)位特性
圖9 應(yīng)用中斷和復(fù)位控制寄存器
SCB->AIRCR的中斷分組決定了如何去理解NVIC中斷優(yōu)先級(jí)控制寄存器IP的高4bit(47bit)。SCB->AIRCR的810位決定了分組的組別,可以分為0到4共5組,不同的組別決定了IP寄存器劃分的搶占優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí)各占幾位。
VECTRESET和VECTCLRACTIVE位域是為調(diào)試器設(shè)計(jì)的,盡管軟件可以利用VECTRESET觸發(fā)一次處理器復(fù)位,不過由于它不會(huì)復(fù)位外設(shè)等系統(tǒng)中的其他部分,因此多數(shù)應(yīng)用程序是不大會(huì)用到它的。若想產(chǎn)生一次系統(tǒng)復(fù)位,多數(shù)情況下(取決于芯片設(shè)計(jì)和應(yīng)用復(fù)位需求)應(yīng)該使用SYSRESETREQ。有一點(diǎn)要注意,VECTRESET和VECTCLRACTIVE不應(yīng)同時(shí)置位,非要這么做的話會(huì)導(dǎo)致Cortex-M3/M4設(shè)備的復(fù)位電路出錯(cuò)。
在Cortex-M3中,有兩種方法能夠進(jìn)行系統(tǒng)復(fù)位:
第一種方法:置位 NVIC 中應(yīng)用程序中斷與復(fù)位控制寄存器(AIRCR)的 VECTRESET 位(位偏移:0)。這種復(fù)位的作用為復(fù)位Cortex-M3處理器內(nèi)核,除了調(diào)試邏輯之外的所有角落,但是它不會(huì)影響到Cortex-M3處理器外部的任何電路,所以STM32上的各片上外設(shè)和其它電路都不受影響。
第二種方法:置位 NVIC 中應(yīng)用程序中斷與復(fù)位控制寄存器(AIRCR)的 SYSRESETREQ位(位偏移:2)。系統(tǒng)復(fù)位是置位同一個(gè)寄存器中的 SYSRESETREQ 位。這種復(fù)位則會(huì)波及整個(gè)芯片上的電路:它會(huì)使Cortex-M3/M4處理器把送往系統(tǒng)復(fù)位發(fā)生器的請求線置為有效。但是系統(tǒng)復(fù)位發(fā)生器不是Cortex-M3/M4的這一局部,而是由芯片廠商實(shí)現(xiàn),因此不同的芯片對此復(fù)位的響應(yīng)也不同。因此,讀者須要仔細(xì)參閱芯片規(guī)格書,明白當(dāng)發(fā)生片內(nèi)復(fù)位時(shí),各外設(shè)和功能模塊都會(huì)回到什么樣的初始狀態(tài),或者有哪些功能模塊不受影響(假如,STM32系列的芯片有后備存儲(chǔ)區(qū),該區(qū)就被特殊對待)。大部分情況下,復(fù)位發(fā)生器在響應(yīng)SYSRESETREQ 時(shí),它也會(huì)同時(shí)把Cortex-M3/M4處理器的系統(tǒng)復(fù)位信號(hào)(SYSRESETn)置為有效。通常,SYSRESETREQ不應(yīng)復(fù)位調(diào)試邏輯。這里有一個(gè)要注意的問題:從SYSRESETREQ被置為有效到復(fù)位發(fā)生器執(zhí)行復(fù)位命令,往往會(huì)有一個(gè)延時(shí)。在此延時(shí)期間,處理器依然能夠響應(yīng)中斷請求。但我們的本意往往是要讓此次執(zhí)行到此為止,不要再做任何其它事情了。所以,最好在發(fā)出復(fù)位請求前,先把FAULTMASK置位。
這里有一個(gè)要注意的問題:從SYSRESETREQ 被置為有效,到復(fù)位發(fā)生器執(zhí)行復(fù)位命令,往往會(huì)有一個(gè)延時(shí)。在此延時(shí)期間,處理器仍然可以響應(yīng)中斷請求。但我們的本意往往是要讓此次執(zhí)行到此為止,不要再做任何其它事情了。所以,最好在發(fā)出復(fù)位請求前,先把FAULTMASK 置位,才萬無一失。即:
void mcuRestart(void)
{
__set_FAULTMASK(1); //關(guān)閉所有中斷
NVIC_SystemReset(); //復(fù)位
}
(4) 系統(tǒng)處理優(yōu)先級(jí)處理器SHP
SCB->SHP[0]到SCB->SHP[11]的位域定義和NVIC中斷優(yōu)先級(jí)寄存器IP的定義相同,不同之處是SHP是用于系統(tǒng)異常優(yōu)先級(jí)的。這些寄存器并未全部實(shí)現(xiàn),為了編程中斷和異常的優(yōu)先級(jí),CMSIS提供了函數(shù)NVIC_SetPrioriity和NVIC_GetPriority。這兩個(gè)函數(shù)位于core_cm3.h中。例如:
圖10 系統(tǒng)處理優(yōu)先級(jí)處理器
(5) 、系統(tǒng)處理控制和狀態(tài)寄存器SHCSR
使用錯(cuò)誤、存儲(chǔ)器管理錯(cuò)誤和總線錯(cuò)誤異常的使能由該寄存器控制。錯(cuò)誤的掛起狀態(tài)和多數(shù)系統(tǒng)異常的活躍狀態(tài)也可以從該寄存器中得到。
多數(shù)情況下,該寄存器及用于應(yīng)用代碼使能可配置的錯(cuò)誤處理(MEMFAULT、 BUSFAULT、USGFAULT)。
圖11 系統(tǒng)處理控制和狀態(tài)寄存器
使能位ENA,設(shè)置1使能異常,設(shè)置0失能異常。
待定位PENDED,如果異常待定讀為1,否則讀為0。我們可以寫這些位改變異常的待定狀態(tài)。
活躍位ACT,如果異?;钴S讀為1,否則讀為0。我們可以寫這些位改變異常的活躍狀態(tài),但是看這部分的注意事項(xiàng)。
盡管可以寫SCB->SHCSR寄存器的所有位,但建議軟件只寫異常使能位。寫這個(gè)寄存器需要小心,確保系統(tǒng)異常的活躍位狀態(tài)不會(huì)被意外修改,使能異常時(shí),應(yīng)該使用一次讀修改寫順序的操作。下面的例子用于使能所有非硬Fault(存儲(chǔ)器管理Fault、總線Fault、用法Fault異常):
不然若一個(gè)已經(jīng)被激活的系統(tǒng)異常的活躍狀態(tài)被意外清除了,當(dāng)系統(tǒng)異常處理產(chǎn)生異常退出時(shí)就會(huì)出現(xiàn)錯(cuò)誤異常。
五、 中斷屏蔽寄存器組
中斷屏蔽寄存器的目的是讓實(shí)時(shí)性要求高的任務(wù)或者事件能夠順利執(zhí)行,因此要在需要的時(shí)候暫時(shí)屏蔽中斷。
圖12 異常和中斷編號(hào)表
編號(hào)為 0~15 的稱為內(nèi)核異常,而 16 以上的則稱為核外(外部)中斷。
PRIMASK
PRIMASK雖然是32位的寄存器,但是只有最低位有效,這是一個(gè)只有1個(gè)bit有效的寄存器。當(dāng)將寄存器的位置為1時(shí),相當(dāng)于將當(dāng)前中斷的優(yōu)先級(jí)設(shè)為0,它只響應(yīng)NMI(優(yōu)先級(jí)為-2更高)和HardFault(優(yōu)先級(jí)為-1更高)異常,關(guān)掉其它優(yōu)先級(jí)小于0(即數(shù)值比0大)所有可屏蔽的異?;蛑袛啵患拇嫫鞯哪J(rèn)值是0,表示沒有關(guān)異?;蛘咧袛唷?/p>
PRIMASK通常用于在處理有實(shí)時(shí)性要求(time critical)的程序時(shí)關(guān)閉所有中斷, 實(shí)時(shí)程序處理完畢后清除PRIMASK,重新開啟中斷。
FAULTMASK
FAULTMASK雖然是32位的寄存器,但是只有最低位有效,這是一個(gè)只有1個(gè)bit有效的寄存器。當(dāng)將寄存器的位置為1時(shí),當(dāng)于將當(dāng)前中斷的優(yōu)先級(jí)設(shè)為-1,它只響應(yīng)NMI(優(yōu)先級(jí)為-2更高),關(guān)掉其它優(yōu)先級(jí)小于-1(即數(shù)值比-1大)的可屏蔽的異常或中斷,甚至是HardFault異常也關(guān)閉;寄存器的默認(rèn)值是0,表示沒有關(guān)異常或者中斷。
BASEPRI
為了提供靈活的中斷屏蔽機(jī)制,內(nèi)核架構(gòu)提供了BASEPRI寄存器,可以根據(jù)優(yōu)先級(jí)屏蔽中斷或者異常,屏蔽的是搶占優(yōu)先級(jí)(主優(yōu)先級(jí)),它可以由用戶來定義需要屏蔽中斷的優(yōu)先級(jí)的閾值,當(dāng)設(shè)置為具體的閾值時(shí),所有大于該數(shù)字值的中斷都被關(guān)閉(優(yōu)先級(jí)數(shù)字越大,表示優(yōu)先級(jí)越低);這里設(shè)置的優(yōu)先級(jí)針對的是搶占優(yōu)先級(jí);寄存器的默認(rèn)值是0,表示沒有關(guān)異?;蛘咧袛?。
比如我們配置寄存器BASEPRI的數(shù)值為3,所有優(yōu)先級(jí)數(shù)值大于等于3的中斷都會(huì)被關(guān)閉,優(yōu)先級(jí)數(shù)值小于3的中斷不會(huì)被關(guān)閉。但0比較特殊,對寄存器basepri寄存器賦值0,那么被關(guān)閉的中斷會(huì)被打開。
寄存器BASEPRI的有效位數(shù)受系統(tǒng)中表達(dá)優(yōu)先級(jí)的位數(shù)影響,如果系統(tǒng)中只使用3個(gè)位(5~7bit)來表達(dá)優(yōu)先級(jí),則BASEPRI有意義的值僅為0x00、0x20、0x40、0x60、0x80、0xA0、0xC0和0xE0。
圖12 寄存器BASEPRI
六、總結(jié)
本篇對STM32的中斷系統(tǒng)涉及到的的寄存器分別進(jìn)行了介紹,了解了各個(gè)寄存器的功能和對應(yīng)寄存器位的定義可以更方便的去理解在實(shí)際使用中斷配置時(shí)的配置功能,下一篇將對中斷配置流程在實(shí)際開發(fā)中的設(shè)計(jì)及應(yīng)用進(jìn)行詳細(xì)的分析。
-
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120365 -
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
356008 -
中斷系統(tǒng)
+關(guān)注
關(guān)注
1文章
96瀏覽量
61021
發(fā)布評論請先 登錄
相關(guān)推薦
評論