0x01 > 什么是中斷
???????? 所謂中斷就是指CPU正處于工作狀態(tài)時(shí),外部發(fā)生了某一事件(按鍵按下),請(qǐng)求CPU進(jìn)行處理,于是 CPU暫時(shí)中斷當(dāng)前的工作,轉(zhuǎn)而處理所發(fā)生的的事件,處理完畢在回到原來(lái)被中斷的地方繼續(xù)工作,這樣的過(guò)程被稱為中斷

中斷包括以下幾部分
- 中斷源
- 中斷申請(qǐng)
- 開(kāi)放中斷
- 保護(hù)現(xiàn)場(chǎng)
- 中斷服務(wù)
- 恢復(fù)現(xiàn)場(chǎng)
- 中斷返回
我們知道 傳統(tǒng)的51單片機(jī)一共有 5 個(gè)中斷源,它們分別為:
- 外部中斷0
- 定時(shí)器0
- 外部中斷1
- 定時(shí)器1
現(xiàn)在正在學(xué)習(xí)的 STM32 有多少中斷呢?
0x02 > STM32 中斷基礎(chǔ)知識(shí)
- Cortex-m3支持256個(gè)中斷,其中包含了16個(gè)內(nèi)核中斷,240個(gè)外部中斷。
- STM32 只有84個(gè)中斷,包括16個(gè)內(nèi)核中斷和68個(gè)可屏蔽中斷
- STM32 上只有60個(gè)可屏蔽中斷,f107上才有68個(gè)中斷
- 先占優(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í)行位于中斷向量表中位置較高的中斷。
? 0x001 >> 嵌套向量中斷控制器 (NVIC)
? ? STM32 的中斷既然有這么多,那么要怎么管理呢?
ST也給了我們一些解決方案就是 使用 嵌套中斷向量控制器 NVIC,NVIC屬于內(nèi)核級(jí)的寄存器,所以當(dāng)我們需要查詢 NVIC 相關(guān)定義 應(yīng)該到 core_cm3.h 中(這里講解的芯片是 STM32F103ZE 是基于 Coretex-M3)
/* 訪問(wèn)嵌套向量中斷控制器 (NVIC)的結(jié)構(gòu)類型 */
typedef struct
{
__IOM uint32_t ISER[8U]; /* 中斷使能寄存器 */
uint32_t RESERVED0[24U];
__IOM uint32_t ICER[8U]; /* 中斷清除寄存器 */
uint32_t RSERVED1[24U];
__IOM uint32_t ISPR[8U]; /* 中斷懸起寄存器 */
uint32_t RESERVED2[24U];
__IOM uint32_t ICPR[8U]; /* 中斷清空懸起寄存器 */
uint32_t RESERVED3[24U];
__IOM uint32_t IABR[8U]; /* 中斷有效位寄存器 */
uint32_t RESERVED4[56U];
__IOM uint8_t IP[240U]; /* 中斷優(yōu)先級(jí)寄存器(8Bit wide) */
uint32_t RESERVED5[644U];
__OM uint32_t STIR; /* 軟件觸發(fā)中斷寄存器 */
} NVIC_Type;
? 0x002 >> 中斷優(yōu)先級(jí)定義 ☆

coretex-M3 內(nèi)核的中斷定義寄存器的寬度是8位的,在上圖中,我們能看到ST在設(shè)計(jì)中斷的時(shí)候只使用了高4位 [7:4]
The processor implements only bits[7:4] of each field, bits[3:0] read as zero and ignore writes.
處理器只實(shí)現(xiàn)每個(gè)字段的位[7:4],位[3:0]讀為零,忽略寫(xiě)。
ST在上述分組中,ST還將中斷分成了主優(yōu)先級(jí)(搶占優(yōu)先級(jí))和子優(yōu)先級(jí)(響應(yīng)優(yōu)先級(jí))。對(duì)應(yīng)的寄存器


上圖就是,優(yōu)先級(jí)分組寄存器和對(duì)應(yīng)的優(yōu)先級(jí)分組,下面來(lái)簡(jiǎn)單的總結(jié)一下優(yōu)先級(jí)分組怎么用。

/* LL 庫(kù)中斷優(yōu)先級(jí)分組,選項(xiàng)和實(shí)現(xiàn) */
#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
4 bits for subpriority */
#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bit for pre-emption priority,
3 bits for subpriority */
#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority,
2 bits for subpriority */
#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority,
1 bit for subpriority */
#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority,
0 bit for subpriority */
/**
\brief Set Priority Grouping
\details Sets the priority grouping field using the required unlock sequence.
The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
Only values from 0..7 are used.
In case of a conflict between priority grouping and available
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
\param [in] PriorityGroup Priority grouping field.
*/
__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
uint32_t reg_value;
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
reg_value = SCB->AIRCR; /* read old register configuration */
reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
reg_value = (reg_value |
((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
(PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */
SCB->AIRCR = reg_value;
}
假設(shè)我們有兩個(gè)外設(shè) 外設(shè)A 和外設(shè)B 我們將 兩個(gè)外設(shè)的主優(yōu)先級(jí)都配置為 0,將外設(shè) A 的子優(yōu)先級(jí)配置為 1,外設(shè) B 的子優(yōu)先級(jí)配置為 2,。當(dāng)它們的中斷請(qǐng)求同時(shí)到來(lái)時(shí),內(nèi)核將如何執(zhí)行?
內(nèi)核將比較兩個(gè)外設(shè)的主優(yōu)先級(jí),如果外設(shè)的主優(yōu)先級(jí)相等,就會(huì)對(duì)子優(yōu)先級(jí)進(jìn)行比較,子優(yōu)先級(jí)越高,子優(yōu)先級(jí)的數(shù)字就越小。
令人頭痛的問(wèn)題,如果外設(shè)的主優(yōu)先級(jí)、子優(yōu)先級(jí)都相同,怎么判斷?
如果外設(shè)的主優(yōu)先級(jí)和子優(yōu)先級(jí)都相等,那么將會(huì)對(duì)硬件中斷編號(hào)進(jìn)行比較
硬件編號(hào)在哪?
硬件編號(hào) 位于 《STM32 中文參考手冊(cè)_V10》第九章 中斷和事件 第9.1.2小節(jié) 中斷和異常向量表
0x03 > 總結(jié)
以上就是 關(guān)于 STM32F103ZE 的外部中斷與中斷管理的理論部分。這篇文章可能會(huì)讓你感到晦澀難懂,或者有漏洞,那是在所難免的問(wèn)題。
如有錯(cuò)誤,歡迎指正,對(duì)您有幫助,點(diǎn)個(gè)贊再走 (>..<)