ImageVerifierCode 换一换
格式:DOC , 页数:78 ,大小:520KB ,
资源ID:7680995      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/7680995.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(C51存储单元.doc)为本站上传会员【xrp****65】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

C51存储单元.doc

1、  char *addr=0xc000; char xdata *addr=0xc000; 除了在内存中占用的字节不同外,还有别的区别吗? char *addr=0xc000; 是通用定义,指针变量 addr 可指向任何内存空间的值; char xdata *addr=0xc000; 指定该指针变量只能指向 xdata 中的值; 后一种定义中该指针变量(addr)将少占用一个存储字节。     uchar xdata *addr=0xc000;指针指向外ram; 如果:data uchar xdata *addr=0xc000;指针指向外ram但指针本身存在于内

2、ram(data) 中 以此类推可以idata uchar xdata *addr=0xc000;pdata uchar xdata *addr=0xc000; data uchar idata *addr=0xa0;......... 51C语言能不能定义1024个字节的xdata unsigned char的数组呢? 电路是用hc573和6264外扩了8K的ram 需要定义1024个字节的xdata unsigned char的数组,然后写了个测试程序测试定义的数组是否正常           FillMemory(RecBuffer,MAXCOMMBUFFER

3、SIZE-1,0x12);//先填充RecBuffer为0x12                 for(i=0;i

4、FF(255) 单片机C语言教程-指针基础知识 一. 指针变量的定义 指针变量定义与一般变量的定义类似,其形式如下: 数据类型 [存储器类型1] * [存储器类型2] 标识符; [存储器类型1] 表示被定义为基于存储器的指针,无此选项时,被定义为一般指针。这两种指针的区别在于它们的存储字节不同。一般指针在内存中占用三个字节,第一个字节存放该指针存储器类型的编码(由编译时由编译模式的默认值确定),第二和第三字节分别存放该指针的高位和低位地址偏移量。存储器类型的编码值如下: 存储类型I Idata/data/bdata xdata pdata Code 编码值 0x

5、00 0x01 0xFE 0xFF [存储类型2]用于指定指针本身的存储器空间。 1.  char * c_ptr; int * i_ptr; long * l_ptr; 上述定义的是一般指针,c_ptr指向的是一个char型变量,那么这个char型变量位于哪里呢?这和编译时由编译模式的默认值有关, 如果Menory Model—Variable—Large:XDATA,那么这个char型变量位于xdata区: 如果Menory Model—Variable—Compact:PDATA, 那么这个char型变量位于pdata 区: 如果Menory Model——Variab

6、le——Small:DATA,那么这个char型变量位于data区。 而指针c_ptr, i_ptr, l_ptr变量本身位于片内数据存储区中。 2.  char * data c_ptr; int * idata i_ptr; long * xdata l_ptr; 上述定义,c_ptr, i_ptr, l_ptr变量本身分别位于data ,idata,xdata区。 3.  char data * c_ptr; //表示指向的是data区中的char型变量,c_ptr在片内存储区中; int xdata * i_ptr; //表示指向的是xdata区中的int型变量,i_pt

7、r在片内存储区中; long code * l_ptr; //表示指向的是code区中的long型变量,l_ptr在片内存储区中; 4.  char data * data c_ptr; //表示指向的是data区中的char型变量,c_ptr在片内存储区data中; Int xdata * idata i_ptr; //表示指向的是xdata区中的int型变量,i_ptr在片外存储区xdata中; long code * xdata l_ptr; //表示指向的是code区中的long型变量,l_ptr在片内存储区xdata中; 二. 指针应用 1.  int x, j;

8、int * px, *py; px=&x; py=&y; 2.  *px=0; py=px; 3.  *px++<=>*(px++) 4.  (*px)++<=>x++ 5.  unsigned char xdata * x; unsinged char xdata * y; x=0x0456; *x=0x34 //等价于 mov dptr,#456h ; mov a,#34h; movx @dptr,a 6.  unsigned char pdata * x; x=0x045; *x=0x34 //等价于 mov r0,#45h ; mov a,#34h; m

9、ovx @r0,a 7.  unsigned char data * x; x=0x30; *x=0x34 //等价于 mov a,#34h; mov 30h ,a 8.  int *px; px=(int xdata *)0x4000; //将 xdata 型指针 0x4000 赋给 px,也就是将0x4000强制转换为指向xdata区中的int型变量的指针,将其赋给px。 9.  int x; x=*((char xdata *)0x4000); //将0x4000强制转换为指向xdata区中的int型变量的指针,从这个地址中取出值赋给变量x。 10.  px=*(

