MC9SDG128B的中斷編程主要有兩種方式:
第一種是使用符號“TRAP_PROC”,TRAP_PROC 提示編譯器下面的函數是插斷服務常式。編譯器會用一個特殊的中斷返回指令來結束這個函數(對大多數處理器來說,一般是RTI指令).
第二種是使用“interrupt”關鍵字,“interrupt”關鍵字是一個非標準ANSI-C的關鍵字,因此,它不能被所有ANSI-C編譯器廠商所支援。同樣,對不同的編譯器,“interrupt”關鍵字的用法可能會改變。“interrupt”關鍵字同樣會提示編譯器下面的函數是一個插斷服務常式。
一旦中斷服務函數寫好了,你必須把插斷服務常式和中斷向量表聯絡起來,這通過初始化中斷向量表來實現,你可以通過下面兩種方法來初始化中斷向量表:
第一種是在PRM檔案中,使用“VECTOR ADDRESS”或“VECTOR”命令。連接器提供兩個命令來初始化中斷向量表:VECTOR ADDRESS 或 VECTOR,你使用VECTOR ADDRESS 命令插斷服務常式的地址寫到中斷向量表裡。
第二種是使用“interrupt”關鍵字,在你寫插斷服務常式的時候,你可以在ANSI-C源檔案裡直接把插斷服務常式和特殊的中斷號聯絡起來.
下面是我寫的MC9SDG128B的16位自由定時器溢出中斷處理常式,已調試通過:
#include /* common defines and macros */
#include /* 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 /* common defines and macros */
#include /* 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”包圍起來。
小記:
IRQ 為 Interrupt ReQuest的縮寫,中文可譯為插斷要求。
由於在電腦運行中,CPU是持續處於忙碌狀態,而當硬體介面裝置開始或結束收發資訊,需要CPU處理資訊運算時,便會透過IRQ對CPU送出插斷要求訊號,讓CPU儲存進行中的工作,然後暫停手邊的工作,先行處理周邊硬體提出的需求,這便是插斷要求的作用。