1. 程式人生 > >STM32 I/O 作為外部中斷輸入

STM32 I/O 作為外部中斷輸入

 I/O口作為外部中斷。general  purpose input and output

STM32 的每個 IO口都可以作為中斷輸入,要把 IO口作為外部中斷輸入,
有以下幾個步驟:
1) 初始化 IO 口為輸入。
這一步設定你要作為外部中斷輸入的
IO 口的狀態,可以設定為上拉/下拉輸入,也可以設
置為浮空輸入,但浮空的時候外部一定要帶上拉,或者下拉電阻。否則可能導致中斷不停的觸
發。在干擾較大的地方,就算使用了上拉
/下拉,也建議使用外部上拉/下拉電阻,這樣可以一
定程度防止外部干擾帶來的影響。
2) 開啟 IO 口複用時鐘,設定 IO 口與中斷線的對映關係。
STM32 IO 口與中斷線的對應關係需要配置外部中斷配置暫存器

EXTICR,這樣我們要
先開啟複用時鐘,然後配置
IO 口與中斷線的對應關係。才能把外部中斷與中斷線連線起來。
3) 開啟與該 IO 口相對的線上中斷/事件,設定觸發條件。
這一步,我們要配置中斷產生的條件,
STM32 可以配置成上升沿觸發,下降沿觸發,或者
任意電平變化觸發,但是不能配置成高電平觸發和低電平觸發。這裡根據自己的實際情況來配
置,同時要開啟中斷線上的中斷。這裡需要注意的是:如果使用外部中斷,並設定該中斷的
EMR
位的話,會引起軟體模擬不能跳到中斷,而硬體上是可以的。而不設定 EMR,軟體模擬就可以
進入中斷服務函式,並且硬體上也是可以的。建議不要配置
EMR 位。
4) 配置中斷分組(NVIC
),並使能中斷。
這一步,我們就是配置中斷的分組,以及使能,對
STM32 的中斷來說,只有配置了 NVIC
的設定,並開啟才能被執行,否則是不會執行到中斷服務函式裡面去的。關於 NVIC 的詳細介
紹,請參考
5.2.6 節。
5) 編寫中斷服務函式。
這是中斷設定的最後一步,中斷服務函式,是必不可少的,如果在程式碼裡面開啟了中斷,
但是沒編寫中斷服務函式,就可能引起硬體錯誤,從而導致程式崩潰!所以在開啟了某個中斷

後,一定要記得為該中斷編寫服務函式。在中斷服務函式裡面編寫你要執行的中斷後的操作。

NVIC 相關的暫存器, MDK 為其定義瞭如下的結構體:
typedef struct
{
__IO uint32_t ISER[8]; //

中斷使能暫存器組 Interrupt Set-Enable Registers
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; //
中斷除能暫存器組
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; //
中斷掛起控制暫存器組
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; //
中斷解掛控制暫存器組
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; //
中斷啟用標誌位暫存器組
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; //
中斷優先順序控制暫存器組
uint32_t RESERVED5[644];
__O uint32_t STIR; //
軟體觸發中斷暫存器組
} NVIC_Type;

        ISER[8]ISER 全稱是: Interrupt Set-Enable Registers 每1 bit 代表一箇中斷,總共有32×8=256箇中斷,你要使能某個中斷,必須設定相應的 ISER 位為 1,使該中斷被使能(這裡僅僅是使能,還要配合中斷分組、遮蔽、 IO 口對映等設定才算是一個完整的中斷設定)

        ICER[8]:全稱是: Interrupt Clear-Enable Registers 該暫存器組與 ISER[8] 的作用恰好相反,是用來清除某個中斷的使能的。 如果想清除一箇中斷,不是在對應bit寫0,而應該在對應位置寫1。寫0是無效的。
        ISPR[8]:全稱是: Interrupt Set-Pending Registers ,每個位對應的中斷和 ISER 是一樣的。通過置 1,可以將正在進行的中斷掛起,而執行同級或更高級別的中斷。寫 0 是無效的。

        ICPR[8]:全稱是: Interrupt Clear-Pending Registers ,通過設定 1,可以將掛起的中斷取消掛起操作。寫 0 無效。

        IABR[8]:全稱是: Interrupt Active Bit Registers,是一箇中斷啟用標誌位暫存器組。對應位所代表的中斷和 ISER 一樣,如果為 1,則表示該位所對應的中斷正在被執行。這是一個只讀暫存器,通過它可以知道當前在執行的中斷是哪一個。在中斷執行完了由硬體自動清零。

        IP[240]:全稱是: Interrupt Priority Registers 是一個中斷優先順序控制的暫存器組。這個暫存器組相當重要! STM32 的中斷分組與這個暫存器組密切相關。 IP 暫存器組由 240 8bit 的寄存器組成,每個可遮蔽中斷佔用 8bit,這樣總共可以表示 240 個可遮蔽中斷。 而 STM32 只用到了其中的 68 個。 IP[67]~IP[0]分別對應中斷 67~0。 而每個可遮蔽中斷佔用的 8bit 並沒有全部使用,而是 只用了高 4 。這 4 位,又分為搶佔優先順序和子優先順序。搶佔優先順序在前,子優先順序在後。而這兩個優先順序各佔幾個位又要根據 SCB->AIRCR 中的中斷分組設定來決定。搶佔優先順序的級別高於響應優先順序。而數值越小所代表的優先順序就越高。

