Keil C51中变量的使用

发布者:liliukan最新更新时间:2011-07-21 关键字:Keil  C51  变量 手机看文章 扫描二维码
随时随地手机看文章

引言
    8051内核单片机是一种通用单片机,在国内占有较大的市场份额。在将C语言用于51内核单片机的研究方面,Keil公司做得最为成功。由于51内核单片机的存储结构的特殊性,Keil C51中变量的使用与标准C有所不同。正确地使用变量,有利于获得高效的目标代码。下面详细介绍Keil C51中变量的使用方法。

1 CPU存储结构与变量的关系
    变量都需要有存储空间,存储空间的不同使得变量使用时的工作效率也不同。
    标准C的典型运行环境是8086(含IA-32系列)内核,其存储结构是CPU内部有寄存器,外部有存储器,寄存器的访问速度大大高于存储器的访问速度。在标准C中,不加特别定义的变量是放在存储器中的,使用register可以强制变量存储在寄存器中,对于使用特别频繁且数量不多的变量可以选用这种存储模式,以获得更高的工作效率。
    相比之下,51内核单片机的存储结构则显得有些怪异,它的存储空间有3个:程序存储器空间(64 KB含片内、片外)、片外数据存储器空间(64KB)、片内数据存储器及特殊功能寄存器空间。它没有真正意义上的寄存器,它的寄存器其实是片内数据存储器(如R0~R7)和特殊功能寄存器(如A、B等)中的一部分。因此,在Keil C51中使用变量就和标准C有很大不同。

2 Keil C51变量分析
    Keil C51支持标准C原有的大多数变量类型,但为这些变量新增了多种存储类型,也新增了一些标准C没有的变量。
2.1 Keil C51新增的变量存储类型
    Keil C51中定义变量的格式如下:
    [存储种类]数据类型[存储类型]变量名表;
    其中,[存储类型]是标准C中没有的,[存储类型]共有6种,分别介绍如下:
    ①data。将变量存储在片内可直接寻址的数据存储器中。使用这种存储模式,目标代码中对变量的访问速度最快。
    ②bdata。将变量存储在片内可位寻址的数据存储器中。在目标代码中变量可以方便地进行位处理,在不进行位处理时与data相同。
    ③idata。将变量存储在片内间接寻址的数据存储器中。在52内核中,当片内直接寻址数据存储器不够用时,可以使用128字节间接寻址数据存储器,访问速度一般较data要慢一些,但具有最大的片内数据存储器空间;在51内核中因无单独的间接寻址数据存储器区,idata与data无区别。
    ④xdata。将变量存储在片外数据存储器中。目标代码中只能使用“MOVX A,@DPTR”和“MOVX@DPTR,A”指令访问变量,访问速度最慢,但存储空间最大(64KB)。
    ⑤pdata。将变量存储在片外数据存储器中的第一页(00H~FFH)中。目标代码中可以使用“MOVX A,@Ri”和“MOVX@Ri,A”指令访问变量,访问速度与xdata相同,存储空间为256字节。
    ⑥code。将变量存储在程序存储器中。目标代码中只能使用MOVC指令访问变量,因变量存储在程序存储器中,具有非易失性且为只读。
2.2 Keil C51新增的指针变量存储类型
    Keil C51中的指针变量形式如下:
    数据类型[数据存储类型]*[指针存储类型]标识符;
    其中,[数据存储类型]和[指针存储类型]都是标准C中没有的。[数据存储类型]定义数据(即寻址对象)存储的空间,[指针存储类型]定义指针自身存储的空间。若不使用[数据存储类型],则指针为一般指针,占用3个字节;若使用[数据存储类型]则指针为基于存储器的指针,占用1~2个字节。
