搜索
bottom↓
回复: 40

关于AVR外部扩展RAM(包括>64KB)的问题

[复制链接]

出0入0汤圆

发表于 2007-11-6 14:19:59 | 显示全部楼层 |阅读模式
最近几天,发现很多人使用M128、M8515等带有外部并行扩展口的AVR芯片,设计外部扩展RAM的系统。估计这些人不是初次学习单片机,可能具备一些使用51设计系统的经验。需要注意的是,AVR不是51,另外AVR也还是8位的单片机,不能完全满足那些需要大量计算和复杂数据处理的应用。

一、正常方式外部扩展RAM
    所有带有外部并行扩展口的AVR芯片,其数据存储器空间容量为64k(地址线16根),也就是说整个系统的可直接操作的数据空间为64K。但与51有区别的是,这64K的空间不是全部应用于外部扩展,因为AVR的32个寄存器、I/O寄存器和内部RAM已经占掉了一部分。所以实际上外部扩展RAM仅占60K左右(M128为例)。在我的《M128》一书的第5章中有对正常方式外部扩展RAM的设计和应用的详细介绍,请大家参考。

二、非正常方式外部扩展RAM
    这里的非正常是指外部扩展大于64KRAM的应用,如128K、256K等。很明显,这样的扩展方案需要使用其它I/O线作为页选信号才能使用,本人在以前使用51的时候,也做过这样的系统。但对于使用AVR,则由于其内部占用了4K左右的地址,使得每页的RAM前端都实际是内部的RAM地址,所以整个RAM中间出现了“空洞”,所以在使用和处理上比51要复杂。
    现在很多低端的32位ARM价格也比较便宜了,个人觉得这样的应用最好选择ARM。如果一定要使用AVR的话,以下几点需要认真的考虑。

1。硬件上地址锁存、译码电路当然是少不了,一定要使用HC系列的,因为AVR的速度比较快。
2。由于所有的C平台是不支持大于64K扩展的,它们只是把数组分配在64K空间内,因此数据定义非常重要。在实际使用中,应该将系统使用的其它各种变量定义在0页中,而把大型的数组定义在其它的页中,还要注意数组最大不能超过60K字节(对于M128,M256则不能超过56K)。
3。在变量定义的时候当然只能是按64K空间处理,在具体操作时用户需要做大量的转换处理,要精心设计,否则肯定会出现问题。

下面用一些简单的例子说明:
    假定系统使用M128,需要2个48K字节的数组,那么64KRAM是不够的,扩展成128K,分成0、1页,用PD0控制。

    定义变量:

    char temp1;
    char arr_temp[2048];
    .......

    char temp2;
    union arr{
            char a0[49152];
            char a1[49152];
            } data;

    说明:定义只能在64K空间。
          temp1、arr_temp[2048]必须先定义,最后查看,应该定位在M128内部的4KRAM中。作为交换使用。
          a0[],a1[]为共同体,占用同一地址空间。但PD0=0是,操作a0[],在0页;PD0=1时,操作a1[],在1页。
          只要变量定位在内部4K的RAM中,那么不管PD0是何值,都可以直接对其操作。!!!!

下面是对数据的典型操作方式:
    1。如果只对a0[]操作,那么将PD0置0,一切采用正常操作。
    2。从a1[]中读一个数据到temp2:

       如果temp2定位在内部RAM:
       PD0 = 1;
       temp2 = data.a1;
        
       如果temp2定位在外部RAM,且在第0页(只能用户自己确定了)
       PD0 = 1;
       temp1 = data.a1;
       PD0 = 0;
       temp2 = temp1;   // temp1必须是定位在内部RAM中的变量

   3。将a1[]数据导入到a0[]中:两者在不同的页,只能通过定位在内部RAM的arr_temp[]间接处理实现
      
  for                                 // 24次   
  {     
      PD0 = 1;
      for
      {
          arr_temp = a1;        // 2048个
      }

      PD0 = 0;
      for
      {
          a0 = arr_temp         // 2048个
      }
  }   
              
哈哈,晕了。其它自己去处理吧。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2007-11-6 14:44:04 | 显示全部楼层
学习中

出0入0汤圆

发表于 2007-11-6 15:15:13 | 显示全部楼层
马老师,有必要设置一个UNION吗?
    char temp1;  
    char arr_temp[2048];  
    .......  

    char temp2;  
    char a0[49152];  
//控制好编译器优化的层次,效果和您原来的union一样的

for                                 // 24次   
  {   //源页   
      PD0 = 1;  
      for  
      {  
          arr_temp = a0;        // 2048个  
      }  

      PD0 = 0;  //换目标页
      for  
      {  
          a0 = arr_temp         // 2048个  
      }  
  }