STM32 5 個分組是通過設定 SCB->AIRCR BIT[10:8]來實現的,而SCB->AIRCR 的修改需要通過在高 16 位寫入 0X05FA這個金鑰才能修改的,故在設定 AIRCR 之前,應該把金鑰加入到要寫入的內容的高 16 位,以保證能正常的寫入 AIRCR在修改 AIRCR 的時候,我們一般採用讀->改->寫的步驟,來實現不改AIRCR 原來的其他設定。

這裡簡單介紹一下 STM32 的中斷分組: STM32 將中斷分為 5 個組,組 0~4。該分組的設
置是由
SCB->AIRCR 暫存器的 bit10~8 來定義的。具體的分配關係如表 5.2.6.1
所示:

AIRCR[108] bit[74]分配情況 分配結果
0 111 04 0 位搶佔優先順序, 4 位響應優先順序
1 110 13 1 位搶佔優先順序, 3 位響應優先順序
2 101 22 2 位搶佔優先順序, 2 位響應優先順序
3 100 31 3 位搶佔優先順序, 1 位響應優先順序
4 011 40 4 位搶佔優先順序, 0 位響應優先順序

                                                                表 5.2.6.1 AIRCR 中斷分組設定表

//設定 NVIC
//NVIC_PreemptionPriority
: 搶佔優先順序
//NVIC_SubPriority : 響應優先順序
//NVIC_Channel : 中斷編號
//NVIC_Group : 中斷分組 0~4
//
注意優先順序不能超過設定的組的範圍!否則會有意想不到的錯誤
//組劃分:
//00 位搶佔優先順序, 4 位響應優先順序
//11 位搶佔優先順序, 3 位響應優先順序
//22 位搶佔優先順序, 2 位響應優先順序
//33 位搶佔優先順序, 1 位響應優先順序
//44 位搶佔優先順序, 0 位響應優先順序
//NVIC_SubPriority NVIC_PreemptionPriority 的原則是, 數值越小, 越優先
void MY_NVIC_Init(u8 NVIC_PreemptionPriorityu8 NVIC_SubPriorityu8 NVIC_Channelu8 NVIC_Group)
{
u32 temp;
MY_NVIC_PriorityGroupConfig(NVIC_Group);//
設定分組
temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf; //
取低四位
NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);
//
使能中斷位(要清除的話,相反操作就 OK)
NVIC->IP[NVIC_Channel]|=temp<<4;     //
設定響應優先順序和搶斷優先順序
}

 NVIC配置總結:

  1)  SCB->AIRCR 決定搶佔優先順序的位數,設定怎麼解釋IP(interrupt priority)分組。其實這個分組的設定在每個系統裡面只要設定一次就夠了,設定多次,則是以最後的那一次為準。整個系統的優先順序分組格式都一樣。

 2)   ISER 使能對應的中斷管腳,

 3)設定優先順序。
       IP[channel] 決定具體的搶佔優先順序和子優先順序。

       IP和SCB->AIRCR 一起決定中斷的優先順序。

       IABR 自讀,顯示當前正在執行的中斷時那個管腳的中斷。

》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

以上是對NVIC的管理和配置,下面說明一下外不中斷的配置。

》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

STM32F103 EXTI 控制器支援 19 個外部中斷/事件請求。每個中斷設有狀態位,每個中斷/事件都有獨立的觸發和遮蔽設定STM32F103 19 個外部中斷為:
    線
0~15:對應外部 IO 口的輸入中斷。
    線
16:連線到 PVD 輸出。
    線
17:連線到 RTC 鬧鐘事件。
    線
