MC9S中斷函數編寫

MC9S的中斷編程主要有兩種方式:
  1.使用符號“TRA_PROC” ,TRAP_PROC 提示編譯器下面的函數是中斷服務例程。編譯器會用一個特殊的中斷返回指令來結束這個函數(對大多數處理器來說,一般是RTI指令).
  2.使用“interrupt”關鍵字,“interrupt”關鍵字是一個非標準ANSI-C的關鍵字,因此,它不能被所有ANSI-C編譯器廠商所支持。同樣,對不同的編譯器,“interrupt”關鍵字的用法可能會改變。“interrupt”關鍵字同樣會提示編譯器下面的函數是一箇中斷服務例程。
  一旦中斷服務函數寫好了,必須把中斷服務例程和中斷向量表聯繫起來,這通過初始化中斷向量表來實現,可以通過下面兩種方法來初始化中斷向量表:
  1.在PRM文件中,使用“VECTOR ADDRESS”或“VECTOR”命令。連接器提供兩個命令來初始化中斷向量表:VECTOR ADDRESS 或 VECTOR,你使用VECTOR ADDRESS 命令中斷服務例程的地址寫到中斷向量表裏。
  2.使用“interrupt”關鍵字,在寫中斷服務例程的時候,可以在ANSI-C源文件裏直接把中斷服務例程和特殊的中斷號聯繫起來。


下面是MC9SDG128B的16位自由定時器溢出中斷處理程序,已調試通過:
#include <hidef.h> /* common defines and macros */
#include <mc9s12dg128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"

int intcount = 0; 
void timer_init(void) 
{ 
    TSCR2_PR0 = 1; //prescale factor is 128 
    TSCR2_PR1 = 1; 
    TSCR2_PR2 = 1; 
    TSCR2_TOI = 1; //overflow enable 
    TFLG2_TOF = 1; 
    TSCR1_TEN = 1; //timer enable
}

#pragma CODE_SEG NON_BANKED
interrupt 16 void timer_interrupt_handle(void)
{ 
    intcount++; 
    TFLG2_TOF = 1; //clear interrupt flag
}
#pragma CODE_SEG DEFAULT 

void main(void)
{ 
    EnableInterrupts; 
    timer_init(); 
    for(;;) {}
}

  以下是採用TRAP_PROC符號編寫的中斷服務程序:

#include <hidef.h> /* common defines and macros */
#include <mc9s12dg128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
int intcount = 0;
void timer_init(void)
{ 
    TSCR2_PR0 = 1; //prescale factor is 128 
    TSCR2_PR1 = 1; 
    TSCR2_PR2 = 1; 
    TSCR2_TOI = 1; //overflow enable 
    TFLG2_TOF = 1; 
    TSCR1_TEN = 1; //timer enable
}

#pragma CODE_SEG NON_BANKED
#pragma TRAP_PROC
void timer_interrupt_handle(void)
{
    intcount++; 
    TFLG2_TOF = 1;
};
#pragma CODE_SEG DEFAULT

void main(void)
{ 
    EnableInterrupts; 
    timer_init(); 
    for(;;) {}
}

  中斷服務程序編寫完後你需要在.prm文件裏添加如下一句:

VECTOR 16 timer_interrupt_handle

  這樣中斷服務程序才和相應的中斷號聯繫起來。

  中斷服務例程必須被定位於non-banked 區域,通過使用“#pragma CODE_SEG NON_BANKED”可以把中斷例程定位於non-banked 區域。同時你必須確保“sectionNON_BANKED”不能出現在.prm文件中。在中斷服務例程的末尾你需要添加“#pragma CODE_SEG DEFAULT”,否則的話,後面的函數也會被定位在“non-banked”區域。
  所以說我們的中斷服務例程必須被“#pragma CODE_SEG NON_BANKED”和“#pragma CODE_SEG DEFAULT”包圍起來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章