出0入0汤圆

 楼主| 发表于 2007-11-6 15:41:49 | 显示全部楼层
效果是一样的,但使用A0、A1在编程上更加明了,看到A0知道是0页的,A1是1页的。

出0入0汤圆

发表于 2007-12-5 14:34:59 | 显示全部楼层
受益不少,使用共用体可以节省很多空间,以前我做的数组切换,就是存在不同的地址单元,浪费了很多空间!

出0入0汤圆

发表于 2007-12-8 19:57:52 | 显示全部楼层
请问马老师,我用CAVR的编译器,定义使用外扩的RAM应该用什么关键字,例如我用典型的m162配32K,有具体的CAVR的例子否?谢谢!

出0入0汤圆

发表于 2007-12-8 20:36:40 | 显示全部楼层
学习了

出0入0汤圆

 楼主| 发表于 2007-12-9 22:52:12 | 显示全部楼层
to 5楼:
不用使用任何关键字.只要在PROJECT的设置中选择使用外部扩展RAM,填上扩展的大小.CVAVR的编译器在需要的时候,会自动将变量分配到外部RAM中,程序中就是简单的读写变量.

需要注意的时,外部扩展的RAM地址必须紧跟在内部RAM后面,中间不能出现"空地址".

出0入0汤圆

发表于 2007-12-11 22:54:43 | 显示全部楼层
需要注意的时,外部扩展的RAM地址必须紧跟在内部RAM后面,中间不能出现"空地址".
这句怎么理解?
另外,我在看m162的DS时,看到:
因为外部存储器在那个图中的内部存储器之后才被映射,所以呢,在外部存储器的头1280字节的空间是不可以寻址的,这就表现为不能存取外部存储器的0X0000-0X04FF。当然有个特殊的情况,当使用的外部存储器小于64K(典型值32K)时,外部存储器的0X0000-0X04FF范围可以通过访问0x8000 to 0x84FF进行存取(想一想为什么?)。因为高位地址线A15没有接入,外部寻址范围只有0X0000-0X7FFF,当访问0x8000 to 0x84FF时,低14位地址线定位在外部0X0000-0X04FF处(或许大家会疑惑,怎么不是访问的内部0X0000-0X04FF?请注意了,我们现在访问的是外部存储器,因为地址范围为0x8000 to 0x84FF,不是内部存储器,所以自然不是定位在内部0X0000-0X04FF范围)。不推荐大家对0x84FF以外的范围进行访问,因为这将改变 0X04FF-0X7FFF的数据,因为低14位地址是重复的。在应用中,地址在0x0500 to 0x84FF范围的存取是连续的线性的,只有0X0000-0X04FF有写特;

上面的这些与你所说的"空地址"有什么联系?

byte a[20480] @0x0500;
我这样的定义可以否,
另外附上一此在CAVR上的截图,请马老师看一下如何设置?






我现在是用M162配32K,一般A15接62256的CS脚,在程序中要对A15脚进行编程吗?
谢谢~!

出0入0汤圆

 楼主| 发表于 2007-12-13 01:33:19 | 显示全部楼层
》外部扩展的RAM地址必须紧跟在内部RAM后面,中间不能出现"空地址".  
通常为
0X0000-0X04FF====》32个通用寄存器、I/O寄存器、内部RAM
0X0500--0X7FFF====》外部RAM  (此时共32KB)
0X8000--0X84FF====》外部RAM的低位空间(1280个)用足33KB多一点。

0X8500--0XFFFF====》可以分配给其它并行接口芯片,中间可以出现“空地址”。

而下面则中间出现“空地址”情况。最好不要这样分配设计
0X0000-0X04FF====》32个通用寄存器、I/O寄存器、内部RAM
0X8000--0XFFFF =====》外部RAM

》我现在是用M162配32K,一般A15接62256的CS脚,在程序中要对A15脚进行编程吗?
为什么使用A15接CS?
如果这样分配:
0X0000-0X04FF====》32个通用寄存器、I/O寄存器、内部RAM
0X0500--0X7FFF====》外部RAM  (此时共32KB)
够的话,那么A15可以作为一个I/O口使用,CS直接接地。

另外,第一张图中的外部SRAM的大小没有填。CVAVR会自动分配变量到外部RAM中的,不必特别的声明。

()

在我的《M128》一书的第5章中有对正常方式外部扩展RAM的设计和应用的详细介绍,请参考。

出0入0汤圆

