现在的位置: 首页 > 综合 > 正文

#pragma CODE_SEG NON_BANKED之中断讲解

2012年04月27日 ⁄ 综合 ⁄ 共 1991字 ⁄ 字号 评论关闭
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储存正在进行的工作,然后暂停手边的工作,先行处理周边硬件提出的需求,这便是中断请求的作用。

抱歉!评论已关闭.