找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 21752|回复: 3
打印 上一主题 下一主题
收起左侧

51单片机同时外扩RAM,ROM的具体实现及Keil的具体设置

[复制链接]
跳转到指定楼层
楼主
ID:70976 发表于 2014-12-23 20:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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 <absacc.h>头文件中
              #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位置了。
        如果有多个程序需要定位,方法同上,找出函数的名称信息,添加到BL51 locate的CODE项中,每个函数之间用逗号隔开。而且要注意,所要定位的多个函数根据定位设置之前的地址高低安排,仍旧是低地址函数在前,高地址函数在后。
        程序分为两部分存储,需要做的设置等如下:
....待续.....
        完成函数定位设置后,由于函数是要烧录在两个ROM中,需要将HEX文件分割成两个,内部ROM空间范围与外部ROM空间范围是不一样的,自然就应该将内部ROM的地址范围的HEX代码存储为一个文件,将剩余部分的代码存储为另一个文件,就完成了分割。
       例如HEX文件的0x0000~~0x0FFF地址划分为一个文件,0x1000~~0xFFFF划分为另一个文件。
       这一点,如果所用的MCU的内部ROM大小不一致,就需要根据具体的大小划分分割HEX文件。
*******************************编译器设置**********************************
        由于是内部ROM和外部扩展ROM同时使用,在工程选项off-chip memory中需要设置外部ROM地址范围,如eprom start:0x1000 size:0xFFFF(根据具体ROM大小设置size,同时use on-chip memory选项不选,电路中EA接高电平)
*******************************扩展ROM,所有程序都在外部ROM中**********************************
        51内部ROM不够用,但外部扩展的ROM应该足够了,所以,在扩展了ROM之后,尽量避免编程麻烦,所有功能均放在外部ROM中,此时需要的设置操作等如下:
....待续.....
        由于程序代码只用到了外部ROM,程序编译等不需要特殊的设置,按正常编译。然后将整个代码烧录到外部ROM就可以了。也就不存在HEX文件分割的问题了。
*******************************编译器设置************************************
        由于只用到了外部ROM,
在工程选项off-chip memory中需要设置外部ROM地址范围,如eprom start:0x0000 size:0xFFFF(根据具体ROM大小设置size,同时use on-chip memory选项不选,电路中EA接低电平),这里的设置不同与内外部ROM都用的情况,没有使用内部ROM的情况下需要地址从0x0000开始,程序的开始地址中断向量等都在这里(具体参考内部ROM地址的使用)。EA接低电平表示程序是从外部ROM开始读起的,即不用内部ROM。
**************************扩展ROM,RAM时,总线地址如何安排*****************************
在扩展了ROM,RAM时,总线地址要如何安排,具体怎样设置呢?操作如下:
......待续.......
       在程序设计时,要考虑硬件连接。例如,在外部ROM,RAM的地址设置时(keil工程选项中),假设P15初始化置1了或在程序中,P15为1时WR RD信号才时序正常(使用了74门电路),则keil工程选项中的地址设置就要考虑工作状态P15是0或1的情况了。页选信号就是从这里这样而来的,P15页选或地址线高字节页选。
*****************************硬件连接,需要考虑的问题**********************************
扩展ROM,RAM时,硬件需要则样连接?总线上的时续,总线设备的速度匹配问题?
.......待续........
       使用总线方式连接扩展设备时,51总线有固定的时序,时序也就决定了速度。比如每个读写的过程,相应的信号持续时间长短,扩展设备能否在这个周期内完成工作,是需要51的总线时序和扩展设备的时序匹配才可以的。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:63162 发表于 2014-12-23 21:49 | 只看该作者
楼主好样的,谢谢楼主的分享,太感谢啦
回复

使用道具 举报

板凳
ID:100713 发表于 2015-12-28 22:35 | 只看该作者
好贴,感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表