C51编译器及其对C语言的扩充允许编程者对中断的所有方面进行控制。这种支持能使系统编程者创建高效的中断服务程序,用户只需在普通和高级方式下关心中断及必要的寄存器组切换操作,C51编译器将产生最合适的代码。
1.8.1 中断服务程序的定义
使用中断服务函数的完整语法如下:
返回值 函数名([参数])[模式][再入] interrupt n[using n] “interrupt”后接一个0~31的常数,不允许使用表达式。 中断不允许用于外部函数,它对函数目标代码的影响如下:
l 当使用函数时,SFR中的ACC、B、DPH、DPL和PSW(当需要时)入栈; l 如不使用寄存器组切换,甚至中断函数所需的所有工作寄存器(Rn)都入栈; l 函数退出前,所有的寄存器内容出栈; l 函数由8051控制命令“RETI”终止。
1.8.2 开发中断过程时的规则
l 不能进行参数传递,如果中断过程包括任何参数声明,编译器将产生一个错误信息; l 无返回值,如果想定义一个返回值将产生错误,然而,如果返回整型值编译器将不产生
错误信息,因为整型值是默认值,因而编译器不能清楚识别。
l 编译器会识别对中断过程的直接调用并拒绝它们,在任何情况下不能直接调用中断过
程,因为退出该过程是由操作码RETI完成的。RETI影响8051芯片的硬件中断系统,由于硬件上没有中断请求存在,因而这个操作码的结果是不定的并且通常是致命的。由于疏忽,可能用指针来间接调用它,这是值得注意的。
l 编译器从绝对地址8n+3处产生一个中断向量,其中n为中断号,该向量包括一个到中
断过程的跳转,向量的产生可由指令NOINTVECTOR压缩。因而用户有能力从独立的汇编模块中提供中断向量。
l C51编译器允许0~31个中断,究竟允许哪些中断依赖于使用的8051系列芯片,编译器
不能检查。
l 如果中断程序中有浮点运算,必须保持浮点寄存器状态,当没有其它程序执行浮点运算
时,可能不保存,函数“fsave”和“fprestore”用来保存浮点状态。
l 中断过程调用的函数所使用的寄存器必须与中断过程相同,当没有使用“using”指令
时,编译器会选择一个寄存器组作绝对寄存器访问,当子程序使用另一个寄存器组时会发生错误,用户必须保证按要求使用相应寄存器组,C编译器不会对此检查。 例:
unsigned int interruptent; unsigned char second;
time() interrupt 1 using 2 /*定时器0中断服务程序,工作寄存器使用2区*/ {
if(++interruptcnt==4000) { second++; /*秒计数加一*/ interruptcnt=0; /*清中断计数*/
} } 1.9 再入函数
再入函数可被递归调用,调用可发生在任何时候,即使是在中断过程中。在实时处理的应用问题中常常需要再入函数。
使用关键字“reentrant”可有选择地定义函数有再入能力。在存贮器模式的基础上为再入函数在内部或外部存贮器中模拟了一个栈区域。由于MCS-51缺乏合适的寻址方法,使用栈结构是相当必要的。因而应尽量少用再入函数。
定义一再入函数的语法如下:
返回值 函数名([参数])[模式]reetrant[interrupt n][using n] 例:
int calc(char i,int b) reentrant { int x; x=table[i]; return(x*b); }
使用再入函数有如下规定:
l 不能传递类型为“bit”的参数。也不能声明一个局部标量,再入功能不能包括位操作
及MCS-51可位寻址区域。
l 不能在“alien”函数调用再入函数。 l 再入函数可同时有其它属性,如“using”函数模式和“interrupt”。 l 再入函数不能同时有“alien”属性,从而遵守PL/M规则。 l 返回地址及可能的PUSH/POP操作存入MCS-51的栈中或被执行(不在再入栈中)。 l 在同一模块中,任意模块的再入函数(small reentrant,lage reentrant,compact reentrant)不能与具有不同模式的再入函数混合。 再入函数举例: /*这个再入函数可以从“main”及中断程序中调用*/ int calc(char i,int b)reentrant { int x; x=table[i]; return(x*b); } 1.10 参数传递 通过CPU的寄存器可传递至多三个参数。这样产生与汇编子程序相当的有效参数机制。如果寄存器被占用,或说明了“#pragma NOREGPARMS”,参数变量将使用固定的存贮器位置,存贮器模式决定了8051存贮器为参数提供的位置。 表:候选的参数寄存器 参数类型 char,1字节指针 int,2字节指针 long,float 一般指针 一个参数 R7 R6,R7 R4~R7 R1,R2,R3 二个参数 R5 R4,R5 R4~R7 R1,R2,R3 三个参数 R3 R2,R3 ? R1,R2,R3 函数的返回值放在CPU固定的寄存器中,列表如下。这样,与汇编子程序的接口变得非常容易。 表:函数返回值的寄存器用法 返 回 值 寄 存 器 意 义 bit 进位标志 C (unsigned) char R7 (unsigned) int R6,R7 高位在R6,低位在R7 (unsigned) long R4~R7 高位在R4,低位在R7 float R4~R7 32位IEEE格式 指 针 R1,R2,R3 类型选择在R3,高位在R2,低位在R1 1.11 PL/M51接口 Franklin C51利用关键字“alien”提供了一个与Intel PL/M-51直接和简单和接口,关键字“alien”在所有存贮器模式下可用于“extern”和“public”函数。现有的PL/M-51程序利用C语言的强大功能可与Franklin C-51连接起来。 使用关键字“alien”,C51可用PL/M-51规定的参数传递方式工作。“alien”可用于外部或公共函数,并可用于任一模式,这样,已有的PL/M-51程序可加入到C-51中。Alien函数始终包含一个标准的参数数量,因此,C中定义的三点(?)记号不被接受,且会产生一个错误信息。 例:
相关推荐: