STM32中斷很強大,STM32中斷可以嵌套,任何外設都可以產生中斷,其中中斷和異常是等價的.
中斷執行流程: 主程序執行過程可以產生中斷去執行中斷的內容(保護現場),然后在返回繼續執行中斷.
中斷分類:(可以在參考手冊查看)
- 系統異常:內核水平 10個
- 外部中斷:外設水平 60個
有關具體的系統異常和外部中斷可在標准庫文件 stm32f10x.h 這個頭文件查詢到,在 IRQn_Type 這個結構體里面包含了 F103 系列全部的異常聲明.(部分截圖)
NVIC簡介
NVIC: 嵌套向量中斷控制器,屬於內核外設,管理着包括內核和片上所有外設的中斷相關的功能。各個芯片廠商在設計芯片的時候會對 Cortex-M3 內核里面的 NVIC 進行裁剪,把不需要的部分去掉,所以說 STM32 的 NVIC 是 Cortex-M3 的 NVIC 的一個子集。
兩個重要的庫文件:core_cm3.h(內核外設)和misc.h ,NVIC的庫函數定義全在misc.h
(外設在STM32F10X.h)
在配置中斷的時候我們一般只用 ISER、 ICER 和 IP 這三個寄存器, ISER 用來使能中斷, ICER 用來失能中斷, IP 用來設置中斷優先級。優先級分為主優先級和子優先級,當主和子優先級相同時,比較中斷向量表中的位置號.(參考手冊)
NVIC 庫函數 |
描述 |
void NVIC_EnableIRQ(IRQn_Type IRQn) |
使能中斷 |
void NVIC_DisableIRQ(IRQn_Type IRQn) |
失能中斷 |
void NVIC_SetPendingIRQ(IRQn_Type IRQn) |
設置中斷懸起位 |
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) |
設置中斷優先級 |
void NVIC_ClearPendingIRQ(IRQn_Type IRQn) |
清除中斷懸起位 |
uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) |
獲取懸起中斷編號 |
uint32_t NVIC_GetPriority(IRQn_Type IRQn) |
獲取中斷優先級 |
void NVIC_SystemReset(void) |
系統復位 |
優先級及優先級分組的定義
在 NVIC 有一個專門的寄存器:中斷優先級寄存器 NVIC_IPRx, 用來配置外部中斷的優先級, IPR 寬度為 8bit,原則上每個外部中斷可配置的優先級為 0~255,數值越小,優先級越高。但是絕大多數 CM3 芯片都會精簡設計,以致實際上支持的優先級數減少,在F103 中,只使用了高 4bit,如下所示:
1. 優先級設定:NVIC->IPRx
用於表達優先級的這 4bit,又被分組成搶占優先級和子優先級。如果有多個中斷同時響應,搶占優先級高的就會搶占 搶占優先級低的優先得到執行,如果搶占優先級相同,就比較子優先級。如果搶占優先級和子優先級都相同的話,就比較他們的硬件中斷編號,編號越小,優先級越高。
2.優先級的分組由內核外設 SCB 的應用程序中斷及復位控制寄存器 AIRCR 的PRIGROUP[10:8]位決定, F103 分為了 5 組,設置優先級分組可調用庫函數 NVIC_PriorityGroupConfig()實現,具體如下:主優先級=搶占優先級,在misc.h中可以找到此表
中斷編程的順序
1-使能中斷請求
這個具體由每個外設的相關中斷使能位控制。比如串口有發送完成中斷,接收完成中斷,這兩個中斷都由串口控制寄存器的相關中斷使能位控制。
2-配置NVIC寄存器
初始化NVIC_InitTypeDef; 並且調用 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);寫入寄存器
1-NVIC_IRQChannel:中斷源
2-NVIC_IRQChannelPreemptionPriority:搶占優先級
3-NVIC_IRQChannelSubPriority:子優先級
4-NVIC_IRQChannelCmd:使能或者失能
1) NVIC_IROChannel:用來設置中斷源,不同的中斷中斷源不一樣,且不可寫錯,即使寫錯了程序也不會報 錯,只會導致不響應中斷。具體的成員配置可參考 stm32f10x.h 頭文件里面的 IRQn_Type 結構體定義,這個結構體包含了所有的中斷源。
2) NVIC_IRQChannelPreemptionPriority:搶占優先級,具體的值要根據優先級分組來確定,具體參考表格 17-5 優先級分組真值表 。
3) NVIC_IRQChannelSubPriority:子優先級,具體的值要根據優先級分組來確定,具體參考表格 17-5 優先級分組真值表 。
4) NVIC_IRQChannelCmd:中斷使能(ENABLE)或者失能(DISABLE)。操作的是 NVIC_ISER 和 NVIC_ICER 這兩個寄存器。
3-編寫中斷服務函數
在啟動文件 startup_stm32f10x_hd.s 中我們預先為每個中斷都寫了一個中斷服務函數,只是這些中斷函數都是為空,為的只是初始化中斷向量表。實際的中斷服務函數都需要我們重新編寫,為了方便管理我們把中斷服務函數統一寫在 stm32f10x_it.c 這個庫文件中。關於中斷服務函數的函數名必須跟啟動文件里面預先設置的一樣,如果寫錯,系統就在中斷向量表中找不到中斷服務函數的入口,直接跳轉到啟動文件里面預先寫好的空函數,並且在里面無限循環,實現不了中斷。