10、int xdata * xdata *)0x4000); //如何分析? 11.  px=*((int xdata * xdata *)0x4000);将阴影部分遮盖,这个意思就是将0x4000强制转换为指向xdata区中的X型变量的指针,这个X型变量就是阴影“int xdata *”,也就是0x4000指向的变量类型是一个指向xdata区中的int型变量的指针,即0x4000中放的是另外一个指针,这个指针指向的是xdata区中的int型变量。Px值放的是0x4000中放的那个指针。比如【0x4000】—【0x2000】-0x34。Px=0x2000。 12.  x=**((int

11、xdata * xdata *)0x4000); x中放着0x4000中放的那个指针所指向的值。比如【0x4000】—【0x2000】-0x34。 三. 指针与数组 1.  int arr[10]; int * pr; pr=arr; // 等价于pr=&arr[0]; 这样的话,*(pr+1)==arr[1]; *(pr+2)==arr[2]; *(arr+3)==arr[3]; *(arr+4)==arr[4]; 或者 pr[0],pr[1]….代表 arr[0],arr[1]….. 可以*pr++ (等价于*(pr++)),来访问所有数组元素,而*arr++是不行的。因为

12、arr是常量,不能++运算 2.  char * s1 char code str[]=”abcdefg” s1=str; 3.  char *s1=”abcdefg”; 四. 指针与结构体 1. typedef struct _data_str { unsigned int DATA1[10]; unsigned int DATA2[10]; unsigned int DATA3[10]; unsigned int DATA4[10]; unsigned int DATA5[10]; unsigned int DATA6[10]; unsigned int D

13、ATA7[10]; unsigned int DATA8[10]; }DATA_STR; //开辟一个外RAM空间,确保这个空间够装你所需要的 xdata uchar my_data[MAX_STR] _at_ 0x0000; DATA_STR *My_Str; My_Str=(DATA_STR*)my_data; //把你的结构体指针指向这个数组的开头 以后的操作就这样: My_Str->DATA1[0]=xxx; My_Str->DATA1[1]=xxx; 那么你的变量就自然放到XDATA中去了. 注意定义的my_data[MAX_STR],不能随便被操作,它只是开始

14、的时候用来开辟内存用的. 2.  struct student { char name[20]; int num; }stu1,stu2; 3.  struct student { char name[20]; int num; }; struct student stu1,stu2; struct student *p; p=&stu1; 访问成员方法: A. stu1.num B. (*p).num; //因为“.”的优先级高于“*”所以要加括号。 C. P->num; 4.  struct student stu[10]; struct stu

15、dent * p; p=stu; (责任编辑:admin) 1. 使用指针 采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。例如: #define uchar unsigned char #define uint unsigned int void test_memory(void) {     uchar idata ivar1; uchar xdata *xdp;         /*定义一个指向XDATA存储器空间的指针*/ char data *dp;                      /*定义一个指向DATA存储器空间的指针*/ uc

16、har idata *idp;         /*定义一个指向IDATA存储器空间的指针*/ xdp=0x1000;           /*XDATA指针赋值,指向XDATA存储器地址1000H处*/ *xdp=0x5A;           /*将数据5AH送到XDATA的1000H单元*/ dp=0x61;                 /*DATA指针赋值,指向DATA存储器地址61H处*/ *dp=0x23;                 /*将数据23H送到DATA的61H单元*/ idp=&ivar1;            /*idp指向IDATA区变量ivar

17、1*/ *idp=0x16;              /*等价于ivar1=0x16*/ } 2. 使用C51运行库中预定义宏 C51编译器提供了一组宏定义用来对80C51系列单片机的CODE、DATA、PDATA和XDATA空间进行绝对地址访问。函数原型如下: #define CBYTE((unsigned char volatile *)0x50000L) #define DBYTE((unsigned char volatile *)0x40000L) #define PBYTE((unsigned char volatile *)0x30000L) #define X

18、BYTE((unsigned char volatile *)0x20000L)   #define CWORD((unsigned int volatile *)0x50000L) #define DWORD((unsigned int volatile *)0x40000L) #define PWORD((unsigned int volatile *)0x30000L) #define XWORD((unsigned int volatile *)0x20000L) 这些函数原型放在absacc.h文件中。 CBYTE以字节形式对CODE区寻址,DBYTE以字节形式对DAT

