当前位置:首页 > 单片机 > 单片机
[导读]Function Declarations函数声明Cx51对标准C进行了一定的扩展,使用这些扩展可以:(1)把一个函数声明为一个中断过程(2)选择使用的寄存器组(3)选择存储器模式(4)声时可重入(5)声明外部函数在函数声中包含这些

Function Declarations函数声明

Cx51对标准C进行了一定的扩展,使用这些扩展可以:

(1)把一个函数声明为一个中断过程

(2)选择使用的寄存器组

(3)选择存储器模式

(4)声时可重入

(5)声明外部函数

在函数声中包含这些扩展或属性,使用下面的方法声明Cx51函数

[return_type]funcname([args]) [{small | compact | large}][reentrant][interruptn][usingn]

这里

return_type 返回值类型

funcname 函数名称

args参数

small, compact, or large 存储器模式

reentrant 是否可重入

interrupt 是否是中断函数

using 使用哪个寄存器组

Function Parameters and the Stack函数参和堆栈

经典的8051堆栈指针只访问内部的数据存储器。Cx51紧接着在所有的数据之后放堆栈区。堆栈指针间接地访问内部数据存储器,可以访问所有的00-FFH的空间

在经典的8051中堆栈的空间是受限制的,最大只有256字节。除了函数参数消耗堆栈空间,Cx51为每个函数指定了一些固定的内存空间。当函数被调用时,调用者必须在进入函数之前把参数拷贝到这个固定的空间中。然后函数从这个固定的空间中读取并使用这些参数。在这个过程中只有返回地址存放在堆栈中。中断函数会需要更多的堆栈空间,因为程序必须切换寄存器组并且保存一些寄存器的值到堆栈中。

注:Cx51允许使用在某些8051的增强型变种中可用的扩展的堆栈区。通过这种方式,堆栈区域的大小可以增加到几K字节。

在缺省的情况下,Cx51使用三个寄存器传递函数的参数,这样可以提高代码的执行速度。

注:有些8051变种仅提供64字节的片上数据存储器,大多数器件有256字节。在使用存储器模式时应该把这些都考虑进去,毕竟片上的data和idata数据存储器直接影响到堆栈空间的大小。

Passing Parameters in Registers通过寄存器传递参数

Cx51允许使用CPU寄存器传递三个参数,由于这种方式不需将参数写入存储器和从存储器中读出,所以明显地提高了系统的性能。参数的传递受上一章讲到的REGPARMS 和NOREGPARMS指令控制。

下表列出了用于不同位置参数和数据类型的寄存器。


参数个数


Char, 1-yte ptr


Int, 2-byte ptr


Long, float


Generic ptr


1


R7


R6&R7


R4-R7


R1-R3


2


R5


R4&R5


R4-R7


R1-R3


3


R3


R2&R3



R1-R3


没有可用的寄存器来传递参数,则用一个固定的存储器区域来传递函数参数。

Function Return Values函数返回值

函数返回值总是使用CPU寄存器。下表列出了返回值的类型和所用的寄存器。


返回值


寄存器


描述


Bit


进位标志



Char, unsigned char, 1-byte ptr


R7



Int, unsigned int, 2-byte ptr


R6&R7


高位字节为R6,低位字节为R7


Long, unsigned long


R4-R7


高位字节为R4,低位字节为R7


Float


R4-R7


32位IEEE格式


Generic ptr


R1-R3


存储器类型在R3,高位R2,低位R1


注:如果函数的第一个参数是bit类型的,其他的参数据是不通过寄存器传递的。这是因为能在寄存器中传递的参数与前述的编号方案都不相同。因此,bit类型的参数应该在参数列表中末尾声明。

Specifying the Memory Model for a Function

声明函数的存储器模式

Cx51函数通常采用缺省的存储器模式来决定哪个存储器空间用于函数的参数和局部变量。

可以通过包含small, compact,或large在函数的属性中来指定函数的存储器类型。

如:

int large_func (int i, int k) large /* Large model */

{

return (mtest (i, k) + 2);

}

函数使用small存储器模式的好处是函数的参数和局部变量都放在8051的RAM中。因此,数据访问效率非常高。然而,内部的数存储器有限。有时候有限的内部数据存储器的大小不能满足需要,就必须使用其他的存储器模式。在这种情况下,可以使用上面的方法定义一个函数使不同的存储器模式。

通过指定函数的存储器模式,可以从三种可能的可重入堆栈和结构指针中择优使用。堆访问SMALL模式要比访问LARGE模式快得多。

Specifying the Register Bank for a Function

指定函数使用的寄存器组

8051系列器件的低32字节被分成了4个组,每个组8个寄存器。程序可以通过R0-R7访问这些寄存器。寄存器组可以通过程序状态字(PSW)的两个位选择。寄存器组对中断处理或者是使用实时操作系统非常有用。在中断服务程序中CPU切换寄存器组而不把不当前的寄存器都保存起来。

关键字using用来指定函数使用的寄存器组:

void rb_function (void) using 3

{

。。。。。。。

}

关键字using的参数是一个0-3的整型常量,而且表达式中不允许有操作符出现。在函数的原型中不允许出现using关键字。这个关键词对函数代码有如下影响:

(1)当前选择的寄存器组在函数的入口处被保存在堆栈中

(2)指定的寄存器组被设定

(3)前面使用的寄存器组被保存下来直到当前的函数退出

不能关键字using来声明一个返回值在寄存器中的函数。在使用的时候必须非常小心,确保寄存器组切换只出现在谨慎地控制地区域。稍不小心会得到错误的返回值。即使用同一个寄存器组,使用了using关键字声明了属性的函数也不能返回一个bit类型的值。

典型地,using属性对于声明了interrupt属的函数是非常有用的。为每一个级别的中断都声明一个不同寄存器组是比较常见的。因此,你可以在所有非中断程序中使用一个寄存器组,在高优先级中断中使用一个寄存器组,在低优先级中断中使用一个寄存器组。

Register Bank Access寄存器访问

Cx51允许在一函数中定义缺省的寄存器组。控制指令REGISTERBANK允许程序员在源文件中指定在所有函数另使用哪一个寄存器组。然而这个指令并不产生切换寄存器的代码。

复位后,8051在PSW中装入00h从而选择寄存器组0。所以缺省地所有非中断程序代码都使寄存器组0。要想改变,必须:

(1)修改startup代码以选择其他的寄存器组

(2)使用REGISTERBANK指令进行声明

缺省地,Cx51编译器生成用绝对地址访问R0-R7的代码。这是为了最高的执行效率。绝对地址的使用通过指令AREGS和NOAREGS控制。使用绝对址进行寄存器访问的函数不能被使用其他寄存器组的函数调用。由于调用者使用了不同的寄存器组,这样做会引起不可预料的后果。要使用函数对当前的寄存器组不敏感,函数必须在编译前使用控制指令NOAREGS。这对于那种可能在主函数中调用,也可能被使用不同寄存器组的中断程序调用的函数很有用。注:Cx51编译器并不检查函数间的寄存器组是否一致。因此,必须确保使用不寄存器组的函数只调用那些不指定缺省寄存器组的函数。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