18:連線到 USB 喚醒事件。
對於外部中斷
EXTI 控制 MDK 定義瞭如下結構體:
typedef struct
{
__IO uint32_t IMR;  //interrupt mask register
__IO uint32_t EMR;  //event mask register 
__IO uint32_t RTSR;  //rising trigger selection register 
__IO uint32_t FTSR;  //falling trigger selection register 
__IO uint32_t SWIER;   //software interrupt event register  
__IO uint32_t PR;     //pending register 
} EXTI_TypeDef;

    IMR中斷遮蔽暫存器。這是一個 32 暫存器。但是隻有前 19 位有效(19個外部中斷)。當位 x 設定為 1 時,則開啟這個線上的中斷,否則關閉該線上的中斷。
    EMR:事件遮蔽暫存器,同 IMR,只是該暫存器是針對事件的遮蔽和開啟
    RTSR上升沿觸發選擇暫存器。該暫存器同 IMR,也是一個 32 為的暫存器,只有前 19位有效。位 x 對應線 x 上的上升沿觸發,如果設定為 1,則是允許上升沿觸發中斷/事件。否則,不允許。
    FTSR下降沿觸發選擇暫存器。同 RTSR,不過這個暫存器是設定下降沿的。下降沿和上升沿可以被同時設定,這樣就變成了任意電平觸發了。
    SWIER軟體中斷事件暫存器通過向該暫存器的位 x 寫入 1,在未設定 IMR EMR 的時候,將設定 PR 中相應位掛起如果設定了 IMR EMR 時將產生一次中斷。被設定的 SWIER位,將會在 PR 中的對應位清除後清除。
    PR掛起暫存器當外部中斷線上發生了選擇的邊沿事件,該暫存器的對應位會被置為 10:表示對應線上沒有發生觸發請求。通過向該暫存器的對應位寫入 1 可以清除該位在中斷服務函式裡面經常會要向該暫存器的對應位寫 1 來清除中斷請求 。

        通過以上配置就可以正常設定外部中斷了,但是外部 IO 口的中斷,還需要一個暫存器配置,也就是 IO 複用裡的外部中斷配置暫存器 EXTICR這是因為 STM32 任何一個 IO 口都可以配置成中斷輸入口,但是 IO 口的數目遠大於中斷線數(16 個)。於是 STM32 就這樣設計,GPIOA~GPIOG [15:0]分別對應中斷線 15~0

        這樣每個中斷線對應了最多 7 IO 口,以中斷線 0為例:它對應了 GPIOA.0GPIOB.0GPIOC.0GPIOD.0GPIOE.0GPIOF.0GPIOG.0而中斷線每次只能連線到 1IO口上,這樣就需要 EXTICR來決定對應的中斷線配置到哪個 GPIO上了。

EXTICR AFIO 的結構體中定義,如下:
typedef struct
{
    __IO uint32_t EVCR;
    __IO uint32_t MAPR;
    __IO uint32_t EXTICR[4];

} AFIO_TypeDef;


-------

EXTICR1


EXTICR2 對應EXTI4,EXTI5,EXTI6,EXTI7。

EXTICR3 對應EXTI8,EXTI9,EXTI10,EXTI11。

EXTICR4 對應EXTI12,EXTI13,EXTI14,EXTI15。

對映GPIOX_K 管腳。

例如,EXTI11,配置外部中斷管腳11,通過對EXTIX[3:0]的設定分別設定為GPIOA  ~ GPIOG 。