19、A区寻址,PBYTE以字节形式对PDATA区寻址,XBYTE以字节形式对XDATA区寻址,CWORD以字形式对CODE区寻址,DWORD以字形式对DATA区寻址,PWORD以字形式对PDATA区寻址,XWORD以字形式对XDATA区寻址。例如: #include #include #define uchar unsigned char #define uint unsigned int void main(void)    {       uint ui_var1;       uchar uc_var1;       ui_var1 =

20、 XWORD [0x0002];     /*访问外部 RAM 0004H~0005H地址的内容*/       uc_var1 = XBYTE [0x0002];      /*访问外部 RAM 0002H地址的内容*/       ……       while(1); } 需要注意的是,ui_var1在外部存储器区访问0x0004。通过使用#define预处理器命令,可采用其他符号定义绝对地址。 3. 使用C51扩展关键字 _at_ 使用_at_对指定的存储器空间的绝对地址进行定位,一般格式如下: [存储器类型] 数据类型 标识符 _at_ 常数   其中,存储器

21、类型为idata、data、xdata等C51能识别的数据类型,如果省略该选项,则按编译模式SMALL、COMPAC或TLARGE规定的默认存储器类型确定变量的存储器空间;数据类型除了可用int、long、float等基本类型外,还可采用数组、结构等复杂数据类型;常数规定变量的绝对地址,必须位于有效的存储器空间之内;使用_at_定义的变量只能为全局变量。例如: uchar xdata xram[0x8000] _at_ 0x0000;           /*在外部RAM空间0000H处定义了一个一维数组 变量xram,数组的元素个数为32768(0x8000)*/ struct bir

22、thdate{    int year;  uchar month, day; } idata struct birthdate Hans _at_ 0x60;              /*结构变量Hans定位于IDATA空间地址0x60 */       5.5.5  中断服务程序 80C51的中断系统十分重要,C51编译器允许在C语言源程序中声明中断和编写中断服务程序,从而减轻了采用汇编程序编写中断服务程序的繁琐程度。通过使用interrupt关键字来实现。定义中断服务程序的一般格式如下: void 函数名( ) interrupt n [using m] 关键字i

23、nterrupt后面的n是中断号,n的取值范围:0~31。编译程序从8n+3处产生中断向量,即在程序存储器8n+3地址处形成一条长跳转指令,转向中断号n的中断服务程序。中断号对应着IE寄存器中的使能位,即:IE寄存器中的0位对应着外部中断0,相应的外部中断0的中断号是0。中断号0~4对应中断源的关系如表所示。   中断号和中断源的对应关系   using m指明该中断服务程序所对应的工作寄存器组,取值范围:0~3。指定工作寄存器组的缺点是所有被中断调用的过程都必须使用同一个寄存器组,否则参数传递会发生错误。通常不设定using m,除非保证中断程序中未调用其他子程序。 使用C51

24、编写中断服务程序,程序员无需关心ACC、B、DPH、DPL、PSW等寄存器的保护,C51编译器会根据上述寄存器的使用情况在目标代码中自动增加压栈和出栈。 C51具有ANSI C的所有标准数据类型。 其基本数据类型包括:char、int、short、long、float和double,对C51编译器来说,short类型和int类型相同,double类型和float类型相同。整型和长整型的符号位字节在最低的地址中。 除此之外,为了更加有利地利用80C51的结构,C51还增加了一些特殊的数据类型,包括bit、sfr、sfr16、sbit。 1. char字符类型 char类型的长度是1B,

25、通常用于定义处理字符数据的变量或常量。分无符号字符类型unsigned char和有符号字符类型signed char,默认值为signed char类型。unsigned char类型用字节中所有的位表示数值,可以表达的数值范围是0~255。signed char类型用字节中最高位表示数据的符号,0表示正数,1表示负数,负数用补码表示,能表示的数值范围是-128~+127。unsigned char常用于处理ASCII字符或用于处理小于或等于255的整型数。 正二进制数的补码与原码相同,负二进制数的补码等于它的绝对值按位取反后加1。 2. int整型 int整型长度为2B,用于存放一

