硬件:用89V51RD2扩展外部32K的数据存储器62256,P0/P2用作地址线,54HC373用来锁存,P2.7连接62256的片选端,存储地址范围为单片机可寻址的0x0000-0x7fff的低32K字节,硬件连接应无问题。
软件:编译环境Keil C51,编译用的型号是89C51RD2(Keil无89V51RD2)
C/C++ code?#include<reg51f.h>//89V51RD2头文件 #define uchar unsigned char uchar xdata *p;//将p定义为指向片外存储器的uchar类型数据的指针 main() { uchar j; init();//初始化,设置好波特率,定时器未启动,无其他代码 p=0x0000; while(p<0x1fff)//写8k字节,0-255循环 { *p=j; j++; } delay(100);//延时一定时间 p=0x0000; while(1) { if(p>0x1ff0) break; send232(*p);//通过串口把外部数据存储器内的数据发送出去 delay(10);//延时一定时间等待串口数据发送完毕 } while(1); }
现象:对外部地址的访问无效,无论写入多长字节,无论写入什么,示波器读到的数据都为0
尝试:①看datasheet,已将AUXR寄存器设置为0x03(0x02也试了),均无效,如果不进行设置,那么xdata读到起内部1k字节RAM的扩展768个字节,其后数据仍为0,表明对其后地址的写入无效②用串口发其他任意数据(不在扩展数据存储器内的),示波器观测均正常,串口发送应无问题③更换单片机/373/62256,问题仍存在,可排除硬件连接④用XBYTE【0x0100】等方式进行读写外扩地址的内容,仍无效⑤将单片机换成P89C58,程序中包含头文件等做相应更改,问题依旧⑥看反汇编,用的就是MOVX @DPTR A以及R7寄存器数值递增往DPTR里面送这样的语句,应该是访问到了外部,但软件实际没有执行
怀疑:是否由于89V51RD2内部有64K的flash空间,所以在寻址上定义xdata访问外部地址可能有冲突?
问题:如何对扩展的32k数据存储器进行访问,软件上还需要什么特殊的设置吗?
附:89V51RD2的部分内容
7.1.2 数据RAM存储器
数据RAM含有1024字节的内部存储器。器件也可对高达64kB的外部数据存储器进行寻址。
7.1.3 扩展数据RAM寻址
P89V51RD2有1kB的RAM。见图5“内部和外部数据存储器结构” 。
器件的内部数据存储器由4部分组成:
1. 低128字节RAM(00H~7FH) ,可直接和间接寻址。
2. 高128字节RAM(80H~FFH) ,间接寻址。
3. 特殊功能寄存器(80H~FFH) ,只可直接寻址。
4. 扩展的 768 字节 RAM(00H~2FFH) ,通过移动外部指令(MOVX)和清除 EXTRAM 位间接寻
址。 (见第6节“特殊功能寄存器”的辅助寄存器(AUXR) ” )
由于高 128 字节和 SFR 占用相同的地址,因此 RAM 空间必须进行间接寻址。尽管 RAM 和 SFR 的地
址相同,但它们在物理上是独立的。
将 EXTRAM 清零,使用 MOVX 指令来访问扩展 RAM。外部 768 字节的存储器在物理上位于片内,
逻辑上占用的是外部存储器的前768字节(地址000H~2FFH) 。
当 EXTRAM=0,扩展 RAM 通过 MOVX 指令和选定寄存器区的 R0、R1 寄存器或 DPTR 间接寻址。
对扩展RAM的访问不会影响P0口、P3.6(WR ) 、P3.7(RD )或P2口。有关EXTRAM=0时扩展RAM
的访问,请参考下面的例子。
扩展RAM访问(只能间接寻址) :
MOVX @DPTR,A DPTR指向0A0H单元
DPTR 指向 0A0H 单元, ‘A’的内容写入到扩展 RAM(而非外部存储器)的 0A0H 地址单元。利用
MOVX指令来访问高于2FFH单元(0300H~FFFFH)的外部存储器,整个过程的执行方法与标准8051器
件完全相同:P0和P2口用作数据/地址总线,P3.6和P3.7分别用作写和读信号。
当EXTRAM=1 时,MOVX @Ri和MOVX @DPTR的用法与标准8051类似。MOVX @Ri 提供一个8
位的地址, 此时P0口还复用为数据总线。 由其它输出端口管脚输出高地址位。 这就提供了一种外部页功能。
MOVX @DPTR 产生一个 16 位地址,允许对高达 64kB 的外部存储器进行访问。由 P2 口提供高 8 位地址
(DPH) ,P0口复用为低8位地址(DPL)总线和数据总线。MOVX @Ri 和MOVX @DPTR均可产生必需
的读和写信号(P3.6-WR ,P3.7-RD ) ,供外部存储器使用。表 7 所示为 EXTRAM 位状态给定时外部
数据存储器的RD 和WR 操作。
表7 EXTRAM位状态给定时外部数据存储器的RD 和WR 操作
MOVX @DPTR,A或MOVX A,@DPTR MOVX @Ri,A或MOVX A,@RI
AUXR
ADDR<0300H ADDR≥0300H ADDR=任何值
EXTRAM=0 RD /WR 无效 RD /WR 有效 RD /WR 无效
EXTRAM=1 RD /WR 有效 RD /WR 有效 RD /WR 有效
访问限制在0~0FFH的ERAM地址内;不能访问100H~02FFH单元。
uchar xdata *p;//将p定义为指向片外存储器的uchar类型数据的指针 main() { uchar j; init();//初始化,设置好波特率,定时器未启动,无其他代码 p=0x0000; while(p<0x1fff)//写8k字节,0-255循环 { *p=j; j++; p++;//! } delay(100);//延时一定时间 p=0x0000; while(1) { if(p>0x1ff0) break; send232(*p);//通过串口把外部数据存储器内的数据发送出去 delay(10);//延时一定时间等待串口数据发送完毕 p++; } while(1); }
AUXR寄存器设置为0x03(0x02也试了),均无效,如果不进行设置,那么xdata读到起内部1k字节RAM的扩展768个字节,其后数据仍为0,说明内部1K RAM起左右,
这种情况,外部连线有没有问题,能不能先用弄个AT89C51来弄试??这个内部没有扩展RAM
捣鼓了一周发现A14的地址线被误连接到其他地方去了……所以在对地址进行操作的时候误操作到别的地方了,更改此处,问题解决。
不过还有一点比较奇怪,我用买的04年的一批62256在错误的地址线情况下还是可以用的,买的11年和13的批次的62256不能用,同一个厂家生产的,难道产品的抗干扰性越做越差了?