SOGO論壇
  登入   註冊   找回密碼
查看: 5128|回覆: 0
列印 上一主題 下一主題

[程式設計] Microchip PIC32入門(3)-中斷(interrupt)簡介 [複製連結]

Rank: 5Rank: 5

數位軟體勳章

狀態︰ 離線
跳轉到指定樓層
1
發表於 2011-12-1 02:52:01 |只看該作者 |倒序瀏覽 | x 1
本帖最後由 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 的中斷函數
  1. void __ISR(_CORE_TIMER_VECTOR, ipl5) CT_Int _Routine (void)
  2. {
  3. :
  4. :
  5. mCTClearIntFlag( );   // 清除 Core-Timer 中斷旗號

  6. }
複製代碼
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 列舉名稱

範例
  1. #include <p32xxxx.h>
  2. #include <plib.h>


  3. #define SYS_FREQ                         (80000000L)
  4. #define PB_DIV                                    8
  5. #define PRESCALE                                   256
  6. #define TOGGLES_PER_SEC                1
  7. #define T1_TICK                       (SYS_FREQ/PB_DIV/PRESCALE/TOGGLES_PER_SEC)

  8. void Init_Timer1(void) ;
  9. int main()
  10. {
  11.           SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
  12.           mPORTASetPinsDigitalOut(BIT_0);
  13.           Init_Timer1();
  14.           INTEnableSystemMultiVectoredInt();
  15. }
  16. void Init_Timer1(void)
  17. {
  18.      ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_4) ;       // 將Timer1的中斷優先權設定為 4
  19.      // 將Timer1中斷致能打開      

  20.      OpenTimer1(T1_ON | T1_SOURCE_INT | T1_PS_1_256, T1_TICK);  
  21.    

  22. }
  23. //***************************************************************//
  24. /*                   TIMER1中斷副程式                                      */
  25. //***************************************************************//
  26. void __ISR(_TIMER_1_VECTOR, ipl4) Timer1Handler(void)
  27. {
  28.         mT1ClearIntFlag() ;       // 清除 Timer1 interrupt Flag ..  // C32 所提供的巨集

  29.            mPORTAToggle(BIT_0);
  30. }
複製代碼
喜歡嗎?分享這篇文章給親朋好友︰
               感謝作者     

失敗只有一種:那就是半途而廢
請注意︰利用多帳號發表自問自答的業配文置入性行銷廣告者,將直接禁訪或刪除帳號及全部文章!
您需要登錄後才可以回覆 登入 | 註冊


本論壇為非營利自由討論平台,所有個人言論不代表本站立場。文章內容如有涉及侵權,請通知管理人員,將立即刪除相關文章資料。侵權申訴或移除要求:abuse@oursogo.com

GMT+8, 2024-5-1 23:58

© 2004-2024 SOGO論壇 OURSOGO.COM
回頂部