//外部中斷配置函式
//只針對 GPIOA~G;不包括 PVDRTC USB 喚醒這三個
//引數: GPIOx0~6, 代表 GPIOA~G;
//BITx
: 需要使能的位;
//TRIM
: 觸發模式, 1, 下升沿; 2, 上降沿;3,任意電平觸發
//該函式一次只能配置 1 IO 口, 多個 IO 口, 需多次呼叫
//該函式會自動開啟對應中斷, 以及遮蔽線
void Ex_NVIC_Config(u8 GPIOxu8 BITxu8 TRIM)
{
u8 EXTADDR;

u8 EXTOFFSET;
EXTADDR=BITx/4; //
得到中斷暫存器組的編號
EXTOFFSET=(BITx%4)*4;//得到中斷暫存器組內的偏移
RCC->APB2ENR|=0x01; //enable AFIO  clock
AFIO->EXTICR[EXTADDR]&=~(0x000F<<EXTOFFSET);//清除原來設定!!!
AFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;        //EXTI.BITx 對映到 GPIOx.BITx
//
自動設定
EXTI->IMR|=1<<BITx;     //開啟 line BITx 上的中斷,寫1 開啟中斷
if(TRIM&0x01)EXTI->FTSR|=1<<BITx; //line BITx 上事件下降沿觸發

if(TRIM&0x02)EXTI->RTSR|=1<<BITx; //line BITx 上事件上升降沿觸發
}

        Ex_NVIC_Config 完全是按照我們之前的分析來編寫的,首先根據 GPIOx 的位得到中斷暫存器組的編號,即 EXTICR 的編號,EXTICR 裡面配置中斷線應該配置到 GPIOx 的哪個位然後使能該位的中斷及事件,最後配置觸發方式。這樣就完成了外部中斷的配置了。


 NVIC配置總結:

  1)  SCB->AIRCR 決定搶佔優先順序的位數,設定怎麼解釋IP(interrupt priority)分組。其實這個分組的設定在每個系統裡面只要設定一次就夠了,設定多次,則是以最後的那一次為準。整個系統的優先順序分組格式都一樣。

 2)   ISER 使能對應的中斷bit,

 3)設定優先順序。
       IP[channel] 決定具體的搶佔優先順序和子優先順序。

       IP和SCB->AIRCR 一起決定中斷的優先順序。

       IABR 自讀,顯示當前正在執行的中斷時那個管腳的中斷。


外部中斷配置總結:

    1) EXTI.BITx 對映到 GPIOx.BITx,通過AFIO_EXTICRn。

    2)開啟外部中斷線。

    3)設定觸發方式。

相關推薦

STM32 I/O 作為外部中斷輸入

 I/O口作為外部中斷。general  purpose input and outputSTM32 的每個 IO口都可以作為中斷輸入,要把 IO口作為外部中斷輸入,有以下幾個步驟:1) 初始化 IO 口為輸入。這一步設定你要作為外部中斷輸入的 IO 口的狀態,可以設定為上拉

stm32紅外遙控的外部中斷實現

