变量便是一种在程序履行进程中其值能不断改变的量。要在程序中运用变量有必要先用标识符作为变量名,并指出所用的数据类型和存储形式,这样编译体系才能为变量分配相应的存储空间。界说一个变量的格局如下:
在界说格局中除了数据类型和变量名表是必要的,其它都是可选项。存储品种有四种:主动(auto),外部(extern),静态(staTIC)和寄存器(register),缺省类型为主动(auto)。
而这儿的数据类型则是和咱们在第四课中学习到的名种数据类型的界说是相同的。阐明晰一个变量的数据类型后,还可挑选阐明该变量的存储器类型。存储器类型的阐明便是指定该变量在C51硬件体系中所运用的存储区域,并在编译时精确的定位。留意的是在AT89C51芯片中RAM只要低128位,坐落80H到FFH的高128位则在52芯片中才有用,并和特别寄存器地址堆叠。特别寄存器(SFR)的地址表请看附录二 AT89C51特别功用寄存器列表
假如省掉存储器类型,体系则会按编译形式SMALL,COMPACT或LARGE所规矩的默许存储器类型去指定变量的存储区域。无论什么存储形式都能够声明变量在任何的8051存储区规模,然而把最常用的指令如循环计数器和行列索引放在内部数据区能够明显的进步体系功用。还有要指出的便是变量的存储品种与存储器类型是彻底无关的。
SMALL存储形式把一切函数变量和部分数据段放在8051体系的内部数据存储区这使拜访数据非常快,但SMALL存储形式的地址空间受限。在写小型的运用程序时,变量和数据放在data内部数据存储器中是很好的由于拜访速度快,但在较大的运用程序中data区最好只寄存小的变量、数据或常用的变量(如循环计数、数据索引),而大的数据则放置在其他存储区域。
COMPACT存储形式中一切的函数和程序变量和部分数据段定位在8051体系的外部数据存储区。外部数据存储区可有最多256字节(一页),在本形式中外部数据存储区的短地址用@R0/R1。
LARGE存储形式一切函数和进程的变量和部分数据段都定位在8051体系的外部数据区外部数据区最多可有64KB,这要求用DPTR数据指针拜访数据。
之前说到简略说到sfr,sfr16,sbit界说变量的办法,下面咱们再来细心看看。
sfr和sfr16能够直接对51单片机的特别寄存器进行界说,界说办法如下:
sfr 特别功用寄存器名= 特别功用寄存器地址常数;
sfr16 特别功用寄存器名= 特别功用寄存器地址常数;
咱们能够这样界说AT89C51的P1口
sfr要害定后边是一个要界说的姓名,可任意选取,但要契合标识符的命名规矩,姓名最好有必定的意义如P1口能够用P1为名,这样程序会变的好读很多。等号后边有必要是常数,不允许有带运算符的表达式,并且该常数有必要在特别功用寄存器的地址规模之内(80H-FFH),详细可检查附录中的相关表。sfr是界说8位的特别功用寄存器而sfr16则是用来界说16位特别功用寄存器,如8052的T2定时器,能够界说为:
sfr16 T2 = 0xCC; //这儿界说8052定时器2,地址为T2L=CCH,T2H=CDH
用sfr16界说16位特别功用寄存器时,等号后边是它的低位地址,高位地址必定要坐落物理低位地址之上。留意的是不能用于定时器0和1的界说。
sbit可界说可位寻址目标。如拜访特别功用寄存器中的某位。其实这样运用是常常要用的如要拜访P1口中的第2个引脚P1.1。咱们能够照以下的办法去界说:
(1)sbit 位变量名=位地址
sbit P1_1 = Ox91;
这样是把位的肯定地址赋给位变量。同sfr相同sbit的位地址有必要坐落80H-FFH之间。
(2)Sbit 位变量名=特别功用寄存器名^位方位
sft P1 = 0x90;
sbit P1_1 = P1 ^ 1; //先界说一个特别功用寄存器名再指定位变量名地点的方位
当可寻址位坐落特别功用寄存器中时可采用这种办法
(3)sbit 位变量名=字节地址^位方位
sbit P1_1 = 0x90 ^ 1;
这种办法其实和2是相同的,仅仅把特别功用寄存器的位址直接用常数表明。
在C51存储器类型中提供有一个bdata的存储器类型,这个是指可位寻址的数据存储器,坐落单片机的可位寻址区中,能够将要求可位录址的数据界说为bdata,如:
unsigned char bdata ib; //在可位录址区界说ucsigned char类型的变量ib
int bdata ab[2]; //在可位寻址区界说数组ab[2],这些也称为可寻址位目标
sbit ib7=ib^7 //用要害字sbit界说位变量来独立拜访可寻址位目标的其间一位
sbit ab12=ab[1]^12;
操作符“^”后边的位方位的最大值取决于指定的基址类型,char0-7,int0-15,long0-31。
下面咱们用上一课的电路来实践一下这一课的常识。同样是做一下简略的跑马灯试验,项目名为RunLED2。程序如下:
sfr P1 = 0x90; //这儿没有运用预界说文件,
sbit P1_0 = P1 ^ 0; //而是自己界说特别寄存器
sbit P1_7 = 0x90 ^ 7; //之前咱们运用的预界说文件其实便是这个效果
sbit P1_1 = 0x91; //这儿别离界说P1端口和P10,P11,P17引脚
void main(void)
{
unsigned int a;
unsigned char b;
do{
for (a=0;a《50000;a++)
P1_0 = 0; //点亮P1_0
for (a=0;a《50000;a++)
P1_7 = 0; //点亮P1_7
for (b=0;b《255;b++)
{
for (a=0;a《10000;a++)
P1 = b; //用b的值来做跑马灯的把戏
}
P1 = 255; //平息P1上的LED
for (b=0;b《255;b++)
{
for (a=0;a《10000;a++) //P1_1闪耀
P1_1 = 0;
for (a=0;a《10000;a++)
P1_1 = 1;
}
}while(1);
}