发表于 2007-12-13 12:16:47 | 显示全部楼层
第一张图里SRAM大小如果是扩32K,就写,32*1024 byte,然后将下面勾上,第二张图就直接按这样的分法,可是我在测试的时候外部没有接上任何的SRAM,程序就不能正常的运行了,这是什么原因呢??谢谢马老师!

出0入0汤圆

 楼主| 发表于 2007-12-13 12:23:50 | 显示全部楼层
图中的设置,是告诉编译器,你使用了外部RAM,以及外部RAM的地址分配,对外部RAM操作是否需要加上等待节拍等.

编译器根据你的设置,将变量分配在外部RAM中了.

可是你外部根本不接RAM,程序能正常么?你在骗编译器?

出0入0汤圆

发表于 2007-12-13 12:32:04 | 显示全部楼层
谢谢马潮老师,基本上已经明白了,现在等硬件搞好后再测试一下,另外,我看到一些51的程序,62256的CS脚接到A15脚,可是程序里根本找不到它对A15脚的编程,这是硬件自动生成的控制吗?谢谢!

出0入0汤圆

发表于 2007-12-21 21:35:13 | 显示全部楼层
学习了

出0入0汤圆

发表于 2008-6-16 10:41:22 | 显示全部楼层
研究学习

出0入0汤圆

发表于 2008-8-5 17:20:21 | 显示全部楼层
用union不错.得到一些启发.

我公司做的一个产品就是128k的sram.但是那些ram地址在程序中都用的绝对地址不是通过编译器分配的.

所以使用起来还是比较可靠的.

出0入0汤圆

发表于 2009-6-6 20:37:19 | 显示全部楼层
学习一下,支持!

出0入0汤圆

发表于 2009-8-19 21:02:56 | 显示全部楼层
能不能推荐几个能够用的SRAM具体型号呢?我看了那些传统的  62256  好像速度都够不到啊!!
如果mega128的时钟是16MHz那么单个周期是62.5ns,然后再看看ram的datasheet后面有个什么70ns
哎,感觉好像不能用,就算用上了可能也会出问题的。
锁存器用74AHC的,这个好像还能够达到要求的


求助?求助?啊啊啊~~~  ~~~

出0入0汤圆

 楼主| 发表于 2009-8-22 09:54:51 | 显示全部楼层
avr读外部SRAM最少需要2个时钟周期。

16MHz,单个周期是62.5ns,2个是125ns,所以70ns的SDRAM可以正常使用。注意PCB的走线。

出0入0汤圆

发表于 2009-9-25 22:38:21 | 显示全部楼层
标记,学习,马老师。

出0入0汤圆

发表于 2009-11-18 22:38:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-17 18:29:32 | 显示全部楼层
回复【楼主位】machao
-----------------------------------------------------------------------

你好马老师我用的是ATMEGA128。里面介绍有128k的程序空间。可是我无法定义超过4K的数组。看了你上面的操作在我这里不成功,我用的ICCAVR编译器?

出0入0汤圆

发表于 2010-3-18 15:48:25 | 显示全部楼层
mark  以后可能用到

出0入0汤圆

发表于 2010-4-26 23:02:02 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-11-17 02:38:43 | 显示全部楼层
学习。。。

出0入0汤圆

发表于 2010-12-4 00:09:35 | 显示全部楼层
学习了,

出0入0汤圆

发表于 2010-12-13 12:25:02 | 显示全部楼层
学习~~

出0入0汤圆

发表于 2010-12-13 17:03:06 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-12-13 18:29:08 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-2-11 08:55:54 | 显示全部楼层
我测试过一块LED屏控制卡,上面使用的是Atmega162和HM628512,RAM的A16~A19连接在别的端口上,CS=~A15。

出0入0汤圆

发表于 2011-4-12 21:02:14 | 显示全部楼层
#include <iom128v.h>
#include <macros.h>
#define uchar unsigned char
#define OFFEST 0x8000
void W_U6CNT2(uchar ctrl)
{
  uchar *p=(uchar *)(OFFEST+0xcf);
  *p=ctrl;
}
void W_U6(uchar ctrl)
{
   uchar *p=(uchar *)(OFFEST+0xdf);
  *p=ctrl;
}
void main()
{
  MCUCR|=0x80;//PA、PG、PC口作为总线功能
  XMCRA=0x00;
  XMCRB=0x80;
   W_U6(0x54); //写控制字
  W_U6CNT2(0x0a);//写低八位计数初值
}
这是我没事用M128的的扩展总线,控制8253的用作分频器的一个测试。但是好像硬件端口出不来波形!求帮助!!!!!!!!!!

出0入0汤圆

发表于 2011-4-24 21:13:19 | 显示全部楼层
受益不少,谢谢。收藏。

