购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.7 变量、存储类型与存储模式

全局变量定义在函数外面。全局变量的生命期从所定义的地方开始,其后面的所有函数都可以读/写该全局变量。在本书有关案例中,在使用定时/计数器(Timer/Counter)时,为得到更大的延时值,程序中定义了全局变量tCount,并在定时器中断内对该变量累加,从而得到更大的延时值。如果源程序中其他位置不使用该变量,则tCount可放在中断函数的上一行,而不必放在程序最前面。

静态(static)变量具有固定的内存定位。如果在某个函数内部定义了静态变量及初始值,仅在该函数被首次调用时,该静态变量将被初始化,此后对该函数的调用都不会再初始化该变量,这类似于定义了一个专属于该函数的全局变量。在有关定时器案例中,为通过软件实现更长的延时,常常在定时器溢出中断函数内部定义static u8 tCount=0,通过在每次溢出中断发生时,累加tCount变量来实现更长的延时。

局部变量定义在函数内部。对于循环及其他的临时计算应尽可能使用局部变量。作为优化处理的一部分,编译程序会试图将局部变量维持在寄存器中。寄存器访问是最快的内存访问类型,特别是对于unsigned char和unsigned int类型的变量。

外部(extern)变量用于声明当前C语言程序要使用,且定义在当前项目内其他C语言程序文件中的变量。例如,某单片机程序项目由2个以上C语言程序文件构成;当前C语言程序文件中有定义extern u8 x,这表示变量x是一个外部变量,它定义在项目内其他C语言程序文件内。

易变型(volatile)变量表示一个单变量或数组的值是会随时变化的,即使程序没有专门对其进行任何赋值操作。例如,作为输入的I/O端口,其引脚值将随时可能被用户改变;在中断函数内被修改的变量相对于主程序流程来讲也是随时变化的;很多特殊功能寄存器的值也将随着指令的运行而动态改变。所有这些类型的变量要注意将它们明确定义成“volatile”类型,该类型定义可通知编译器在优化处理过程中不能无故消除它们。

在单片机C语言程序中断函数内,凡是修改的是全局变量或全局数组,而这些变量或数组又被主程序或其他函数引用,则要注意添加volatile关键字。

在8051单片机中,程序存储器(ROM)与数据存储器(RAM)是严格分开的,特殊功能寄存器与片内RAM统一编址,这与一般微型计算机的存储结构是不同的。

Keil C51编译器完全支持8051单片机硬件结构,可完全访问8051单片机的硬件系统的所有部分。Keil C51编译器通过将变量、常量定义成不同的存储类型(data、bdata、idata、pdata、xdata、code),从而将它们定位在不同的存储区中。表1-9列出了Keil C51存储类型与8051单片机存储空间的对应关系。

表1-9 Keil C51存储类型与8051单片机存储空间的对应关系

data、bdata、idata存储类型将数据定位在片内RAM中,且只需要8位地址。

Keil C51编译器提供了两种片外存储类型:xdata和pdata。指定为xdata存储器类型的数据保存在最大空间为64KB的片外RAM中。通过P0与P2端口给出的16位地址(2 16 =64KB)可访问片外空间中的任意位置,但是64KB地址空间并非总是用于存储器寻址的,单片机外围扩展设备地址也可以映射到存储器空间(Memory Space)。这样,C语言程序在访问外围设备时所使用语句与访问扩展内存的语句是相同的,并将这种技术称为内存映射I/O技术。本书有关8255和部分字符及图形液晶显示案例使用的就是这种技术。pdata存储类型的数据保存在最大空间为一页的256B片外RAM中,而页地址则由P2接口提供。

在扩展片外存储器或外部设备时,源程序必须包含绝对内存访问(Absolute Memory Access)头文件absacc.h。该文件中有宏定义:

由其中的XBYTE定义可知,表达式XBYTE[地址]或*(XBYTE+地址)均可用来读/写片外RAM空间的字节数据。在有关62256扩展内存案例中就使用了该表达式访问片外RAM。该表达式相当于汇编语言中的MOVX @DPTR语句。

对于STC15单片机而言,上述关于片内与片外的描述是相对的,要真正选择片外存储,还需要AUXR寄存器的EXTRAM位配合。

在涉及数码管显示、图像与文字显示的案例中,由于数码管段码是固定的,待显示的图像或文字点阵数据也是固定的,将这些数据全部保存在RAM中会占用太多宝贵的空间,甚至导致编译失败并提示变量定义超出了RAM空间。这是因为单片机的RAM空间本来就是非常有限的。在使用C语言开发单片机程序时,应将那些运行过程中不会发生变化的数据定义为code存储类型,以保证将这些数据分配到Flash ROM中而不是RAM中。

定义变量时如果省略存储类型,编译程序将自动选择默认存储类型。默认存储类型有小模式(Small)、紧缩模式(Compact)和巨模式(Large)限制,存储模式决定了变量的默认存储类型、参数传递区和未指明存储类型变量的存储类型。表1-10列出了这3种存储模式及相关说明。

表1-10 3种存储模式及相关说明

在固定的存储器地址上进行变量传递是Keil C51的特征之一。在Small模式下,参数传递在片内RAM中完成,Compact和Large模式允许参数在片外RAM中传递。模式选择可在Keil C51项目选项窗口中的Target选项卡下完成,默认选择的是Small模式。 eMcbKvFOSSkUY5mgN5bIDJ2k+dAYc+R93JwthfbXxyFm0rNKNUrYb3WkkvveHzlg

点击中间区域
呼出菜单
上一章
目录
下一章
×