- 1、本文档共8页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
KEIL C51使用技巧
函数的递归调用和再入函数
函数类型 函数名 (形参表)[reentrant]
再入函数可被递归调用,无论何时,包括中断服务函数在内的任何函数都可调用再入函数。与非再入函数的参数传递和局部变量的存储分配方式不同,Cx51编译器为再入函数生成一个模拟栈,通过其来完成参数传递和存放局部变量。
模拟栈所在的存储器空间根据再入函数存储器模式的不同,可以是DATA、PDATA、XDATA存储器空间。当程序中包含有多种存储器模式的再入函数时,编译器为每种模式单独建立一个模拟栈并独立管理各自的栈指针。
对于再入函数有如下规定:
再入函数不能传送bit类型的参数,也不能定义一个局部位变量,再入函数不能包括位操作和8051系列单片机的可位寻址区
与PL/M51兼容的函数不能具有reentrant属性,也不能调用再入函数
编译时存储器模式基础上为再入函数在内部或外部存储器中建立一个模拟堆栈区,称为再入栈。在small模拟下再入栈位于idata区,在compact模式下再入栈位于pdaa区,在large模式下再入栈位于xdata区。再入函数的局部变量及参数都被放入再入栈中,从而使再入函数可进行递归调用。而非再入函数的局部变量被放在再入栈外的暂存区内,如对其进行递归调用,则上次调用时使用的局部变量数据将被覆盖。
在同意 个程序中可定义或使用不同存储器模式的再入函数,任意模式的再入函数不能调用不同模式的再入函数,但可任意调用非再入函数。
在参数的传递上,实际参数可传递给间接调用的再入函数。无再入属性的间接调用函数不能包含调用参数,但可以使用定义的全局变量来进行参数传递。
采用函数递归调用可使程序结构紧凑,但要求采用再入函数,以便利用再入栈来保存有关的局部变量数据,因此要占用较大的内存空间。另外,递归调用时对函数的处理速度较慢,因此一般情况下应尽量避免使用函数递归调用,定义函数时应尽量避免使用再入属性。
8051常规栈是位于内部数据RAM中,是向上生长型的
而模拟再入栈是向下生长型的。
中断服务函数与寄存器组定义
C语言中一般形式为:
函数类型 函数名(形参表) [interrupt n][using n]
Interrupt n中n为中断号,取值范围0-31,编译器从8n+3处产生中断向量
一般常用的中断向量表如下:
中断号n 中断源 中断向量8n+3
0 外部中断0 0003H
1 定时器0 000BH
2 外部中断1 0013H
1 定时器1 001BH
4 串行口 0023H
8051系列单片机片内RAM使用4个不同的工作寄存器组,每个组中有8个寄存器R0-R7
扩展关键字using专门用于选择不同的工作寄存器组,n范围0-3。
若不选择using,则由编译器自动选择一个寄存器组作为绝对寄存器组访问。注意该关键字后面不允许跟带运算符的表达式。
该关键字对函数目标代码的影响如下:
在函数入口处将当前工作寄存器组保护到堆栈中;
指定的工作寄存器内容不会改变;
函数退出前将被保护的工作寄存器组从堆栈中恢复。
使用关键字using要保证任何寄存器组的切换都只在仔细控制的区域中发生。带该关键字的函数原则上不能返回bit类型的值。关键字using不允许用于外部函数。
关键字interrupt不允许用于外部函数,对中断函数目标代码的影响如下:
在进入中断函数时,特殊功能寄存器ACC、B、DPH、DPL、PSW将被保存入栈
若不使用关键字using进行工作寄存器组切换,则将中断函数所用到的工作寄存器都入栈保存
函数退出前所有寄存器内容出栈恢复
中断函数由RETI结束
中断函数编写需遵循的原则
中断函数不能进行参数传递,否则编译报错
中断函数没有返回值,建议定义为void类型
任何情况下都不能直接调用中断函数,否则编译错误
若中断函数调用了其他函数,则被调用函数使用的寄存器必须和中断函数相同,由于中断函数不可预测,中断函数对其他函数的调用有可能形成递归调用,需要时,可将被中断函数调用的其他函数定义成再入函数
KEIL Cx51编译器从绝对地址8n+3处产生一个中断向量,该向量包含一个到中断函数入口地址的绝对跳转,在对源程序编译时,可用编译控制命令NOINTVECTOR抑制中断向量的产生,从而使用户有能力从独立的汇编程序模块中提供中断向量。
函数变量的存储方式
C语言中有四种存储种类:
自动变量(auto):默认,也可省略申明。当函数调用时存在,退出函数则消失。
外部变量(extern)
静态变量(static):分局部静态变量和全局静态变量
局部静态变量:只能在定义它的函数中进行访问,退出函数后,该值依旧存在,但不能访问。
全局静态变量:在函数外部定义,作用防卫从它的定义点开始,直到程序结束。
文档评论(0)