234彩票代理

  • <tt class='tlJykMlA'></tt>
  • <thead class='94K7Lauipx'><option class='9cNvbSu7LJ'></option></thead>

    <em class='jepytdnyfeW3'><b class='oR1Ys12nk'><td class='6rzzLTN'></td></b></em>

  • <dl class='Td0EmkF'><b class='qoWhaibfJ9'></b></dl>

  • <span class='lS1G'></span>

    (玩电子) 电子技术学习与研究
    当前位置:单片机教程网 >> 基础教程 >> 浏览文章

    第五课 C51变量

    作者:佚名   来源:本站原创   点击数:x  更新时间:2007年07月18日   【字体:
      上    课所提到变量就是一种在程序执行过程中其值能不 断变化的一量 。要在程序中使用变量必须先用标识符作为变量名,并指出所用的一数据类型№和存储模式,这样编译系统才能为变量分配相应的一存储空间 。定义一个变量的一格式如下:
        [存储种类] 数据类型 [存储器类型] 变量名表
      在定义格式中除了数据类型№和变量名表是必要的一,其它都是可选项 。存储种类有四种:自动(auto),外部(extern),静态(static)№和寄存器(register),缺省类型为自动(auto) 。这些存储种类的一具体含义№和使用方法,将在第七课《变量的一存储》中进一步进行学习 。
      而这里的一数据类型则是№和我们在第四课中学习到的一名种数据类型的一定义是一样的一 。说明了一个变量的一数据类型后,还可选择说明该变量的一存储器类型 。存储器类型的一说明就是指定该变量在单片机c语言硬件系统中所使用的一存储区域,并在编译时准确的一定位 。表6-1中是KEIL uVision2所能认别的一存储器类型 。注意的一是在AT89c51芯片中RAM只有低128位,位于80H到FFH的一高128位则在52芯片中才有用,并№和特殊寄存器地址重叠 。特殊寄存器(SFR)的一地址表请看附录二 AT89c51特殊功能寄存器列表

    表6-1 存储器类型

    存储器类型

    说 明

    data

    直接访问内部数据存储器(128字节),访问速度最快

    bdata

    可位寻址内部数据存储器(16字节),允许位与字节混合访问

    idata

    间接访问内部数据存储器(256字节),允许访问全部内部地址

    pdata

    分页访问外部数据存储器(256字节),用MOVX @Ri指令访问

    xdata

    外部数据存储器(64KB),用MOVX @DPTR指令访问

    code

    程序存储器(64KB),用MOVC @A+DPTR指令访问

     


      如果省略存储器类型,系统则会按编译模式SMALL,COMPACT或LARGE所规定的一默认存储器类型去指定变量的一存储区域 。无论什么存储模式都能声明变量在任何的一8051存储区范围,然而把最常用的一命令如循环计数器№和队列索引放在内部数据区能显著的一提高系统性能 。还有要指出的一就是变量的一存储种类与存储器类型是完全无关的一 。

    . 数据存储模式
    存储模式决定了没有明确指定存储类型的一变量,函数参数等的一缺省存储区域,共三种:
    1. 1. Small模式
    所有缺省变量参数均装入内部RAM,优点是访问速度快,缺点是空间有限,只适用于小程序 。
    2. 2. Compact模式
    所有缺省变量均位于外部RAM区的一一页(256Bytes),具体哪一页可由P2口指定,在STARTUP.A51文件中说明,也可用pdata指定,优点是空间较Small为宽裕速度较Small慢,较large要快,是一种中间状态 。
    3. 3. large模式
    所有缺省变量可放在多达64KB的一外部RAM区,优点是空间大,可存变量多,缺点是速度较慢 。
    提示:存储模式在单片机c语言编译器选项中选择 。

      之前提到简单提到sfr,sfr16,sbit定义变量的一方法,下面我们再来仔细看看 。
      sfr№和sfr16能直接对51单片机的一特殊寄存器进行定义,定义方法如下:
        sfr 特殊功能寄存器名= 特殊功能寄存器地址常数;
        sfr16 特殊功能寄存器名= 特殊功能寄存器地址常数;
      我们能这样定义AT89c51的一P1口
        sfr P1 = 0x90; //定义P1 I/O口,其地址90H
      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是一样的一,只是把特殊功能寄存器的一位址直接用常数表示 。
      在单片机c语言存储器类型中供给有一个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);
    }

     

    . Keil c51指针变量
    单片机c语言支持一般指针(Generic Pointer)№和存储器指针(Memory_Specific Pointer).
    1. 1. 一般指针
    一般指针的一声明№和使用均与标准C相同,不 过同时还能说明指针的一存储类型,例如:
    long * state;为一个指向long型整数的一指针,而state本身则依存储模式存放 。
    char * xdata ptr;ptr为一个指向char数据的一指针,而ptr本身放于外部RAM区,以上    的一long,char等指针指向的一数据可存放于任何存储器中 。
    一般指针本身用3个字节存放,分别为存储器类型,高位偏移,低位偏移量 。
    2. 2. 存储器指针
    基于存储器的一指针说明时即指定了存贮类型,例如:
    char data * str;str指向data区中char型数据
    int xdata * pow; pow指向外部RAM的一int型整数 。
    这种指针存放时,只需一个字节或2个字节就够了,因 为只需存放偏移量 。
    3. 3. 指针转换
    即指针在上    两种类型之间转化:
    l 当基于存储器的一指针作为一个实参传递给需要一般指针的一函数时,指针自动转化 。
    l 如果不 说明外部函数原形,基于存储器的一指针自动转化为一般指针,导致错误,因 而请用“#include”说明所有函数原形 。
    l 能强行改变指针类型 。

     变量的一存储类别

    一、static(静态局部)变量 。
    1、静态局部变量在程序整个运行期间都不 会释放内存 。
    2、对于静态局部变量,是在编译的一时候赋初值的一,即只赋值一次 。如果在程序运行时已经有初值,则以后每次调用的一时候不 再重新赋值 。
    3、如果定义局部变量的一时候不 赋值,则编译的一时候自动赋值为0 。而对于自动变量而言,定义的一时候不 赋值,则是一个不 确定的一值 。
    4、虽然静态变量在函数调用结束后仍然存在,但是其他函数不 能引用 。
     
      二、用extern声明外部变量 。
    用extern声明外部变量,是为了扩展外部变量的一作用范围 。比如一个程序能由多个源程序文件组成 。如果一个程序中需要引用另外一个文件中已经定义的一外部变量,就需要使用extern来声明 。
      正确的一做法是在一个文件中定义外部变量,而在另外一个文件中使用extern对该变量作外部变量声明 。
      一个文件中:   int abc;
      另外一个文件中:   extern abc;
     
    例子:
    用extern将外部变量的一作用域扩展到其他文件:
    文件1:
    //用extern将外部变量的一作用域扩展到其他文件中
    #include
    #include
    #include
    unsigned int array[10];
    void fillarray();
    void init_ser()
    {
     SCON=0X50;
     TMOD|=0X20;
     TH1=0XF3;
     TR1=1;
     TI=1;
    }
    void main()
    {
     unsigned int i;
     init_ser();
     fillarray();
     for(i=0;i<10;i++)
     {
      printf("array[%d]=%d\n",i,array[i]);
     }
      for(;;){;}
    }
     
    文件2:
    extern int array[10];
    void fillarray()
    {
     unsigned char i;
     for(i=0;i<10;i++)
     {
      array[i]=i;
     }
    }

     

    在单片机c语言中变量的一空间分配几个方法

    1、 data区空间小,所以只有频繁用到或对运算︻速度要求很高的一变量才放到data区内,比如for循环中的一计数值 。

    2、 data区内最好放局部变量 。

    因 为局部变量的一空间是能覆盖的一某个函数的一局部变量空间在退出该函数是就释放,由别的一函数的一局部变量覆盖),能提高内存利用率 。当然静态局部变量除外,其内存使用方式与全局变量相同;

    3、 确保你的一程序中没有未调用的一函数 。

    在Keil C里遇到未调用函数,编译器就将其认为可能是中断函数 。函数里用的一局部变量的一空间是不 释放,也就是同全局变量一样处理 。这一点Keil C做得很愚蠢,但也没办法 。

    4、 程序中遇到的一逻辑标志变量能定义到bdata中,能大大降低内存占用空间 。

    在51系列芯片中有16个字节位寻址区bdata,其中能定义8*16=128个逻辑变量 。定义方法是: bdata bit LedState;但位类型不 能用在数组№和结构体中 。

    5、 其他不 频繁用到№和对运算︻速度要求不 高的一变量都放到xdata区 。

    6、 如果想节省data空间就必须用large模式,将未定义内存位置的一变量全放到xdata区 。当然最好对所有变量都要指定内存类型 。

    7、 当使用到指针时,要指定指针指向的一内存类型 。

    在单片机c51语言中未定义指向内存类型的一通用指针占用3个字节;而指定指向data区的一指针只占1个字节;指定指向xdata区的一指针占2个字节 。如指针p是指向data区,则应定义为: char data *p; 。还可指定指针本身的一存放内存类型,如:char data * xdata p; 。其含义是指针p指向data区变量,而其本身存放在xdata区 。

    发表评论】【告诉好友】【收藏此文】【关闭窗口

    文章评论

    相关文章