为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > XBYTE

XBYTE

2013-01-09 35页 doc 230KB 20阅读

用户头像

is_326155

暂无简介

举报
XBYTEXBYTE The XBYTE macro accesses individual bytes in the external data memory of the 8051. You may use this macro in your programs as follows: #include /* Include Macro Definitions */ . . . rval = XBYTE [0x0002]; XBYTE [0x0002] = 57; . . . This example ...
XBYTE
XBYTE The XBYTE macro accesses individual bytes in the external data memory of the 8051. You may use this macro in your programs as follows: #include /* Include Macro Definitions */ . . . rval = XBYTE [0x0002]; XBYTE [0x0002] = 57; . . . This example reads and writes the contents of the byte in external data memory at address 0002h. The range of valid index values for this macro is 0-65535.   http://www.keil.com/support/man/docs/c51/c51_xbyte.htm           上面的是在keil的help里ctrl+c来的,以前在论坛里看到过有人问如何用c语言实现定位存储,呵呵,当时还说不可能呢!现在在查找using的时候,无意中看到了XBYTE,点中看看,居然有大发现啊!           百度结果:这个主要是在用C51的P0,P2口做外部扩展时使用,其中XBYTE [0x0002],P2口对应于地址高位,P0口对应于地址低位。一般P2口用于控制信号,P0口作为数据通道。         如:P2.7接WR,P2.6接RD,P2.5接CS,那么就可以确定个外部RAM的一个地址,想往外部RAM的一个地址写一个字节时,地址可以定为XBYTE [0x4000],其中WR,CS为低,RD为高,那就是高位的4,当然其余的可以根据情况自己定,然后通过 XBYTE [0x4000] = 57。这赋值语句,就可以把57写到外部RAM的0x4000处了,此地址对应一个字节。   一下摘自论坛网友的问答: 问: 在一般的读写外部RAM的程序中,经常看到这样的句子:     XBYTE[address]=data   写数据     data=XBYTE[address]   读数据 但是我想问的是,为什么用了XBYTE后,就不用顾及其时序了呢? 就是说,读写数据的时候,WR和RD怎么都不用用程序去控制了呢? 参考了很多读写外部RAM的程序,都找不到其控制WR和RD控制线的语句 哪位大侠能帮忙解释一下这是为什么嘛? 最好还能说说XBYTE具体的用法..... 答: 外部总线, 1外部总线由3组总线组成,数据 地址 控制,我们常常一般就叫他外部总线,既然是有3组不同的信号,那么他们是怎么协调工作的呢?一般情况CPU有特殊的外部数据访问指令如你这里讲51的MOVX指令(在C语言中他会编译成这个指令)在执行这个指令的时候3组线是协调工作 mov dptr,#1000h mov a,#55h movx @dptr,a 上面3调语句的C语言可以表示如下 #define  W_DATA  XBYTE[0x1000] W_DATA=0X55; 在使用外部总线的时候,数据 地址和控制信号是直接按照规定的时序输出高低电平的,所以不用你管,当然你必须要满足时序工作 一下摘自网友博客文章: 如何理解#define XBYTE ((unsigned char volatile xdata * 8051 特有的内存型态 code    以 MOVC @A+DPTR 读取的程序内存 data    可以直接存取的内部数据存储器 idata    以 Mov @Rn 存取的内部数据存储器 bdata    可以位寻址(Bit Addressable)的内部存储器 xdata    以 MOVX @DPTR 存取的外部数据存储器 pdata    以 MOVX @Rn 存取的外部数据存储器 特殊资料型态 bit    一般位(bit)变量 sbit    绝对寻址的位(bit)变量 语法 sbit    my_flag    =    location;    (location 范围从 0x00 ~ 0x7F) 范例 sbit    EA =    0xAF; 或是配合 bdata 宣告的位(bit)变量 char    bdata        my_flags; sbit    flag0 =      my_flags ^ 0; (注意 sbit 前不可以加 static) sfr    特殊功能缓存器(Special Function Register) 语法 sfr    my_sfr    =    location;    (location 范围从 0x80 ~ 0xFF) 范例 sfr    P0    =    0x80; 指定绝对地址的变量 在单一模块内可以使用下面的语法宣告 [memory_space]    type    variable_name    _at_    location 范例 pdata        char    my_pdata    _at_    0x80; 如果该变量必须为多个模块所使用(Global Variable)则以 抽象指针(Abstract Pointer)的方式在标头档(Header File)定义较为方便。 #define    variable_name    *((data_type *)        location) 范例 #define    my_pdata    *((char pdata *)    0x80) (注意 char 与 pdata 的顺序) ABSACC.H 提供了下列方便的宏(Macro)定义。 #define CBYTE ((unsigned char volatile code *) 0) #define DBYTE ((unsigned char volatile data *) 0) #define PBYTE ((unsigned char volatile pdata *) 0) #define XBYTE ((unsigned char volatile xdata *) 0) #define CWORD ((unsigned int volatile code *) 0) #define DWORD ((unsigned int volatile data *) 0) #define PWORD ((unsigned int volatile pdata *) 0) #define XWORD ((unsigned int volatile xdata *) 0) 隐藏的初始化程序 80C51 在电源重置后(Power On Reset)所执行的第一个程序模块并不是使用者的主程序 main(),而是一个隐藏在 KEIL-C51 链接库中称为 startup.a51 的程序模块。 startup.a51 的主要工作是把包含 idata、xdata、pdata 在内的内存区块清除为 0,并 且初始化递归指针。接着 startup.a51 被执行的仍然是一个隐藏在 KEIL-C51 标准链接库 中称为 init.a51 的程序模块。而 init.a51 的主要工作则是初始化具有非零初始值设定的 变量。 在完成上述的初始化程序之后,80C51 的控制权才会交给 main() 开始执行使用者的程序。 #define XBYTE ((unsigned char volatile xdata *) 0) 定义    XBYTE 为 指向 xdata 地址空间unsigned char 数据类型的指针,指针值为0 这样,可以直接用XBYTE[0xnnnn]或*(XBYTE+0xnnnn)访问外部RAM了 XBYTE XBYTE 宏允许访问51 外部数据区的单个字节可以如下使用 rval = XBYTE[0x0002]; XBYTE[0x002] = 57; 读或写外部数据存储区地址0002h 的字节内容 XWORD XWORD 宏允许访问51 外部数据区的单个字可以如下使用 rval = XWORD[0x0002]; XWORD[0x002] = 57; 读或写外部数据存储区地址0004h 2×sizeof(unsigned int)=4 的字内容 1. 绝对宏: 在程序中,用“#include”即可使用其中定义的宏来访问绝对地址,包括CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD 具体使用可看一看absacc.h便知,例如: rval=CBYTE[0x0002];指向程序存贮器的0002h地址 rval=XWORD[0x0002];指向外RAM的0002h地址 2. _at_关键字 直接在数据定义后加上_at_ const即可,但是注意: (1)绝对变量不能被初使化; (2)bit型函数及变量不能用_at_指定。 例如: idata struct link list _at_ 0x40;指定list结构从40h开始。 xdata char text[25b] _at_0xE000;指定text数组从0E000H开始 提示:如果外部绝对变量是I/O端口等可自行变化数据,需要使用volatile关键字进行描述,请参考absacc.h。   查看文章   51单片机C语言编程中对单片机绝对地址访问的两种 2009-04-17 14:27    在进行8051单片机应用系统程序时,编程都往往少不了要直接操作系统的各个存储器地址空间。C51程序经过编译之后产生的目标代码具有浮动地址,其绝对地址必须经过BL51连接定位后才能确定。为了能够在C51程序中直接对任意指定的存储器地址进行操作,可以采用扩展关键字“at”、指针、预定义以及连接定位控制命令。 在这些方法中,本人认为最简单而有效的方法是用“ _at_ ”关键字来对指定变量存储器空间绝对地址来指定。一般格式如下:                              [存储器类型]           数据类型 标识符            _at_            地址常数             其中:                      存储器类型                为idata、data、xdata等C51能够识别的所有类型,最好不要省略。                      数据类型                   可以用int、long、float等基本类型,当然也可以用数组、结构等复杂数据类型             ,                本人认为一般用unsigned int 就可以解决很多问题了。                     标识符                      就是要定义的变量名,编程者自己决定                    地址常数                    就是要直接操作的存储器的绝对地址,必须位于有效的存储器空间之内。 注意:不能对变量进行初始化,只能是全局变量,一般不要轻易用,免得出错。 举例:                      xdata            unsigned int             addr1            _at_ 0x8300; 另有一种方法就是要用到一个头文件absacc.h,也不是很难,举个例说明一下就会明白:                #include                 XBYTE[0x8300]=0;              /*向外部存储器(XDATA)地址0x8300写0 本人强烈建议用at,这样可能会更好些,还有一点就是不能乱用,因为有些存储器空间不能随便占用,C51编译器已经做其它的用了,而且有些空间单片机本身就做了很重要的作用,如果乱用,很容易出错. 类别:c语言 | | 添加到搜藏 | 分享到i贴吧 | 浏览(64) | 评论 (0)   上一篇:C语言嵌入式系统编程修炼之软件...    下一篇:C程序的优化   相关文章: • 51单片机输出PWM的两种方法                最近读者: 登录后,您就出现在这里。 转自网络)关于C51的XBYTE 工作 2009-07-14 17:38:05 阅读196 评论0 字号:大中小 XBYTE The XBYTE macro accesses individual bytes in the external data memory of the 8051. You may use this macro in your programs as follows: #include     /* Include Macro Definitions */ . . . rval = XBYTE [0x0002]; XBYTE [0x0002] = 57; . . .This example reads and writes the contents of the byte in external data memory at address 0002h. The range of valid index values for this macro is 0-65535.   http://www.keil.com/support/man/docs/c51/c51_xbyte.htm           上面的是在keil的help里ctrl+c来的,以前在论坛里看到过有人问如何用c语言实现定位存储,呵呵,当时还说不可能呢!现在在查找using的时候,无意中看到了XBYTE,点中看看,居然有大发现啊!           百度结果:这个主要是在用C51的P0,P2口做外部扩展时使用,其中XBYTE [0x0002],P2口对应于地址高位,P0口对应于地址低位。一般P2口用于控制信号,P0口作为数据通道。         如:P2.7接WR,P2.6接RD,P2.5接CS,那么就可以确定个外部RAM的一个地址,想往外部RAM的一个地址写一个字节时,地址可以定为XBYTE [0x4000],其中WR,CS为低,RD为高,那就是高位的4,当然其余的可以根据情况自己定,然后通过 XBYTE [0x4000] = 57。这赋值语句,就可以把57写到外部RAM的0x4000处了,此地址对应一个字节。   一下摘自论坛网友的问答: 问: 在一般的读写外部RAM的程序中,经常看到这样的句子:     XBYTE[address]=data   写数据     data=XBYTE[address]   读数据 但是我想问的是,为什么用了XBYTE后,就不用顾及其时序了呢? 就是说,读写数据的时候,WR和RD怎么都不用用程序去控制了呢? 参考了很多读写外部RAM的程序,都找不到其控制WR和RD控制线的语句 哪位大侠能帮忙解释一下这是为什么嘛? 最好还能说说XBYTE具体的用法..... 答: 外部总线, 1外部总线由3组总线组成,数据 地址 控制,我们常常一般就叫他外部总线,既然是有3组不同的信号,那么他们是怎么协调工作的呢?一般情况CPU有特殊的外部数据访问指令如你这里讲51的MOVX指令(在C语言中他会编译成这个指令)在执行这个指令的时候3组线是协调工作 mov dptr,#1000h mov a,#55h movx @dptr,a 上面3调语句的C语言可以表示如下 #define  W_DATA  XBYTE[0x1000] W_DATA=0X55; 在使用外部总线的时候,数据 地址和控制信号是直接按照规定的时序输出高低电平的,所以不用你管,当然你必须要满足时序工作 一下摘自网友博客文章: 如何理解#define XBYTE ((unsigned char volatile xdata * 8051 特有的内存型态 code    以 MOVC @A+DPTR 读取的程序内存 data    可以直接存取的内部数据存储器 idata    以 Mov @Rn 存取的内部数据存储器 bdata    可以位寻址(Bit Addressable)的内部存储器 xdata    以 MOVX @DPTR 存取的外部数据存储器 pdata    以 MOVX @Rn 存取的外部数据存储器 特殊资料型态 bit    一般位(bit)变量 sbit    绝对寻址的位(bit)变量 语法 sbit    my_flag    =    location;    (location 范围从 0x00 ~ 0x7F) 范例 sbit    EA =    0xAF; 或是配合 bdata 宣告的位(bit)变量 char    bdata        my_flags; sbit    flag0 =      my_flags ^ 0; (注意 sbit 前不可以加 static) sfr    特殊功能缓存器(Special Function Register) 语法 sfr    my_sfr    =    location;    (location 范围从 0x80 ~ 0xFF) 范例 sfr    P0    =    0x80; 指定绝对地址的变量 在单一模块内可以使用下面的语法宣告 [memory_space]    type    variable_name    _at_    location 范例 pdata        char    my_pdata    _at_    0x80; 如果该变量必须为多个模块所使用(Global Variable)则以 抽象指针(Abstract Pointer)的方式在标头档(Header File)定义较为方便。 #define    variable_name    *((data_type *)        location) 范例 #define    my_pdata    *((char pdata *)    0x80) (注意 char 与 pdata 的顺序) ABSACC.H 提供了下列方便的宏(Macro)定义。 #define CBYTE ((unsigned char volatile code *) 0) #define DBYTE ((unsigned char volatile data *) 0) #define PBYTE ((unsigned char volatile pdata *) 0) #define XBYTE ((unsigned char volatile xdata *) 0) #define CWORD ((unsigned int volatile code *) 0) #define DWORD ((unsigned int volatile data *) 0) #define PWORD ((unsigned int volatile pdata *) 0) #define XWORD ((unsigned int volatile xdata *) 0) 隐藏的初始化程序 80C51 在电源重置后(Power On Reset)所执行的第一个程序模块并不是使用者的主程序 main(),而是一个隐藏在 KEIL-C51 标准链接库中称为 startup.a51 的程序模块。 startup.a51 的主要工作是把包含 idata、xdata、pdata 在内的内存区块清除为 0,并 且初始化递归指针。接着 startup.a51 被执行的仍然是一个隐藏在 KEIL-C51 标准链接库 中称为 init.a51 的程序模块。而 init.a51 的主要工作则是初始化具有非零初始值设定的 变量。 在完成上述的初始化程序之后,80C51 的控制权才会交给 main() 开始执行使用者的程序。 #define XBYTE ((unsigned char volatile xdata *) 0) 定义    XBYTE 为 指向 xdata 地址空间unsigned char 数据类型的指针,指针值为0 这样,可以直接用XBYTE[0xnnnn]或*(XBYTE+0xnnnn)访问外部RAM了 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xb_crazyman/archive/2008/10/15/3081731.aspx   知道的: 问: 请大家看下面这段程序# define ADCOM XBYTE[ 0xff7c ] /* 使A0=0 ,R/C=0, CS=0 */# define ADLO XBYTE [ 0xff7f ] /* 使 R/C =1,A0=1, CS=0 */# define ADHI XBYTE [ 0xff7d ] /* 使R/C=1,A0=0,CS =0 */本人一直理解是ADCOM是一个指针,指针指向的地址为0xff7c,完事可以通过对ADCOM的操作来更改地址0xff7c内变量的值,但是为何同时在宏定义后,相应的注释里会是同时初始化某值的作用呢? 问题补充: 那在问下像0xff7c这些地址,是应该怎样和外部电路相配合呢?是说地址可以随便写么?   答:XBYTE定义的是外部地址,这样才能和接到你的IO口上的器件通信 关于你的不充问题: 你把0xff7c展开成二进制形式就全明白了,0xff7c的二进制是:1111,1111,0111,1100 再结合后面的注释可知外部电路管脚的对应关系为: CS——P1.7 A0——P1.1 R/C——P1.0 用XBYTE定义的目的是将外部电路不同的功能编程不同的地址而已 这样就可以在程序里面通过直接对地址附置,就能使外部电路实现需要的功能,这样做还有一个好处就是在编译的时候会产生 MOVX 指令,这样可以操作WR和RD引脚,以实现特定的功能 至于用XBYTE定义的地址是多少就得根据实际的外围电路的连接来确定,不是随便写的 如何理解XBYTE(转载) (2009-11-05 17:04:46) 转载 标签: 单片机 it 8051 特有的内存型态   code    以 MOVC @A+DPTR 读取的程序内存 data    可以直接存取的内部数据存储器 idata    以 Mov @Rn 存取的内部数据存储器 bdata    可以位寻址(Bit Addressable)的内部存储器 xdata    以 MOVX @DPTR 存取的外部数据存储器 pdata    以 MOVX @Rn 存取的外部数据存储器   特殊资料型态  bit    一般位(bit)变量  sbit    绝对寻址的位(bit)变量  语法 sbit    my_flag    =    location;    (location 范围从 0x00 ~ 0x7F)  范例 sbit    EA =         0xAF;  或是配合 bdata 宣告的位(bit)变量  char    bdata        my_flags; sbit    flag0 =              my_flags ^ 0;   (注意 sbit 前不可以加 static)   sfr    特殊功能缓存器(Special Function Register)   语法 sfr    my_sfr    =    location;    (location 范围从 0x80 ~ 0xFF)   范例 sfr    P0    =    0x80;   指定绝对地址的变量     在单一模块内可以使用下面的语法宣告   [memory_space]    type    variable_name    _at_    location   范例 pdata        char    my_pdata    _at_    0x80;   如果该变量必须为多个模块所使用(Global Variable)则以   抽象指针(Abstract Pointer)的方式在标头档(Header File)定义较为方便。   #define    variable_name    *((data_type *)        location)   范例 #define    my_pdata    *((char pdata *)    0x80)   (注意 char 与 pdata 的顺序)   ABSACC.H 提供了下列方便的宏(Macro)定义。   #define CBYTE ((unsigned char volatile code *) 0) #define DBYTE ((unsigned char volatile data *) 0) #define PBYTE ((unsigned char volatile pdata *) 0) #define XBYTE ((unsigned char volatile xdata *) 0) #define CWORD ((unsigned int volatile code *) 0) #define DWORD ((unsigned int volatile data *) 0) #define PWORD ((unsigned int volatile pdata *) 0) #define XWORD ((unsigned int volatile xdata *) 0)   隐藏的初始化程序   80C51 在电源重置后(Power On Reset)所执行的第一个程序模块并不是使用者的主程序 main(),而是一个隐藏在 KEIL-C51 标准链接库中称为 startup.a51 的程序模块。 startup.a51 的主要工作是把包含 idata、xdata、pdata 在内的内存区块清除为 0,并 且初始化递归指针。接着 startup.a51 被执行的仍然是一个隐藏在 KEIL-C51 标准链接库 中称为 init.a51 的程序模块。而 init.a51 的主要工作则是初始化具有非零初始值设定的 变量。   今天在51的头文件中碰到了如下语句: #define   Page        XBYTE[0X7000] 查相关资料: answer: xbyte[地址]=数据; 对XBYTE的解释: The XBYTE macro accesses individual bytes in the external data memory of the 8051. You may use this macro in your programs as follows: #include     /* Include Macro Definitions */ . . . rval = XBYTE [0x0002]; XBYTE [0x0002] = 57; . . . This example reads and writes the contents of the byte in external data memory at address 0002h. The range of valid index values for this macro is 0-65535. 其中利用宏定义文件absacc.h可以方便的对任何内存空间进行操作。   原来是对外部RAM的操作,XBYTE[0x7000]相当于一个地址而已 #define   Page        XBYTE[0X7000] 就是相当于定义外部寄存器Page,搞定!!! C语言之一 软件学习 2009-05-19 22:39:48 阅读8 评论0 字号:大中小 1、带参数与不带参数的宏定义 带参数:  #define NIL 0x80 不带参数:#define SQ(a,b) a*b   2、文件包含 #include /*在C中用双引用形式更保险,在C51中常用物是尖括弧形式*/   3、条件编译:#if  #elif  #else  #endif  #ifdef  #ifndef /*一般源程序中的所有程序行都参加编译,但有时希望对其中一部分内容在满足一定条件下才进行编译;选择不同的编译范围,产生不同的代码,提供通用性*/   4、#error:捕捉不可预料的编译条件      #if (myv!=0&&myv!=1)/*假定其值必为0或1*/      #error myv must be 1 or 0/*出错时显示*/      #endif   5、#pragma:用于在程序中向编译器传送各种编译控制命令      #pragma 编译命令序列      /*例:想按如下命令编译ex.c c51 ex.c debug cod large可用:*/      #pragma DB CD LA      #pragma disable   6、数据类型及长度: char        int            long      1:unsinged  0~255      0~65535        0~4294967295      2:signed    -128~127   -32768~32767   -2147483648~2147483647 指针:* 3字节位标量: sbit   7、特殊功能寄存器:sfr      16位特殊功能寄存器:sfr16 占2个内存单元,0~65535      可寻址位:sbit利用他可访问51单片机的内部RAM中的可寻址位或特殊功能寄存器中的可寻址位      sfr P0=0x80; /*将P0口的口地址定义为80H*/      sbit P0_1=P1^1;  /*将P0.1位定义为P1_1*/   8、数据存储类型      表1. C51数据存贮类型      ━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━      数据存贮类型  ┃ 与存贮空间的对应关系      ━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━      data           ┃ 直接寻址片内数据存贮区,访速度快      bdata          ┃ 可位寻址片内数据存贮区,允许位与字节混合访问      idata          ┃ 间接寻址片内数据存贮区,可访问片内全部RAM地址空间      pdata          ┃ 分页寻址片外数据存贮区(256字节)由MOVX @R0访问      xdata         ┃ 片外数据存贮区(64K),由MOVX @DPTR访问      code          ┃ 代码存贮区(64K),由MOVC @DPTR访问      ━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━   9、变量的存储类型定义      char data var      /*字符变量var被定义为data存贮类型,C51编译器将把该变量定位在51单片机片内数据区存贮区中*/      bit bdata flag      /*位变量flag被定义为bdata存贮类型,C51编译器将把该变量定位在51单片机片内数据区存贮区(RAM)中的位寻址区:20H--2FH*/   10、typedef:重新定义数据类型         typedef 已有数据类型 新的数据类型      typedef int word;       /*将word定义为整型*/      word i,j;              /*将i,j定义为整型*/   11、数组作为函数的参数 例:用数组作为函数的参数,计算两个不同长度的数组中所有元素的平均值 float average(array,n) {     int N; float array[ ]; int I; float aver,sum=array[0]; for(I=1;I工程
上我们在采集数据时一般要求精度达到5%%,大于这个值将认为无效。主要来自于随机干扰,下面就各种干扰的方法给出简单的去除方法: 1、白噪声:最重要的统计特性为平均值为0,可采取每路数据采集几次求平均的方法; 2、随机干扰:该点明显高于或低于附近正常采样值,故采取中值滤波法,即对被测信号连续采样M次,进行大小排序,取大小居中的1/3个采样值进行算术平均; 3、电源干扰:特点是有固定周期,故可采用定时采样求平均的方法。   13、  指针:可对内存地址直接操作       基于存贮器的指针以存贮器类为参量,它在编译时才被确定。因此为指针选择存贮器的方法可以省掉,这些指针的长度可为1个字节(idata *,data *,pdata *)或2个这节(code *,xdata *)。       char xdata *address; ADC0809具有8个模拟量输入通道,采用中断方式,在中断函数中读取8个通道的A/D转换值,分别存储在外部RAM的1000H~1007H单元。ADC0809端口地址为00F0H。 程序定义了两个指针变量* ADC和* ADCdata,分别指向ADC0809端口地址(00F0H)和外部RAM单元地址(1000H~1007H)       由*ADC=I送入通道数,启动ADC0809进行A/D转换,转换结束时产生INT1中断。在中断服务函数int1()中通过temp=*ADC和*ADCdata=temp;读取A/D转换结果并存到外部RAM中。  #include      unsigned int xdata *ADC; /*定义ADC0809端口指针*/      unsigned int xdata *ADCdata; /*定义ADC0809数据缓冲器指针*/      unsigned char I;      void main( )      {      ADC=0x00f0; /*定义端口地址和数据缓冲器地址*/      ADCdata=0x1000;      I=8; /* ADC0809有8个模拟输入通道*/      EA=1; EX1=1;IT1=1; /*开中断*/      *ADC=I; /*启动ADC0809*/      WHILE(I); /*等待8个通道A/D转换完*/      }      void int1() interrupt 2      {      unsigned char tmp;      temp=*ADC;         /*读取A/D转换结果*/      *ADCdata=temp;      /*结果值存到数据缓冲区*/      ADCdata++;          /*数据缓冲区地址加1*/      i—;      *ADC=I;             /*启动下一个模拟输入通道A/D转换*/      } 除了用指针变量来实现对内存地址的直接操作外,c51编译器还提供一组宏,该宏定义文件为:“absacc.h”,利用它可十分方便地实现对任何内存空间的直接操作,改写上面的程序:      #include      #include                /*包含绝对地址操作预定义头文件*/      #define ADC 0x00f0;      /*定义ADC0809端口地址*/      #define ADCdata 0X1000  /*定义数据缓冲器地址*/      unsigned char I;      void main( )      {      I=8;                    / *ADC0809有8个模拟输入通道*/      EA=1;ex1=1;it1=1;        / *开中断*/      XBYTE[ADC]=I;         /*启动0809 */      While(i);                /*等待8个通道转换完毕*/      } void int1() interrupt2  {      unsigned char tmp;      tmp=XBYTE[ADC];       /*读取A/D转换结果*/      i--;      XBYTE[ADCdata+I]=tmp;  /**结果值存储到数据缓冲器*/      XBYTE[ADC]=I;          /*启动下一个模拟输入通道A/D转换*/      }   两指针相减-----计算字符串的长度      #include      main() {      char *s=”abcdef”;      int strlen(char *s);      printf(“\n length of ‘%%s’=%%d\n”,s,strlen(s));      } int strlen(char *s) {      char *p=s;      while(*p!=’\0’)p++;      return(p-s);      } 结果为:length of ‘abcdef’=6注:不允许指针之间进行加,乘,除,移位,或屏蔽运算,也不允许用float类型数据与指针做加,减运算!抽象型指针:      ANSI新标准增加了一种“void * ”的指针类型,这是一种抽象型指针,即可以定义一个指针变量,但不指定该指针是指向哪种类型的数据的。在赋值时需进行强制类型转换:      Char *p1;      Void *p2;      P1=(char*)p2;   传统51MCU--AT89C51扩展ROM,RAM实验 默认分类 2009-08-07 13:10:01 阅读89 评论0 字号:大中小 51MCU内部有RAM,ROM,不同于8031。尽管如今的增强行51MCU的内部RAM,ROM可能已经很大的空间。但就技术而言,扩展RAM,ROM还是需要学会的。         对于不同的设计需求,扩展可能基于以下任何一种设计:         A,只扩展RAM         B,只扩展ROM         C,扩展ROM,RAM ****************************总线扩展时,P2口是否可用做普通IO口************************************    这种扩展是基于总线扩展的,所以,P0P2口就已经不可以再做它用了(有网友提供信息,总线扩展P2还可以做普通IO口用,有两种可能:1,P2口复用,如同P1利用373锁存器。2,在总线扩展时,只用到了低地址总线,P2口未用到。就作为普通IO口应用。由于技术还不到位,不做评论。) *******************************************扩展RAM****程序************************************************        扩展RAM,在程序中定义的xdata类型 XBYTE类型等地址范围在外部RAM的变量,对其读写的过程。用C51语言编写程序,且使用总线扩展的RAM,则时序电路不用考虑,WR RD等信号由编译器/硬件自动完成。 **************************************编译器设置*****************************************        内部RAM:0x00~~0xFF        外部RAM:0x0000~~0xFFFF        RAM的地址虽重复,但是两个RAM是没有关系的,所以不会造成干扰        使用了外部RAM,就在工程选项---off-chip xdata memory中设置 start:0x0000 size:0xFFFF(根据具体的RAM大小设置size)。 *******************************扩展RAM时的变量定位及连续读取问题*********************************        ROM,RAM的扩展时,需要用到变量的绝对地址定位,函数定位等。        变量的绝对地址定位,是由于在程序中可能需要即时读取某个变量,但变量的类型可能是XDATA,存储在外部RAM中。这里有两个方法:        1,用 _at_ 定位 关键字定位               unsigned char xdata xxx _at_ 0x1100   //定义变量XXX数据类型xdata,位置0x1100               [memory_space]tepe variable_name _at_ constant;               ***绝对地址的变量不可以被初始化;函数或BIT类型的变量是不可以被定义为绝对地址;         2,用 XBYTE 定位 宏定义 绝对地址访问               #define CBYTE((unsigned char volatile code*)0)               #define DBYTE((unsigned char volatile idata*)0)               #define PBYTE((unsigned char volatile pdata*)0)               #define XBYTE((unsigned char volatile xdata*)0)               ////////////////////////////////////////////////////////////////////////////               #define CWORD((unsigned int volatile code*)0)               #define DWORD((unsigned int volatile idata*)0)               #define PWORD((unsigned int volatile pdata*)0)               #define XWORD((unsigned int volatile xdata*)0)               以上是宏定义的原型函数,定义在 #include 头文件中               #defme xxx XBYTE[0x8000]    //变量类型为unsigned char 类型的数据xxx,位置xdata 0x8000               yyy=XBYTE[0x8000];              //变量类型为unsigned char 类型的数据yyy,位置xdata 0x8000         (在这里,有网友提到,当编译器优化时,用绝对地址定位的变量,可能导致变量在连续读取时出           错,采用解决方法:           a,将编译器优化调整为0,即不优化,程序不用修改,做以下操作                >>选择project窗口的Target,然后打开"OptionsforTarget” 设置对话框,选择“C5l”选项卡,                将“Code Optimiztaion”中的“Level”选择为“0:Costant folding”。再次编译<<           b,修改变量定义,增加“volatile”关键字说明其特征:就是说明该变量具有‘挥发’性,每次的读取都一                有意义的,这样编译器即使在优化时,编译后的代码也不会省略掉重复读取的过程。如:                 unsigned char volatile xdata xxx_at_0x8000;                由上文XBYTE等的宏定义函数原型可以看出,该宏定义已经说明了变量具有volatile特性,因此,                                                                                                     也可以直接用XBYTE定义所需要的变量           c,硬件解决办法                以上解决方法为参考网络文章) *************扩展ROM时的函数定位**************函数一部分在内部ROM,一部分在外部ROM中****************         函数定位,个人理解:当一个完整功能的程序存储在外部内部ROM中时,即利用了内部ROM,可能由于内部ROM空间不够,部分函数在外部中,这时,如果要执行整个功能,就需要告诉编译器,其他功能函数的地址(函数在外部ROM中的地址),此时就要用到函数定位功能。解决方法如下: ....待续.....         51内部ROM地址范围0x0000~0x0FFF,所以外部ROM的地址为0x1000~~最大0xFFFF。                 c51bbs有详细介绍         编写完整的程序(如果建立两个工程,堆栈等可能分配位置不同,导致地址重复或多个地址出错), 编译后查看.M51文件,找到需要定位的函数名称信息(如?PR?_BCD2HEX?TOOLS),在KEIL51工程选项---BL51 lacate中code项中加入:?PR?_BCD2HEX?TOOLS(0x1000)再次编译工程,打开.M51文件会发现?PR?_BCD2HEX?TOOLS已经定位在了0x1000位置了。         如果
/
本文档为【XBYTE】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索