2.3 Keil C51新增的变量类型
    bit:位变量。存储在片内数据存储器的可位寻址字节(20H~2FH)的某个位上,这个变量在实时控制中具有很高的实用价值。
    sfr:特殊功能寄存器变量。存储在片内特殊功能寄存器中,用来对特殊功能寄存器进行读写操作。
    sbit:特殊功能寄存器位变量。存储在片内特殊功能寄存器的可位寻址字节(地址可以被8整除者)的某个位上,用来对特殊功能寄存器的可位寻址位进行读写操作。
    sbitl6:16位特殊功能寄存器变量。存储在片内特殊功能寄存器的连续2个字节的低地址上,这个变量类型很少使用。
以上这些Keil C51中新增的变量类型,不支持数组和指针操作。[page]

3 Keil C51中使用变量存储模式的必要性
    在Keil C51中,变量的存储模式是一个可选项,如果不使用这个选项,则Keil C51在编译时自动进行优选分配。但这种处理方法有以下缺点:
    ①系统不知道各种变量的使用频度,有可能对使用频度高的变量使用了访问速度慢的片外存储方式,而对使用频高的变量使用了片内存储方式,使得程序的运行效率降低;
    ②在使用指针寻址时,由于不知道寻址对象的存储方式,只好使用一般指针,在Keil C51中一般指针要多占用1~2个字节,并且使用时还要对存储方式进行判断,增加了寻址操作时间。
    如果能够在定义变量的同时定义其存储类型,可以高效地使用51内核单片机的存储空间,获得高质量的目标代码。

4 Keil C51变量的使用方法
4.1 全局变量和静态局部变量
    全局变量一般会在多个函数中被使用,并在整个程序运行期间内有效,静态局部变量虽然只在一个函数中使用,但也是在整个程序运行期间有效。对于这些变量,应尽量选择data型,这样在目标代码中就可以用直接寻址指令访问,获得最高的访问速度,提高程序的工作效率。例如一个保存人数的全局变量n_g,在多个函数中都被经常用到,可以这样定义:
    unsigned int data n_g;//对n_g赋值时使用“MOV XXH,……”指令
4.2 数组(包括全局和局部)
    定义数组一般用idata存储类型,在目标代码中使用“MOV@Ri”指令进行间接寻址。如果因数组元素过多而在编译时报错,可以改用pdata和xdata存储类型。
    数组定义为data存储类型意义不大,因为既然使用数组,就是希望能够根据某一自变量访问数组元素。如定义X[100],一般都是为了能够使用X[i](i是一个变量)来访问,这样在目标代码中就必须使用问接寻址,所以数组没有必要使用data存储类型,即便使用了data存储类型,在目标代码中也仍然要用间接寻址指令。数组定义成idata存储类型,在使用52内核且片内数据存储器不够时,会使用只能间接寻址的片内数据存储空间。这样,既不能降低处理速度,又扩大了可使用的存储空间。
4.3 供查表用的数据
    这类数据的特点是需要始终保持不变,且使用时只读,因此应定义为code型。例如一个字形表:
    c.JPG
    全局或局部code型变量在存储时无区别。
4.4 非静态局部变量
    非静态局部变量仅在某一函数内使用,退出该函数时变量也被释放。
    若系统使用small存储模式,对于这些变量可以不加存储说明,由编译软件自行按最优原则决定,因为仅在函数内使用的非静态局部变量,有可能使用工作寄存器R0~R7,这样会更快速和更节省存储空间。例如:
    unsigned char i,j; //系统尽可能会用R0~R7存储i和j
    若系统使用了compact或large存储模式,则应将这些变量定义为data存储模式,以防系统自行决定时被定义为pdagta或xdata模式而降低工作效率。
4.5 指针
    如前所述,定义指针变量时有2个存储类型:数据存储类型,说明被寻址对象的存储类型;指针存储类型,说明指针自身的存储类型。当数据存储类型为xdata时,指针自身占用2个字节;当数据存储类型为pdata以及idata等片内存储类型时,指针自身占用1个字节;若不说明数据存储类型,指针自身就要占用3个字节。因此,在KeilC51中使用指针时,应尽量定义数据存储类型,但要特别注意指针中的数据存储类型与被寻址对象的存储类型必须一致。指针都是频繁使用的,它要不断被设置、修改和使用,因此它自身的存储类型应选择data型。例如定义一个数组时就同时定义其存储类型,以后用指针对其寻址时就将数组的存储类型添加到指针的数据类型中。方法如下:
    d.JPG

