stm32的每個IO口都可以作為外部中斷的入口。stm32f103的中斷控制器支援19個外部中斷/事件請求(question1:外部中斷和時間請求的差別?),這19個外部中斷中0-15對應外部IO口的輸入中斷16連接配接到PVD輸出(question2:什麼是PVD輸出?)17連接配接到RTC鬧鐘事件(question3:這有什麼意義)18連接配接到USB喚醒事件(question4:USB喚醒事件是什麼?)。由上可以看出stm32供IO的中斷線隻有16個但是stm32的IO口遠遠不止16個那麼怎麼一一對應呢?于是 STM32 就這樣設計, GPIO 的管教 GPIOx.0~GPIOx.15(x=A,B,C,D,E, F,G)分别對應中斷線 0~15。
1. 第一步
配置GPIO與中斷線的映射關系是由函數
GPIO_EXTILineConfig()
實作的使用範例是:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
**
2. 第二步
**
将中斷線與IO口映射後,接下來設定中斷線上中斷的初始化參數。這是通過函數
EXTI_Init()
實作的
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
例:
/* Enables external lines 14 interrupt generation on falling
edge */
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line12;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
其中需要設定四個參數
1.中斷線标号 EXTI_Line0~EXTI_Line15
2.中斷模式 中斷
EXTI_Mode_Interrupt
和事件
EXTI_Mode_Event
3.觸發方式 下降沿觸發
EXTI_Trigger_Falling
,上升沿觸發
EXTI_Trigger_Rising
,或者任意電平(上升沿和下降沿) 觸發
EXTI_Trigger_Rising_Falling
4.使能
3. 第三步
在配置完中斷的初始化參數後就是設定NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); //中斷優先級分組初始化
4. 第四步
NVIC配置完成之後配置就是編寫中斷服務函數 注意STM32的IO口外部中斷通道和函數都隻有6個分别為
EXPORT EXTI0_IRQHandler
EXPORT EXTI1_IRQHandler
EXPORT EXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORT EXTI4_IRQHandler
EXPORT EXTI9_5_IRQHandler
EXPORT EXTI15_10_IRQHandler
中斷線 0-4 每個中斷線對應一個中斷函數, 中斷線 5-9 共用中斷函數
EXTI9_5_IRQHandler
,中斷線 10-15 共用中斷函數
EXTI15_10_IRQHandle
r。
在編寫中斷服務函數的時候會經常使用到兩個函數
1.判斷某個中斷線上的中斷是否發生,一般使用在中斷服務函數開頭傳回值為SET 或 RESET
EXTIStatus = EXTI_GetITStatus(EXTI_Line8);
2.清除某個中斷線上的中斷标志位,一般應用在中斷服務函數結束之前, 清除中斷标志
EXTI_ClearITpendingBit(EXTI_Line2);
一般的中斷服務函數格式為:
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判斷某個線上的中斷是否發生
{
中斷邏輯…
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中斷标志位
}
}
固件庫還提供了另外兩個函數用來判斷外部中斷狀态以及清除外部狀态
标志位的函數
EXTI_GetFlagStatus
和
EXTI_ClearFlag
,他們的作用和前面兩個函數的作用類似。隻是在
EXTI_GetITStatus
函數中會先判斷這種中斷是否使能,使能了才去判斷中斷标志位,而
EXTI_GetFlagStatus
直接用來判斷狀态标志位。(question5:關于此的詳解)最後固件庫提供了産生軟體中斷的函數其用法為
EXTI_GenerateSWInterrupt(EXTI_Line6);
(qusetion6:什麼是軟體中斷)
最後進行問題的解答:
question1:外部中斷和時間請求的差別?
question2:什麼是PVD輸出?
question3:17連接配接到RTC鬧鐘事件這有什麼意義
question4:USB喚醒事件是什麼?
question5:關于
EXTI_GetFlagStatus
和
EXTI_GetITStatus
的不同詳解?
qusetion6:什麼是軟體中斷?
ANSWER1:事件機制提供了一個完全有硬體自動完成的觸發到産生結果的通道,不要軟體的參與,降低了CPU的負荷,節省了中斷資源,提高了響應速度(硬體總快于軟體),是利用硬體來提升CPU晶片處理事件能力的一個有效方法詳情點選
ANSWER2:PVD = Programmable Votage Detector 可程式設計電壓監測器它的作用是監視供電電壓,在供電電壓下降到給定的閥值以下時,産生一個中斷,通知軟體做緊急處理儲存重要資訊 類似于看門狗的喚醒中斷
ANSWER3:去喚醒停機模式下的系統詳情點選
ANSWER4:通過USB喚醒核心(具體我也不懂請各位指教)
ANSWER5:
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
{
ITStatus bitstatus = RESET;
uint32_t enablestatus = ;
/* Check the parameters */
assert_param(IS_GET_EXTI_LINE(EXTI_Line));
enablestatus = EXTI->IMR & EXTI_Line;
if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_GET_EXTI_LINE(EXTI_Line));
if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
EXTI_GetFlagStatus
隻是純粹讀取中斷标志位的狀态,但是不一定會響應中斷(EXT_IMR寄存器對該中斷進行屏蔽);而
EXTI_GetITStatus
除了讀取中斷标志位,還檢視EXT_IMR寄存器是否對該中斷進行屏蔽,在中斷挂起沒有屏蔽的情況下就會響應中斷。是以我們一般用的是
EXTI_GetITStatus
ANSWER6:又軟體産生的中斷比如可以由定時器産生 具體的應用還不了解 希望大家指教