花了整整兩天時間終於算是基本把紅外解碼搞明白了,其實並不是很難,用了兩天時間,說來慚愧啊,原因就是細節上的問題,不過最終總算找出問題來了。使用外部中斷來解碼,就先對外部中斷進行配置吧 void exti_init() {  RCC->APB2ENR|=1<

裝置管理---I/O系統與中斷機構

一、I/O系統的基本功能、模型和介面 關於裝置管理 管理物件:I/O裝置和相應的裝置控制器(I/O系統組成) 基本任務: (1)完成使用者提出的I/O請求, (2)提高I/O速率、改善I/O裝置的利用率。 (3)為更高層程序方便使用裝置提供手段 I/O系統的

I/O流】檔案輸入與輸出(Scanner)& Scanner和io流讀寫有何區別?(待填坑)

對檔案進行讀取,僅需要用File物件構造一個Scanner物件Scanner in= new Scanner(Paths.get("myfile.tet"),"UTF-8");如果檔名中含反斜槓符號,需要在每個反斜槓之前加一個額外的反斜槓如:“c:\\mydirectory\

STM32學習之路-外部中斷(1)

這裡要記錄的有點太多了,有點頭昏腦脹....先來看看吧 所有的GPIO口都有外部中斷的能力,為了使用外部中斷線,埠必須設定成輸入模式. 輸入模式有三種:上拉、下拉、浮空 請看圖: 上拉輸入模式:區別在於沒有輸入訊號的時候預設輸入高電平 下拉輸入模式:區別在於沒有輸入訊號

STM32學習之:外部中斷

一、STM32中斷分組:  STM32 的每一個GPIO都能配置成一個外部中斷觸發源,這點也是 STM32 的強大之處。STM32 通過根據引腳的序號不同將眾多中斷觸發源分成不同的組,比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0為第一組,那麼依此類推,我們能得出一共有16 組,STM32 規定

微控制器入門學習十一 STM32微控制器學習八 外部中斷

1、概述 STM32的每個IO都可以作為外部中斷輸入。 STM32的中斷控制器支援19個外部中斷/事件請求: 線0~15:對應外部IO口的輸入中斷。 線16:連線到PVD輸出。 線17:連線到RTC鬧鐘事件。 線18:連線到USB喚醒事件。 1

STM32 I/O複用功能時鐘配置

RCC_APB2Periph_AFIO--複用IO時鐘的使用 為了優化64腳或100 腳封裝的外設數目,可以把一些複用功能重新對映到其他引腳上。設定複用 重對映和除錯I/O 配置暫存器(AFIO_MAPR) 實現引腳的重新對映。這時,複用功能不再對映到它 們的原始

Java I/O (1) - 輸入/輸出流

puts 概念 網絡連接 iter 輸入 stream put 基礎 個人 先說概念: Java API中,可以從其中讀入一個字節序列的對象叫做輸入流,可以向其中寫入一個字節序列的對象叫做輸出流。這些字節序列的來源地 和 目的地 可以文件、網絡連接甚至內存塊。抽象類Inp

Unix I/O--輸入/輸出(I/O) : 是指主存和外部裝置(如磁碟,終端,網路)之間拷貝資料過程

輸入/輸出(I/O) : 是指主存和外部裝置(如磁碟,終端,網路)之間拷貝資料過程   https://www.bbsmax.com/A/o75N88ZxzW/   10.1 Unix I/O 一個Unix 檔案就是一個m個位元組的序列: 所有

stm32 IO口作為中斷輸入

1.初始化IO口為輸入,設定IO口狀態 2.開啟IO口複用時鐘,設定IO口與中斷線的對映關係 3.開啟與該IO口相對的線上中斷事件,設定觸發條件 4.配置中斷分組(NVIC),並使能中斷 5.編寫中斷服務函式

關於STM32的幾種輸入模式以及外部中斷的配置

最近做畢業設計,需要用按鍵來觸發外部中斷。實驗的時候是正常的,但是換了個核心板以及用上自己做的PCB電路板後,出現了一些問題。問題如下: 要求:將連線按鍵的IO口配置為上拉輸入,按鍵一端接IO口,一端接地,即當按鍵按下後,該IO口會產生一個下降沿,觸發下降沿中斷。 問題:將

I/O(輸入/輸出)

while 類定義 leo post 字節 lose void 簡單的 ring ---恢復內容開始--- 在變量、數組和對象中儲存的數據是暫時存在的,程序結束後它們就會丟失。為了能夠永久地保存創建的數據,需要將其保存在磁盤文件中,這樣就可以在其他程序中使用它們。Jav

I/O輸入輸出

fileinput 文件 實現 輸入 create 數據 ring NPU file 流概述   一組有序的數據序列,就好比流淌的小溪,只是小溪流淌的是水,而這個流的是數據,是流入還是流出是相對內存而言的,內存可以認為是數據源的聚集地,而文件從外部流向數據源頭即輸入流,

操作系統——第五章 輸入輸出(I/O)管理

image 就是 輸出 nbsp 輸入輸出 輸入 dct alt 技術 這就是SDT表和DCT表 操作系統——第五章 輸入輸出(I/O)管理

STM32第二章I/O端口應用

端口 下拉 之前 alt 位置 .com 喚醒 連接 ima STM32F10xxx系列中,有7個I/O端口,每個端口有兩個32位配置寄存器(GPIOx_CRL,GPIOx_CRH),兩個32位數據寄存器(GPIOx_IDR和GPIOx_ODR),一個32位置位/復位寄存器

STM32-(SysTick定時器,EXTI外部中斷/事件控制器)

Systick系統定時器 介紹:systick定時器上屬於CM3核心中的一個外設,內嵌在NVIC中。系統定時器是一個24位向下計數的計數器,計數器每一次計數的時間是1/SYSTICK,一般我們設定SYSTICK為72M。當過載數值暫存器的值遞減到0時,系統定時器產生一次中斷,以此迴圈。

STM32第二章I/O埠應用

STM32F10xxx系列中,有7個I/O埠,每個埠有兩個32位配置暫存器(GPIOx_CRL,GPIOx_CRH),兩個32位資料暫存器(GPIOx_IDR和GPIOx_ODR),一個32位置位/復位暫存器(GPIOxBSRR),一個16位復位暫存器(GPIOx_BRR)和一個32位鎖存器(GPIOx_LC

I/O輸入系統

I/O輸入系統     計算機有兩個主要任務:I/O操作與計算處理。在許多情況下,主要任務是I/O操作。而計算處理只是附帶的。     作業系統在計算機I/O方面的作用是管理和控制I/O操作和I/O裝置。 概述  

java基礎類庫學習(六.2)輸入輸出 I/O

前言 java的IO通過java.io包下的類和介面來支援,包括輸入輸出兩種流,每種流又分為位元組流和字元流, 輸入輸出流:位元組流和字元流 位元組流:以位元組為單位處理輸入輸出 字元流:以字元來處理輸入輸出 java7對原有io進行升級,提供了一系列全新的API放在NIO中