Skip to content

STM32 Interrupt 中斷

發佈

前言

在上一篇中,我們使用輪詢的方式來讀取目前的按鈕狀態,但這種方式的效率不是很好,在需要讀取按鈕狀態等情況下,我們可以使用外部中斷(External Interrupt,EXTI),讓 CPU 可以去忙其它事情,等到按鈕被按下時會產生中斷事件,才去執行按鈕被按下時要處理的事。

在這一篇文章中,我將簡單介紹 STM32 的中斷。

中斷基本概念

中斷(Interrupt)是幾乎所有 MCU 都會有的基本功能(Arduino 也有)之一,如同它的名字,它是一種用來中斷其它程式的功能。

MCU 在工作時會遭遇許多不同的「事件」,例如按鈕被按下、接收到訊息、定時器到了等,而 MCU 也要為了這些事件作出相應的處理,這時就會需要先放下目前的工作,優先處理事件,而這就是中斷的目的:發生中斷事件時,暫時放下目前的工作,優先處理中斷,等中斷處理完後再回到原本的工作繼續執行。

例如小明正在寫作業,突然肚子痛,所以先跑去上廁所,上完廁所後再繼續寫作業。其中,「肚子痛」是一個事件,它會向大腦/CPU 發送中斷請求(Interrupt Request,IRQ),「上廁所」是中斷服務程式(Interrupt Service Routine,ISR)。每個 IRQ 都有對應的 ISR,當 IRQ 被接受時就會執行此對應的 ISR。

中斷向量

中斷向量(Interrupt Vector)指的是 ISR 的起始位址。而程式中的 ISR 通常會有很多,也就會有許多的中斷向量,把這些中斷向量儲存成表就是中斷向量表。

當 IRQ 被接受時,CPU 就會根據中斷向量表查詢 ISR 的起始位址,並開始執行 ISR。

中斷優先級

中斷通常也都會設計優先級。當多個 IRQ 發生時,CPU 會優先接受優先級較高的 IRQ。在 STM32(和大多數 MCU )中,最高的中斷優先級是等級 0,數字越大優先級越低。

而 STM32 的中斷優先級又再細分為搶佔優先級(Preemption Priority)和副優先級(Subpriority)。搶佔優先級的特色就如同它的名字——它可以從其它中斷中搶走優先執行的權利,也就是高搶佔優先級的 IRQ 可以中斷其它低搶佔優先級的 ISR;副優先級的運作方式就如同上面說的中斷優先級,用於在搶佔優先級相同的情況也能指定執行順序。

例如目前有一個搶佔優先級為 3 的中斷正在執行其 ISR——ISR_3,這時有個搶佔優先級為 2 的中斷事件發生了,這時 CPU 就會再「中斷」原本的 ISR_3,優先執行較高搶佔優先級的 ISR——ISR_2,等高搶佔優先級的 ISR_2 處理完了再回去繼續執行低搶佔優先級的 ISR_3

簡單來說,搶佔優先級決定了這個中斷可以中斷哪些其它的中斷,而副優先級決定了在搶佔優先級相同的情況下的優先順序。

優先級分組

STM32 還可以以 NVIC Priority Group 設定搶佔優先級與副優先級的等級數量。基本上中斷等級就是 16 個(4 bit),你可以決定這 4 個位元中,搶佔與副優先級要分配幾個位元。例如搶佔優先級分配了 4 bit,那就是 16 個等級全都是搶佔優先,沒有副優先級(都是 0),或搶佔優先級分配 1 bit,副優先級分配 3 bit 等。全部的分組方式如下:

組別搶佔優先級分配位元數 (等級數)副優先級分配位元數 (等級數)
00-bit (1)4-bit (16)
11-bit (2)3-bit (8)
22-bit (4)2-bit (4)
33-bit (8)1-bit (2)
44-bit (16)0-bit (1)

如果你使用了「組別 1」的設定,那搶佔優先級就有 2 個等級(01),副優先級有 8 種等級(000111)。

NVIC 為 Nested vectored interrupt controller(嵌套向量中斷控制器),是 ARM Cortex-M 的中斷控制單元。

小結

這次介紹了中斷的基本概念,中斷的基本原理每個 CPU/MCU 都大同小異,只是搶佔優先與副優先的概念可能一般不會聽到。

參考資料

本文同步發表於 iT 邦幫忙-2022 iThome 鐵人賽


STM32 EXTI 外部中斷
STM32 LibOpenCM3:GPIO 輸入

留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)