26、个双字节数据。分有符号int整型数signed int和无符号int整型数unsigned int,默认值为signed int类型。signed int表示的数值范围是-32768~+32767,字节中最高位表示数据的符号,0表示正数,1表示负数。unsigned int表示的数值范围是0~65535。 3. long长整型 long长整型长度为4B,用于存放一个4B数据。分有符号long长整型signed long和无符号long长整型unsigned long,默认值为signed long类型。signed int表示的数值范围是-2147483648~+2147483647,字节

27、中最高位表示数据的符号,0表示正数,1表示负数。unsigned long表示的数值范围是0~4294967295。 4. float浮点型 float浮点型在十进制中具有7位有效数字,是符合IEEE-754标准(32)的单精度浮点型数据,占用4B。具有24位精度。 5. *指针型 指针型本身就是一个变量,在这个变量中存放的指向另一个数据的地址。这个指针变量要占据一定的内存单元,对不同的处理器长度也不尽相同,在C51中它的长度一般为1~3个字节。 6. bit位标量 bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。它的值是一

28、个二进制位,不是0,就是1,类似一些高级语言中的Boolean类型中的True和False。 7. sfr特殊功能寄存器 sfr也是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfr P1 = 0x90这一句定义P1为P1端口在片内的寄存器,在后面的语句中可以用P1 = 255(对P1端口的所有引脚置高电平)之类的语句操作特殊功能寄存器。  8. sfr16 16位特殊功能寄存器 sfr16用于定义存在于80C51单片机内部RAM的16位特殊功能寄存器。sfr16型数据占用2个内存单元,取值范围为0~65535,如定时器T

29、0和T1。通过名字或地址引用的sfr16地址必须大于80H。 9. sbit可寻址位 sbit同位是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。 在80C51单片机系统中,经常要访问特殊功能寄存器中的某些位,用关键字sbit定义可位寻址的特殊功能寄存器的位寻址对象。 定义方法有如下三种: (1)sbit 位变量名 = 位地址 将位的绝对地址赋给位变量,位地址必须位于0x80H~0xFF之间。 (2)sbit 位变量名 = 特殊功能寄存器名^位位置 当可寻址位位于特殊功能寄存器中时,可采用这种方法。位位置是一个0~7之间的常

30、数。 (3)sbit 位变量名 = 字节地址^位位置 这种方法是以一个常数(字节地址)作为基地址,该常数必须在0x80H~0xFF之间。位位置是一个0~7之间的常数。 80C51单片机中的特殊功能寄存器和特殊功能寄存器可寻址位,已被预先定义放在文件reg51.h中,在程序的开头只需加上#include或#include即可。 另外,sbit还可访问80C51单片机片内20H~2FH范围内的位对象。C51编译器提供了一个bdata存储器类型,允许将具有bdata类型的对象放入80C51单片机片内可位寻址区。   sbit和bit的区别:sbit定义

31、特殊功能寄存器中的可寻址位;而bit则定义了一个普通的位变量,一个函数中可包含bit类型的参数,函数返回值也可为bit类型。 5.5.3  变量的存储种类和存储器类型 变量是一种在程序执行过程中,其数值不断变化的量。C51规定变量必须先定义后使用。C51对变量的进行定义的格式如下: [存储种类] 数据类型 [存储器类型] 变量名表 其中,存储种类和存储器类型是可选项。 1. 存储种类 存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有四种,分别为:自动(auto)、外部(extern)、静态(static)和寄存器(register)。 使用存储种类说明符auto定义的

32、变量称为自动变量。 自动变量作用范围在定义它的函数体或复合语句内部,在定义它的函数体或复合语句被执行时,C51才为该变量分配内存空间,当函数调用结束返回或复合语句执行结束时,自动变量所占用的内存空间被释放,这些内存空间又可被其他的函数体或复合语句使用。可见使用自动变量能最有效地使用80C51单片机内存。定义变量时,如果省略存储种类,则该变量默认为自动(auto)变量。 由于80C51单片机访问片内RAM速度最快,通常将函数体内和复合语句中使用频繁的变量放在片内RAM中,且定义为自动变量,可有效地利用片内有限的RAM资源。 使用外部种类存储符extern定义的变量称为外部变量。 在一个函