[page]

4.6 二义性变量
    在标准C中如果要使用一个二义性变量,只能用枚举类型。如:
    e.JPG
    以上程序在Keil C51中使用时,变量t虽然仅有0和1两种状态,但在目标代码中仍占用一个字节。此处理方法既浪费存储资源,又延长了处理时间,这对于8086内核算不上多大问题,但在资源有限、运行速度不高的51内核中就不能不考虑了。在Keil C51中可使用以下方法:
    f.JPG
    这两种方式效果是完全相同的,但在目标代码中变量t仅占用1位(即1/8字节),而且因为51内核单片机指令系统中有位处理指令,生成的目标代码占用内存少、运行速度快。
4.7 特殊功能寄存器变量(包括位变量)
    特殊功能寄存器中,累加器A、寄存器B、堆栈指针SP和数据指针DPTR是归系统使用的,在C51中不提供给用户。其他的特殊功能寄存器都可以用sfr定义成变量,其中地址可以被8整除者的各位,还可以用bsfr定义成位变量。访问这些变量,就可以对特殊功能寄存器及其可以位寻址的各位进行读写,达到操作单片机内部各硬件的目的。对于标准的51内核单片机,头文件reg51.h、reg52.h或其他头文件中已对这些特殊功能寄存器变量作了定义,用户可以用#include将此头文件包含进来,然后就可以使用了。现在很多51内核兼容型单片机扩展了更多的特殊功能寄存器,这些就需要用户自行定义,具体方法可参考器件的使用说明。
4.8 外部数据存储器变量
    若设置成pdata和xdata存储类型,将把变量存储在片外数据存储器中。这两种存储类型的访问速度最慢,非迫不得已不要使用。在使用这两种存储类型时,注意尽量只用它保存原始数据或最终结果,尽量减少对其访问的次数,需要频繁访问的中间结果不要用它。
4.9 用外部数据存储器地址扩展的其他硬件
    在单片机外部扩展的其他硬件,一般都借用外部数据存储器地址,表现为外部数据存储器单元形式。对于这些硬件,可以用指针进行读写操作。例如:
    g.JPG

结语
    Keil C51中的变量增加了存储类型,在使用时而显得比标准C稍微复杂。在Keil C51中,变量的存储类型不同,访问变量所需要的时间也不同,由于C51内核单片机资源少、速度慢,变量存储类型对系统工作速度的影响不可忽视。在了解变量与单片机存储结构关系的基础上,根据程序对变量的使用要求,合理地选择变量的存储类型,可以在相同的硬件上获得更高的工作效率。

 

 

 

关键字:Keil  C51  变量 引用地址:Keil C51中变量的使用

上一篇:C8051F020在SD卡主控制器设计中的应用
下一篇:MCS-51单片机与无线调制器的应用

推荐阅读最新更新时间:2024-03-16 12:38

