中斷與事件
事件建立在OS的基礎上的。
在intel微處理手冊中,把同步中斷和異步中斷分別稱為異常和中斷。
中斷是由間隔定時器和I/O設備產生的。
異常是由程序的錯誤產生的。
同步:在計算機中,同步指一個進程在執行某個請求的時候,若該請求需要一段時間才能返回,那么這個進程將會一直等待下去直到返回信息才能繼續執行下去。
異步:異步是指進程需要一直等待下去,而是繼續執行下面的操作,不管其他進程的狀態,當有消息返回時系統會通知進程處理,這樣可以提高效率。
在中斷異常向量表中:復位(reset)的優先級時最高的:-3然后是NMI(Non Maskable Interrupt)不可屏蔽中斷。(在LINUX中為異常信號)。優先級位:-2;
因此可以這樣認為:異常時優先級很高的中斷。高到必須立即執行。
外部中斷/事件控制器(EXTI)
對於一般的STM32,互聯型有20個產生事件/中斷請求的檢測邊沿檢測器構成,其他的有19個。
這些控制器的映射關系:
每個I/O口有16個引腳分別對應EXTI(0~15).
EXTI線16連接到PVD輸出
EXTI線17連接到RTC鬧鍾事件
EXTI線18連接到USB喚醒事件
EXTI線19連接到以太網喚醒事件(只適用於互聯型產品)
中斷與事件的區別
每條中斷/事件邊沿檢測器檢測到信號是並不區別信號是中斷信號還是事件信號,只有到信號到中斷屏蔽寄存器(同時信號到達事件屏蔽寄存器)如果是一個中斷,將信號送到NVIC中斷控制器,否則將是一個事件信號,送到脈沖發生器。
中斷/事件的產生
要產生中斷,必須先配置好並使能中斷線。根據需要的邊沿檢測設置2個觸發寄存器,同時在中斷屏蔽寄存器的相應位寫’1’允許中斷請求。當外部中斷線上發生了期待的邊沿時,將產生一個中斷請求,對應的掛起位也隨之被置’1’。在掛起寄存器的對應位寫’1’,將清除該中斷請求。如果需要產生事件,必須先配置好並使能事件線。根據需要的邊沿檢測通過設置2個觸發寄存器,同時在事件屏蔽寄存器的相應位寫’1’允許事件請求。當事件線上發生了需要的邊沿時,將產生一個事件請求脈沖,對應的掛起位不被置’1’。通過在軟件中斷/事件寄存器寫’1’,也可以通過軟件產生中斷/事件請求。
硬件中斷配置
通過如下過程來配置20個線路做為中斷源:
配置20個中斷線的屏蔽位(EXTI_IMR)
配置所選中斷線的觸發選擇位(EXTI_RTSR和EXTI_FTSR);
配置對應到外部中斷控制器(EXTI)的NVIC中斷通道的使能和屏蔽位,使得20個中斷線中的請求可以被正確地響應。
硬件事件配置
配置20個事件線的屏蔽位(EXTI_EMR)
配置事件線的觸發選擇位(EXTI_RTSR和EXTI_FTSR)
軟件的中斷/事件配置
20個線路可以被配置成軟件中斷/事件線。產生軟件中斷的過程:
配置20個中斷/事件線屏蔽位(EXTI_IMR, EXTI_EMR)
設置軟件中斷寄存器的請求位(EXTI_SWIER)
STM32的外部中斷初始化
初始化IO口為輸入時:可以設置為上拉/下拉輸入,也可以設置為浮空輸入,但浮空的時候外部一定要帶上拉,或者下拉電阻。否則可能導致中斷不停的觸發。在干擾較大的地方,就算使用了上拉/下拉,也建議使用外部上拉/下拉電阻,這樣可以一定程度防止外部干擾帶來的影響 。
需要開啟IO口復用時鍾,設置IO口與中斷的映射關系:
STM32 的 IO 口與中斷線的對應關系需要配置外部中斷配置寄存器 EXTICR,需要先開啟復用時鍾,然后配置 IO 口與中斷線的對應關系。才能把外部中斷與中斷線連接起來
配置中斷分組(NVIC),使能中斷。
編寫中斷服務函數。
編寫中斷的代碼解析;
中斷服務函數是在相應中斷到的時候對中斷到來時做出的響應,這個函數可以編寫任意你需要的函數,但對於一個中斷函數在函數結束時必須清除中斷標志,不然中斷將一直存在。需要注意的是:服務函數命名的格式為Name_IRQHandler(void),(Name為你設置的中斷類型。如:TIMx,EXTIx等表示你使用的中斷類型,因為在給定的代碼對相應的進行了定義可以參考(stm32f10x.h));
中斷的初始化函數定義如下:
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
這里有四個參數,下面說明含義
中斷分組函數(NVIC_Group):它是一個給一個中斷優先級的函數,函數如下:
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{ u32 temp,temp1;
temp1=(~NVIC_Group)&0x07;
temp1<<=8;
temp=SCB->AIRCR;
temp&=0X0000F8FF;
temp|=0X05FA0000; //寫入鑰匙
temp|=temp1;
SCB->AIRCR=temp; // 寫入優先級
}
這個函數有一個SCB->AIRCR 可以理解為一個寄存器也看可以理解為一個變量,在這個寄存器中bit[10:8]位標志着一個函數的搶占優先級和響應優先級(搶占優先級>響應優先級,同搶占優先級看響應優先級,數值越小,優先級越高)。
這個表給出了相應設置下的優先級分配。
本函數為一個系統函數不用做修改。
還有兩個參數,分別是搶占優先級(NVIC_PreemptionPriority)和響應優先級(NVIC_SubPriority),對於這連個參數的是設置中斷IP[240]寄存器的(Interrupt Priority Registers),IP 寄存器組由 240 個 8bit 的寄 存器組成,每個可屏蔽中斷占用 8bit,這樣總共可以表示 240 個可屏蔽中斷。8bit用了高4位來表示優先級。如上表給出的結果。
需要注意的是:對於這個函數需要設置中斷屏蔽位,把相應的中斷置1,這里還有一個參數也就NVIC_Channel,這個參數就是一個中斷編號,它的格式Name_IRQn(Name為你設置的中斷類型。如:TIMx,EXTIx等表示你使用的中斷類型)
對於一般的使用來說,我們只要掌握對函數:
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) 的使用就行
各個參數的含義:
//NVIC_PreemptionPriority:搶斷優先級
//NVIC_SubPriority :相應優先級
//NVIC_Channel :中斷編號(中斷服務函數)
//NVIC_Group :中斷分組。