出0入0汤圆

发表于 2011-4-28 15:18:58 | 显示全部楼层
【楼主位】 machao
    说明:定义只能在64K空间。  
          temp1、arr_temp[2048]必须先定义,最后查看,应该定位在M128内部的4KRAM中。作为交换使用。
-----------------------------------------------------------------------

【7楼】 machao
不用使用任何关键字.只要在PROJECT的设置中选择使用外部扩展RAM,填上扩展的大小.CVAVR的编译器在需要的时候,会自动将变量分配到外部RAM中,程序中就是简单的读写变量
-----------------------------------------------------------------------
1、如果设置了选择使用外部扩展RAM
如何定义变量到内部 如何定义变量到外部?
  
是不是在内部够用的情况下
使用unsigned char arr_temp[2048];这样的 默认使用内部

而使用指针地址偏移的,如:
#define OFFEST 0x1100
unsigned char *p=(uchar *)(OFFEST+偏移量);
指针地址超出内部RAM寻址范围的转为使用外部?

2、

(原文件名:b.jpg)


(原文件名:c.jpg)

这是datasheet里关于地址锁存要求的一段话,下半段话怎么理解?

出0入0汤圆

 楼主| 发表于 2011-4-30 14:19:20 | 显示全部楼层
1、如果设置了选择使用外部扩展RAM,如何定义变量到内部,如何定义变量到外部?

==》作为普通的变量,通常编译器会根据情况自动分配,分配的情况可以查看编译后产生的类似MAP类型的文件。同时编译器也提供用户指定分配的语句,例如CVAVR:

Global variables can be stored at specific SRAM and EEPROM locations at design-time using the @ operator.
Example:


/* the integer variable "a" is stored
   in RAM at address 80h */
int a @0x80;


/* the structure "alfa" is stored
   in RAM at address 90h */
struct s1 {
    int a;
    char c;
    } alfa @0x90;


/* the float variable "b" is stored
   in EEPROM at address 10h */
eeprom float b @0x10;


/* the structure "beta" is stored
   in RAM at address 20h */
eeprom struct s2 {
    int i;
    long j;
    } beta @0x20;


The following procedure must be used if a global variable, placed at a specific address using the @ operator, must be initialized during declaration:


/* the variable will be stored in RAM at address 0x182 */
float pi @0x182;
/* and it will be initialized with the value 3.14 */
float pi=3.14;


/* the variable will be stored in EEPROM at address 0x10 */
eeprom int abc @0x10;
/* and it will be initialized with the value 123 */
eeprom int abc=123;


是不是在内部够用的情况下,使用unsigned char arr_temp[2048];这样的默认使用内部

而使用指针地址偏移的,如:
#define OFFEST 0x1100  
unsigned char *p=(uchar *)(OFFEST+偏移量);
指针地址超出内部RAM寻址范围的转为使用外部?

==》通常是这样的。

2。后面是给出建立稳定的地址输出和锁存的最小时间要求。

出0入0汤圆

发表于 2011-4-30 19:58:14 | 显示全部楼层
回复【33楼】machao
-----------------------------------------------------------------------

恩 知道了 谢谢马老师的解答

片外扩展RAM理论上是好理解的 实际上操作要求考虑到很多方面 而且现在要做的还要带掉电保护的

出0入0汤圆

发表于 2012-8-19 21:44:17 | 显示全部楼层
学习了!   

出0入0汤圆

发表于 2013-4-14 09:37:51 | 显示全部楼层
记录一下

出0入0汤圆

发表于 2013-5-13 14:28:26 | 显示全部楼层
一、正常方式外部扩展RAM
    所有带有外部并行扩展口的AVR芯片,其数据存储器空间容量为64k(地址线16根),也就是说整个系统的可直接操作的数据空间为64K。但与51有区别的是,这64K的空间不是全部应用于外部扩展,因为AVR的32个寄存器、I/O寄存器和内部RAM已经占掉了一部分。所以实际上外部扩展RAM仅占60K左右(M128为例)。在我的《M128》一书的第5章中有对正常方式外部扩展RAM的设计和应用的详细介绍,请大家参考。


请问下 《M128》这个的完整书名是什么啊?

出0入0汤圆

发表于 2013-5-13 14:39:38 | 显示全部楼层
superray2008   你好  可以认识一下你吗?
我的qq:150216708

出0入0汤圆

发表于 2013-5-13 16:11:33 来自手机 | 显示全部楼层
mark,,,,

出0入0汤圆

发表于 2013-5-15 08:35:40 | 显示全部楼层
请问下 《M128》这个的完整书名是什么啊?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 22:35

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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