33、数体内,要使用一个已在该函数体外或别的程序模块文件中定义过的外部变量时,该变量在本函数体内要用extern说明。外部变量被定义后,即分配了固定的内存空间,在程序的整个执行时间内都是有效的。通常将多个函数或模块共享的变量定义为外部变量。外部变量是全局变量,在程序执行期间一直占有固定的内存空间。当片内RAM资源紧张时,不建议将外部变量放在片内RAM。 使用存储种类说明符static定义的变量称为静态变量。 静态变量分为局部静态变量和全局静态变量。 局部静态变量是在两次函数调用之间仍能保持其值的局部变量。有些程序要求在多次调用之间仍然保持变量的值,使用自动变量无法作用到这一点。使用全局变量有时

34、会带来意外的副作用,这时可采用局部静态变量。 使用存储种类说明符register定义的变量称为寄存器变量。 80C51访问寄存器的速度最快,通常将使用频率最高的那些变量定义为寄存器变量。C51编译器能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户无需专门声明。 2. 存储器类型 定义变量时,除了说明存储种类外,还允许说明变量的存储器类型。存储器类型和存储种类是完全不同的概念,存储器类型指明该变量所处的单片机的内存空间。   如果在变量定义时省略了存储器类型标识符,C51编译器会选择默认的存储器类型。默认的存储器类型由SMALL、COMPACT和LARGE存储模式指

35、令决定。   1)DATA区 对DATA区的寻址是最快的,所以应该把使用频率高的变量放在DATA区,由于空间有限,必须注意使用DATA区,DATA区除了包含程序变量外,还包含了堆栈和寄存器组DATA区。 unsigned char data system_status=0; unsigned int data unit_id[2]; char data inp_string[16]; float data outp_value; mytype data new_var; 在SMALL存储模式下,未说明存储器类型时,变量默认被定位在DATA区。标准变量和用户自定义变量都可以存储

36、在DATA区,只要不超过DATA区的范围。因为C51使用默认的寄存器组传递参数,至少失去了8B。另外要定义足够大的堆栈空间,当内部堆栈溢出的时候,程序会产生莫名其妙的错误,实际原因是80C51系列单片机没有硬件报错机制,堆栈溢出只能以这种方式表示出来。 2)BDATA区 当在DATA区的位寻址区定义变量,这个变量就可进行位寻址,并且声明位变量。这对状态寄存器来说十分有用,因为它可以单独使用变量的每一位,而不一定要用位变量名引用位变量。下面是一些在BDATA区中声明变量和使用位变量的例子。 unsigned char bdata status_byte; unsigned int bda

37、ta status_word; unsigned long bdata status_dword; sbit stat_flag=status_byte^4; if(status_word^15){ ……} stat_flag=1; 编译器不允许在BDATA区中定义float和double类型的变量,如果想对浮点数的每位寻址,可以通过包含float和long的联合实现。 typedef union{                              /*定义联合类型*/ unsigned long lvalue;                       /*长整型3

38、2位*/ float fvalue;                                     /*浮点数32位*/ }bit_float;                                       /*联合名*/ bit_float bdata myfloat;                  /*在BDATA区中声明联合*/ sbit float_ld=myfloat.lvalue^31;    /*定义位变量名*/ 3)IDATA区 IDATA区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。在寄存器中设置8位地址进行间接寻址,与外

39、部存储器寻址比较,它的指令执行周期和代码长度都比较短。 unsigned char idata system_status=0; unsigned int idata unit_id[2]; char idata inp_string[16]; float idata outp_value; 4)PDATA和XDATA区 在这两个区声明变量和在其他区的语法是一样的,PDATA区只有256B,而XDATA区可达65536B,举例如下。 unsigned char xdata system_status=0; unsigned int pdata unit_id[2]; char

40、 xdata inp_string[16]; float pdata outp_value; 对PDATA和XDATA的操作是相似的,对PDATA区寻址比对XDATA区寻址要快,因为对PDATA区寻址只需要装入8位地址,而对XDATA区寻址需装入16位地址。所以尽量把外部数据存储在PDATA区中,对PDATA和XDATA寻址要使用MOVX指令,需要2个处理周期。 5)CODE区 CODE区即80C51的程序代码区,所以代码区的数据是不可改变的,80C51的代码区不可重写。一般代码区中可存放数据表,跳转向量和状态表,对CODE区的访问和对XDATA区的访问的时间是一样的,代码区中的对象在

