原文地址:http://lixin9925.blog.163.com/blog/static/349447422009016262585/
interrupt中断的关键字,n是中断号提供中断程序的入口地址。
0-INT0 1-T0 2-INT1 3-T1 4-串行中断 5-T2
直接访问寄存器和端口
定义
sfr P0 0x80
sfr P1 0x81
sfr ADCON; 0xDE
sbit EA 0x9F
操作
ADCON = 0x08 ;
P1 = 0xFF ;
io_status = P0 ;
EA = 1 ;
在使用了interrupt 1 关键字之后,会自动生成中断向量
在 ISR中不能 与其他 "后台循环代码"(the background loop code) 共享 局部变量
因为 连接器 会复用 在RAM中这些变量的 位置 ,所以 它们会有不同的意义,这取决于当前使用的不同的函数
复用变量对 RAM有限的51来将 很重要。所以,这些函数希望按照一定的顺序执行 而不被中断。
timer0_int() interrupt 1 using 2
{
unsigned char temp1 ;
unsigned char temp2 ;
executable C statements ;
}
"interrupt"声明 表示 向量生成在 (8*n+3),这里,n就是interrupt参数后的那个数字
这里,在08H的代码区域 生成 LJMP timer0_int 这样一条指令
"using" tells the compiler to switch register banks on entry to an interrupt routine. This "context" switch is the fastest way of providing a fresh registerbank for an interrupt routine's local data and is to be preferred to stacking registers for very time-critical routines. Note that interrupts of the same priority can share a register bank, since there is no risk that they will interrupt each other.
'using' 告诉编译器 在进入中断处理器 去切换 寄存器的bank。这个"contet"切换是
为中断处理程序的局部变量提供一个新鲜的寄存器bank 最快的方式。 对时序要求严格的程序,是首选的 stack寄存器(保存寄存器到stack)方式。
注意:同样优先级别的中断 可以共享 寄存器bank,因为 他们每次将中断 没有危险
If a USING 1 is added to the timer1 interrupt function prototype, the pushing of registers is replaced by a simple MOV to PSW to switch registerbanks. Unfortunately, while the interrupt entry is speeded up, the direct register addressing used on entry to sys_interp fails. This is because C51 has not yet been told that the registerbank has been changed. If no working registers are used and no other function is called, the optimizer eliminiates teh code to switch register banks.
如果在timer1 的中断函数原型中使用USING 1, 寄存器的pushing将被 MOV to PSW 切换寄存器bank 所替换。
不幸的是,当一个中断入口被加速时。用在入口的 直接寄存器寻址 将失败。
这是因为 C51没有告诉 寄存器bank已经改变。如果 不工作的寄存器将被使用,如果没有其他函数被调用,优化器.....
Logically, with an interrupt routine, parameters cannot be passed to it or returned. When the interrupt occurs, compiler-inserted code is run which pushes the accumulator, B,DPTR and the PSW (program status word) onto the stack. Finally, on exiting the interrupt routine, the items previously stored on the stack are restored and the closing "}" causes a RETI to be used rather than a normal RET.
逻辑上,一个中断服务程序,不能传递参数进去,也不可返回值。
当中断发生时,编译器插入的代码 被运行,它 将 累加器 ,B,DPTR和PSW(程序状态字)入栈。最后,在退出中断程序时,预先存储在 栈中 被恢复。最后的"}"结束符号
将 插入 RETI到 中断程序的最后,
为了用 Keil‘C’语言创建一个中断服务程序(ISR),利用 interrupt 关键词和正确的中断号声明一个 static void 函数。Keil‘C’编译器自动生成中断向量,以及中断程序的进口、出口代码。Interrupt 函数属性标志着该函数为 ISR。可用 using 属性指定ISR使用哪一个寄存器区,这是可选的。有效的寄存器区范围为1到3。
中断源的矢量位置
中断源 Keil中断编号 矢量地址
最高优先级 6 0x0033
外部中断0 0 0x0003
定时器0溢出 1 0x000B
外部中断1 2 0x0013
定时器1溢出 3 0x001B
串口 4 0x0023
定时器2溢出 5