一、什么是中斷?
打斷當前的操作,執行中斷需要做的事情。
中斷的作用:中斷機制不僅賦予了系統處理意外情況的能力,就可以“同時”完成多個任務,提高了并發“處理”能力。
和線程的區別:線程是同時執行多個任務,中斷是停下來去執行其他的(注意優先級),執行完了再回來執行,
定時器才相當于線程,定一個時間,每到這個時間執行一次
二、中斷概述
STM32F4并沒有使用CM4內核的全部東西,而是只用了它的一部分。
STM32F40xx/STM32F41xx總共有92個中斷
STM32F42xx/STM32F43xx則總共有96個中斷
STM32F40xx/STM32F41xx的92個中斷里面,包括10個內核中斷和82個可屏蔽中斷,具有16級可編程的中斷優先級,而我們常用的就是這82個可屏蔽中斷。
三、外部中斷/事件線映射多達140個GPIO。
根據圖文,發現我們的中斷線總共有23根,其中16根是連接PA~PI引腳。
STM32F4供IO使用的中斷線只有16個:EXTI線0~15:對應外部IO口的輸入中斷。
剩下的七根是分別連接專用設備的:
另外七根 EXTI 線連接方式如下:
● EXTI 線 16 連接到 PVD 輸出
● EXTI 線 17 連接到 RTC 鬧鐘事件
● EXTI 線 18 連接到 USB OTG FS 喚醒事件
● EXTI 線 19 連接到以太網喚醒事件
● EXTI 線 20 連接到 USB OTG HS(在 FS 中配置)喚醒事件
● EXTI 線 21 連接到 RTC 入侵和時間戳事件
● EXTI 線 22 連接到 RTC 喚醒事件
四、中斷服務函數分配
IO口外部中斷在中斷向量表中只分配了7個中斷向量,也就是只能使用7個中斷服務函數
從表中看出,外部中斷線5~9分配一個中斷向量,共用一個服務函數 外部中斷線10~15分配一個中斷向量,共用一個中斷服務函數
中斷服務函數列表如下:
四、設置中斷優先級的分組
1、中斷優先級有兩種:
搶占(占先式)優先級 --》 第一序列 響應(副)優先級 --》 第二序列
2、搶占優先級 &響應優先級區別:
高優先級的搶占優先級是可以打斷正在進行的低搶占優先級中斷的。
搶占優先級相同的中斷,高響應優先級不可以打斷低響應優先級的中斷。
搶占優先級相同的中斷,當兩個中斷同時發生的情況下,哪個響應優先級高,哪個先執行。
如果兩個中斷的搶占優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執行;
3、中斷優先級設置步驟
①系統運行后先設置中斷優先級分組。調用函數:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);整個系統執行中只設置一次中斷分組。
②針對每個中斷,設置對應的搶占優先級和響應優先級:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
③如果需要掛起/解掛,查看中斷當前激活狀態,分別調用相關函數即可
五、外部中斷的一般配置步驟
①使能SYSCFG時鐘:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
②初始化IO口為輸入。
GPIO_Init();
③設置IO口與中斷線的映射關系。
void SYSCFG_EXTILineConfig();//通過設置SYSCFG寄存器,建立IO口和中斷線的連接
④初始化線上中斷,設置觸發條件等。
EXTI_Init();
⑤配置中斷分組(NVIC),并使能中斷。
NVIC_Init();
⑥編寫中斷服務函數。
EXTIx_IRQHandler();
且清除中斷標志位
EXTI_ClearITPendingBit();//清除中斷標志位是為了表示中斷已經開始執行,可以接收下一個中斷。
----------------------------------------------------------------------------------------------------------------------------------------------------------
代碼如下:
/**********************************************
*
*功能:四個按鍵中斷
*
**********************************************/
#include "exti.h"
//外部中斷初始化程序
//初始化PE2~4,PA0為中斷輸入.
void EXTI4_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //KEY0 KEY1 KEY2對應引腳
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);//PE4 連接到中斷線4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中斷事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中斷線使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中斷4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//搶占優先級1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子優先級2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);//配置
}
void EXTI3_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //KEY0 KEY1 KEY2對應引腳
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);//PE4 連接到中斷線4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中斷事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中斷線使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//外部中斷4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//搶占優先級1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子優先級2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);//配置
}
void EXTI2_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //KEY0 KEY1 KEY2對應引腳
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);//PE4 連接到中斷線4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中斷事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中斷線使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//外部中斷4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//搶占優先級1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子優先級2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);//配置
}
void EXTI0_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA,GPIOE時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //KEY0 KEY1 KEY2對應引腳
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PE4 連接到中斷線4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中斷事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中斷線使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中斷4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//搶占優先級1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子優先級2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);//配置
}
//外部中斷4服務程序
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4) != RESET)//判斷是否置位
{}
EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中斷標志位
}
//外部中斷3服務程序
void EXTI3_IRQHandler(void)
{
delay_ms(15);
EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中斷標志位
}
//外部中斷2服務程序
void EXTI2_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中斷標志位
}
//外部中斷0服務程序
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中斷標志位
}
上一篇:Cortex-M0 LPC11C14中斷控制器
下一篇:LPC824 一種IAP實現方法
推薦閱讀
史海拾趣
在激烈的市場競爭中,APD公司始終堅持品質至上的原則。公司建立了嚴格的質量管理體系,從原材料采購到產品生產、檢測等各個環節都嚴格把關。憑借卓越的產品品質和良好的售后服務,APD贏得了眾多客戶的信賴和支持。
在發展過程中,Carling Technologies還通過收購其他企業來增強自身實力。例如,公司收購了Maretron品牌,將其納入旗下,并充分利用其在船舶監控和控制解決方案方面的優勢,為前沿產品和解決方案的持續開發提供支持。這種收購與品牌整合的策略不僅豐富了公司的產品線,也擴大了其在特定市場的影響力。
Digitron公司始終將創新作為企業發展的核心驅動力。公司投入大量資金用于研發新技術和新產品,不斷提升產品的性能和功能。XXXX年,Digitron公司成功研發出一款具有無線傳輸功能的數據記錄器,用戶可以通過手機或電腦實時查看和監控數據。這一創新產品受到了市場的熱烈歡迎,為Digitron公司帶來了顯著的增長。
隨著公司的發展,Astron Wireless Technologies Inc開始尋求與其他行業的領軍企業建立戰略合作關系。通過與一家知名通信設備制造商的合作,公司成功將其無線通信技術集成到了對方的產品中,從而進一步擴大了市場份額。這一合作不僅提升了公司的知名度,還為公司帶來了穩定的收入來源。
隨著Avic公司在航空電子技術領域的不斷發展和創新,其產品在國內外市場上的競爭力日益增強。公司成功拓展了國內外市場,市場份額穩步增長。這不僅體現了公司在航空電子領域的實力,也為中國航空工業的整體發展做出了積極貢獻。
這五個故事雖然不能完全涵蓋Avic公司在電子行業發展的所有細節,但希望能通過概括性的描述,為您展現該公司在這一領域的重要發展歷程和取得的成就。需要注意的是,這些故事是基于公開資料和已知事實進行描述的,旨在客觀呈現事實,而非進行主觀評價。
Desoutter公司一直注重技術創新和產品升級。公司擁有一支專業的研發團隊,不斷投入資源進行新產品的研發和現有產品的改進。例如,公司成功開發了一系列新型氣動螺絲起子、氣動鉆和氣動沖擊扳手等,這些產品不僅提高了工作效率,還降低了勞動強度。同時,Desoutter公司還利用先進的電腦輔助技術,實現了產品設計和生產的自動化,進一步提升了產品的質量和性能。
我在讀寫GPIO的時候遇到了一個很奇怪的問題。 以下程序中,GPECON的內容可以正確讀寫,GPEDAT卻總是很奇怪的數值。 百思不得其解,大家能否幫我看一下? 代碼如下: v_pIOPRegs = (volatile IOPreg*)VirtualAlloc(0, sizeof(IOPreg), MEM_RESER ...… 查看全部問答∨ |
|
在IAR Embedded Workbench 把程序編好了,設置好編譯環境后調試無錯誤,debugger進入CSPY,我知道的僅僅到這一步,接著怎么做啊?假定我的程序達到我的要求,寫入時通過PET連上了單片機,此時單片機需要供電么?怎么寫入? 哪位高手幫忙解答一下, ...… 查看全部問答∨ |
我使用的42X0系列的單片機,使用兩個A/D通道,通道2和通道5,請問在中斷程序中怎么來判斷是那個通道產生的中斷啊?我只是在sd16cctl0寄存器中看到有sd16ifg位,但不知道怎么用來判斷中斷源?請大俠們指教。急!!!… 查看全部問答∨ |
LM3S9B96學習(二)-----blinky 打開blinky文件夾下的工程,整個工程包含兩個最要的代碼文件 : blinky.c 和 startup_rvmdk.S , startup_rvmdk.S 是系統的啟動文件 ,里面使用匯編語言編寫,因為這個例程不需要修改堆棧和使用到中斷,所以在這 ...… 查看全部問答∨ |
設計資源 培訓 開發板 精華推薦
- STM32一文通(6) 外部中斷
- ESP32玩轉MicroPython(一) 燒入固件, 初識
- ESP32玩轉MicroPython(二) 連接WIFI網絡 webperl文件傳輸
- ESP32玩轉MicroPython(三) 延時、計時 和GPIO操作
- 玩轉 ESP32 + Arduino (一) 開發環境搭建
- 玩轉 ESP32 + Arduino (四) 電容按鍵 霍爾傳感器 外部中斷 延時 脈沖檢測
- 玩轉 ESP32 + Arduino (五) platformIO引入類庫 自開發庫 串口打印字符串
- 玩轉 ESP32 + Arduino (六) 硬件定時器, IIC, SPI
- 玩轉 ESP32 + Arduino (八) U8G2驅動OLED