41、编译时初始化,否则就得不到想要的值。下面是代码区的声明例子。 unsigned int code unit_id[2]={0x1234, 0x89ab}; unsigned char code uchar_data[16] ={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15}; 3. 存储模式 C51编译器允许采用三种存储模式:小编译模式SMALL、紧凑编译模式COMPACT、大编译模式LARGE。一个变量的存储器模式确定了变量在内存中的地址空间。在SMALL模式下,该变

42、量在80C51单片机的内部RAM中;在COMPACT和LARGE模式下,该变量在80C51单片机的外部RAM中。同样一个函数的存储器模式确定了函数的参数和局部变量在内存中的地址空间。在SMALL模式下,函数的参数和局部变量在80C51单片机的内部RAM中;在COMPACT和LARGE模式下,函数的参数和局部变量在80C51单片机的外部RAM中。 下面这个例子说明了存储模式的定义方法。 【例5.15】  变量和函数的存储模式 #pragma small                       /*默认存储器类型为80C51片内直接寻址RAM*/ char data i,j,k;   

43、                      /*在80C51片内直接寻址RAM中定义了3个变量,默认为自 动变量*/ char i,j,k;                                /*未指明存储模式,由#pragma small决定,与前一句完全等价*/ int xdata m, n;                              /*在80C51片外RAM中定义了2个自动变量*/ static char m, n;                          /*在80C51片内直接寻址RAM中定义了2个静态变量*/ unsigned ch

44、ar xdata ram[128];        /*在80C51片外RAM中定义了大小为128B的数组变量*/ int func1(int i, int j) large               /*指定 large 模式*/ {    return(i+j); } int func2(int i, int j)                      /*未指明存储模式, 按默认的SMALL模式*/ {    return(i-j); } 不同的存储器类型访问速度是不一样的,如: unsigned char data var1;                /

45、SMALL模式,var1被定位在DATA区*/                                                         /*即80C51片内直接寻址RAM*/ unsigned char pdata var1;              /*COMPACT模式,var1被定位在PDATA区*/                                                         /*即80C51片外按页面间接寻址RAM*/ unsigned char xdata var1;               /*LARGE模

46、式,var1被定位在XDATA区*/                                                         /*即80C51片外间接寻址RAM*/ 在SMALL模式下,var1被定位在DATA区,经C51编译器编译后,采用内部RAM直接寻址方式访问速度最快;在COMPACT模式下,var1被定位在PDATA区,经C51编译器编译后,采用外部RAM间接寻址方式访问速度较快;在LARGE模式下,var1被定位在XDATA区,经C51编译器编译后,采用外部RAM间接寻址方式访问速度最慢。为了提高系统运行速度,建议在编写源程序时,把存储模式设定为SMALL

47、再在程序中把XDATA、PDATA和IDATA等类型变量进行专门声明。 5.5.4  绝对地址的访问 1. 使用指针 采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。例如: #define uchar unsigned char #define uint unsigned int void test_memory(void) {     uchar idata ivar1; uchar xdata *xdp;         /*定义一个指向XDATA存储器空间的指针*/ char data *dp;                      /*定义一

48、个指向DATA存储器空间的指针*/ uchar idata *idp;         /*定义一个指向IDATA存储器空间的指针*/ xdp=0x1000;           /*XDATA指针赋值,指向XDATA存储器地址1000H处*/ *xdp=0x5A;           /*将数据5AH送到XDATA的1000H单元*/ dp=0x61;                 /*DATA指针赋值,指向DATA存储器地址61H处*/ *dp=0x23;                 /*将数据23H送到DATA的61H单元*/ idp=&ivar1;          

49、  /*idp指向IDATA区变量ivar1*/ *idp=0x16;              /*等价于ivar1=0x16*/ } 2. 使用C51运行库中预定义宏 C51编译器提供了一组宏定义用来对80C51系列单片机的CODE、DATA、PDATA和XDATA空间进行绝对地址访问。函数原型如下: #define CBYTE((unsigned char volatile *)0x50000L) #define DBYTE((unsigned char volatile *)0x40000L) #define PBYTE((unsigned char volatile *

50、)0x30000L) #define XBYTE((unsigned char volatile *)0x20000L)   #define CWORD((unsigned int volatile *)0x50000L) #define DWORD((unsigned int volatile *)0x40000L) #define PWORD((unsigned int volatile *)0x30000L) #define XWORD((unsigned int volatile *)0x20000L) 这些函数原型放在absacc.h文件中。 CBYTE以字节形式对C

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服