【STM32 LL庫(kù)編程】外部中斷與中斷管理

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è)中斷源,它們分別為:

  1. 外部中斷0
  2. 定時(shí)器0
  3. 外部中斷1
  4. 定時(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í)定義 ☆

中斷優(yōu)先級(jí)設(shè)定寄存器

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í)分組寄存器

優(yōu)先級(jí)組

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


優(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è)贊再走 (>..<)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容