Keil5.15使用GCC编译器编译STM32工程
我们使用Keil一般使用ARMCC编译MCU工程代码.其实,Keil也是支持内嵌GCC编译器的.我们可以使用GCC来编译我们的工程代码. 一、下载GCC编译器 GCC编译器下载地址 二、安装GCC 我们可以把GCC解压到keil的安装目录下面.如下图 三、配置Keil使用GCC编译器 1、配置CC编译规则,Misc Controls 填写 -mcpu=cortex-m4 -mthumb -fdata-sections -ffunction-sections 2、Assembler中规则,Misc Controls 填写 -mcpu=cortex-m4 -mthumb 3、Linker中填写,Mi
[单片机]
<font color='red'>Keil</font>5.15使用GCC编译器编译STM32工程
C51/C52的中断(EXTI)
一、什么是中断 打断:打断当前做的事情,去执行中断函数里的程序,执行完过后回来接着执行原来未执行完的程序。如下图所示: ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 二、中断源及中断号 注意:写中断服务函数时,中断源与中断号要一一对应,否则不能进入中断服务函数,比如: void Timer0IRQ(void) inter
[单片机]
<font color='red'>C51</font>/C52的中断(EXTI)
C51矩阵键盘的检测(两种方法)
要求:扫描矩阵键盘,并将对应按键的值显示在LED上 方法一(传统检测): #include reg52.h #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; //sbit key1=P3^4; uchar code table ={   //共阳极LED数码管显示数字0~F 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e }; uchar num,temp,num1; void delay(u
[单片机]
ARM-LINUX-GCC设置环境变量
在/etc/profile里添加arm-linux-gcc的存放路径 具体是在命令行输入#sudo gedit /etc/profile回车 export PATH=$PATH:/你的arm-linux-gcc存放的路径 保存退出export PATH=/usr/local/arm/bin 注意 这里最好使用 export PATH=$PATH:/usr/local/arm/4.3.2/bin 没有$符号的时候可能会修改了默认路径 然后会回到终端输入命令界面,输入#arm-linux-gcc -v 下面的来自 http://hi.baidu.com/gonghuixue/item/74a18faa2f752292
[单片机]
两种MCU间的串行通信协议设计
ANLA,Rn;A与Rn中的值按位'与',结果送入A中 ANLA,direct;A与direct中的值按位'与',结果送入A中 ANLA,@Ri;A与间址寻址单元@Ri中的值按位'与',结果送入A中 ANLA,#data;A与立即数data按位'与',结果送入A中 ANLdirect,A;direct中值与A中的值按位'与',结果送入direct中 ANLdirect,#data;direct中的值与立即数data按位'与',结果送入direct中。 这几条指令的关键是知道什么是逻辑与。这里的逻辑与是指按位与
[单片机]
C51 单片机 读取93C64
#include reg52.h #include intrins.h //define OP code #define OP_EWEN_H 0x00 // 00 write enable #define OP_EWEN_L 0x60 // 11X XXXX write enable #define OP_EWDS_H 0x00 // 00 disable #define OP_EWDS_L 0x00 // 00X XXXX disable #define OP_WRITE_H 0x40 // 01 A6-A0
[单片机]
<font color='red'>C51</font> 单片机 读取93C64
stm32变量类型
stm32编程过程经常定义变量类型,经常担心数据运算过程中 超过变量类型范围。因为在编程过程中,不同的CPU,其数据类型的意义各不相同,所以一定要注意相应变量数据类型的定义和转换,否则在计算中可能会出现不确定的错误。所以下面列出常见数据类型: 在编程过程中,不同的CPU,其数据类型的意义各不相同,所以一定要注意相应变量数据类型的定义和转换,否则在计算中可能会出现不确定的错误。 一、C语言数据类型 stm32使用的数据类型定义在 stm32f4xx.h中 整型定义: #include core_cm4.h /* Cortex-M4 processor and core peripherals */ #include
[单片机]
Proteus软件在嵌入式系统教学中的应用研究
   0 引言   嵌入式系统是一门涉及计算机体系结构、计算机软件以及其他相关电子技术的综合技术。目前,嵌入式系统技术已经成为最热门的技术之一,各类企业对具备嵌入式系统设计开发能力人才的需求量非常旺盛。在目前各高校开设的嵌入式系统课程中,普遍采用的微处理器是8位的单片机8051,32位ARM7TDMI核的飞利浦NXP LPC系列和三星S3C4480芯片。首先以单片机作为嵌入式系统设计学习的入门,掌握了基本的概念和设计方法之后,再把ARM7内核CPU作为一种“功能更强大的单片机”,无缝升级到流行的ARM平台。   传统的嵌入式系统教学,课堂环节多是纯理论教学,实践环节一般也是使用传统的实验箱,实验项目较少,内容固定,创新手段不足
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved