- 註冊時間
- 2004-10-30
- 最後登錄
- 2025-1-23
- 主題
- 查看
- 積分
- 265
- 閱讀權限
- 50
- 文章
- 219
- 相冊
- 0
- 日誌
- 0
 
狀態︰
離線
|
本帖最後由 alphi 於 2011-12-1 03:00 編輯
前言
PIC32有非常高效能的中斷機制架構,其中特性如下
1.內建向量中斷控制器(Vectored Interrupt Controller)
1.1.支援單一中斷向量模式(Single Vector mode),此模式(預設)是給RTOS統一管理中斷發生
1.2.也支援多向量中斷模式(Multi Vector mode)
1.2.1.支援高達96個中斷來源(Interrupt Sources)
1.2.2.支援高達64個中斷向量(Interrupt Vectors)
1.3.多優先權(從0~7)以及子優先權(0~4)
搶先式中斷(Preemptive Interrupt)
PIC32中斷機制為搶先式中斷,搶先式中斷優點就是在其中斷發生時.可在接受其比其中斷優先權更高的中斷發生.以下圖為例(優先權:L7>L4>L1>L0)
一開始程式在main執行(L0).當發生L4中斷時.去執行L4中斷函式.在執行L4中斷時,又發生L7中斷.由於優先權L7>L4.則執行L7中斷.在執行L7中斷時.發生L1中斷
由於L7>L1(故不理會此中斷)....
設定週邊中斷
A. 設定周邊中斷基本上有以下步驟
1. INTEnableSystemMultiVectoredInt();
2. 使用 _ _ ISR ( Vector, ipl) 定義中斷函數
3. 設定該週邊的中斷是否要致能及中斷的優先權等級 – 使用巨集 ConfigIntxxxx( ) 或 C32 的基本 函式
4. 設定該週邊的工作模式、功能 – 使用 Openxxxx()
B. 致能及設定周邊中斷優先等級的 MPLAB C32 基本函式
1. INTEnable( )
2. INTSetVectorPriority( )
3. INTSetVectorSubPriority()
定義中斷服務常式(ISR)
使用 void _ _ISR(vector,ipl) ISR_Function_Name (void) 來定義服務特定中斷向量的 “中斷服務程式”
1. vector 為中斷向量的編號 (從 0 開始),相對的定義名稱在 h 檔裡
2. ipl 為該中斷函數的優先權等級從 ipl1 ~ ipl7 (ipl0 為關閉此中斷)
3. ISR 所設定的 ipl 需與該周邊所設定的 Interrupt Priority 相同
4. ISR_Function_Name 為中斷函數名稱
範例:定義 Core Timer 中斷優先權等級為 5 的中斷函數- void __ISR(_CORE_TIMER_VECTOR, ipl5) CT_Int _Routine (void)
- {
- :
- :
- mCTClearIntFlag( ); // 清除 Core-Timer 中斷旗號
- }
複製代碼 ConfigInt[xxxx] 設定周邊中斷及優先權等級
ConfigInt[xxxx] ( INT ON/OFF | INT_Priority| INT_Sub_Priority) 參數的傳遞 (config)基本有三項,使用 OR (|)的運算加入
1 參數一 : 開啟 / 關閉 該週邊的中斷
2. 參數二 : 主要的中斷優先權等級
3. 參數三 : 次要的中斷優先權等級
Open[xxxx] 設定該週邊的工作模式、功能
Open[xxxx] ( config1, config2, … ) 基本上Open 這個函數是設定該週邊的工作模式及功能,相對的也就複雜多了。
建議先研讀相關的周邊後再來設定輸入的參數項
1.周邊詳細資料 : PIC32_Family Reference Manuals
2. 參數的多寡不一定,看該週邊有多少的控制暫存器要設定
清除周邊的中斷旗號
這裡有三種方式可以清除中斷旗號
1. 傳統使用位元結構 : IFS0bits.T1IF = 0;
2. 使用 C32 的巨集 : m[xx]ClearIntFlag( );
3. 使用 C32 的清除函數 : INTClearFlag(xx);
PS. [xx] 為該週邊的 INT_SOURCE 列舉名稱
範例- #include <p32xxxx.h>
- #include <plib.h>
- #define SYS_FREQ (80000000L)
- #define PB_DIV 8
- #define PRESCALE 256
- #define TOGGLES_PER_SEC 1
- #define T1_TICK (SYS_FREQ/PB_DIV/PRESCALE/TOGGLES_PER_SEC)
- void Init_Timer1(void) ;
- int main()
- {
- SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
- mPORTASetPinsDigitalOut(BIT_0);
- Init_Timer1();
- INTEnableSystemMultiVectoredInt();
- }
- void Init_Timer1(void)
- {
- ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_4) ; // 將Timer1的中斷優先權設定為 4
- // 將Timer1中斷致能打開
-
- OpenTimer1(T1_ON | T1_SOURCE_INT | T1_PS_1_256, T1_TICK);
-
- }
- //***************************************************************//
- /* TIMER1中斷副程式 */
- //***************************************************************//
- void __ISR(_TIMER_1_VECTOR, ipl4) Timer1Handler(void)
- {
- mT1ClearIntFlag() ; // 清除 Timer1 interrupt Flag .. // C32 所提供的巨集
- mPORTAToggle(BIT_0);
- }
複製代碼 |
|