c语⾔关键字interrupt,KeilC51对C语⾔的关键词扩展之⼗四:
interrupt
8051/8052系列单⽚机标准向量表:
中断号描述地址
0外部中断00003h
1定时/计数器0000Bh
2外部中断10013h
3定时计数器1001Bh
4串⼝0023h
5定时计数器2(8052)002Bh
众多⼚商为其51系列单⽚机添加了更多的中断。Keil Cx51编译器⽀持多达32个中断函数(中断号0-31)。下表列出了这32个中断向量⼊⼝
地址:
中断号 ⼊⼝地址
00003h1000Bh20013h3001Bh40023h5002Bh60033h7003Bh80043h9004Bh100053h11005Bh120063h13006Bh140073h 中断号 ⼊⼝地址
160083h17008Bh180093h19009Bh2000A3h2100ABh2200B3h2300BBh2400C3h2500CBh2600D3h2700DBh2800E3h2900
函数声明时使⽤interrupt关键词,该函数将被编译器视为中断服务程序,例如:
unsigned int interruptcnt;
unsigned char cond;
void timer0 (void) interrupt 1 using 2 {
if (++interruptcnt == 4000) {
cond++;
interruptcnt = 0;
}
}
interrupt 关键词后跟⼀个整数,表⽰中断号,取值范围0-31。中断号必须为常数,不允许使⽤操作符表达式。
interrupt关键词影响了该函数的⽬标代码:
1)该中断服务程序被调⽤时,寄存器ACC、B、DPH、DPL、PSW的内容被压⼊堆栈;
2)该函数声明时,如果没有使⽤using关键词指定寄存器组,则在其被调⽤时,它所使⽤的所有⼯作寄存器的内容被压⼊堆栈;
3)被压⼊堆栈的⼯作寄存器、特殊寄存器在该退出中断服务程序前被恢复;
4)该中断服务程序以RETI指令结束;
下⾯的程序介绍了interrupt关键词的⽤法,展⽰了⽤于进⼊、退出中断服务程序的汇编代码,using关
键词则是为了指定该中断服务程序使
⽤与⾮中断程序不同的⼯作寄存器组,须要注意的是,下⾯的中断服务程序没有使⽤⼯作寄存器,所以进⼊函数时切换寄存器组的代码被优
化掉了:
1 extern bit alarm;
2 int alarm_count;
3
4
5 void falarm (void) interrupt 1 using 3 {
6 1 alarm_count *= 2;
7 1 alarm = 1;
8 1 }
下⾯是对应的汇编代码:
0000 C0E0 PUSH ACC/* 进⼊中断服务程序时,ACC寄存器内容压栈 */
0002 C0D0 PUSH PSW/* 进⼊中断服务程序时,PSW寄存器内容压栈 */0004 E500 R MOV A,alarm_count+01H
0006 25E0 ADD A,ACC
0008 F500 R MOV alarm_count+01H,A
000A E500 R MOV A,alarm_count
000C 33 RLC A
000D F500 R MOV alarm_count,A
000F D200 E SETB alarm
0011 D0D0 POP PSW/* 退出中断服务程序前,恢复PSW寄存器的内容 */
0013 D0E0 POP ACC/* 退出中断服务程序前,恢复ACC寄存器的内容 */
0015 32 RETI
作为中断服务程序的函数必须遵循的规则:
1)中断服务函数不能有参数;
2)中断服务函数返回值类型必须为void类型;
3)不能直接调⽤或者通过函数指针调⽤中断服务函数,中断服务函数只能由硬件⾃动调⽤,我们在程序中调⽤中断服务函数,将引起RETI 指令的执⾏,该指令被⼈为执⾏,⽽其对应的硬件中断请求并不存在,这将导致单⽚机硬件中断系统产⽣不确定的致命错误;
4)Keil Cx51编译器⽀持中断号范围0-31,具体可⽤的中断号须要结合⽤户所⽤的具体芯⽚⼿册;