打印
[ZLG-ARM]

依然是EasyARM2200外部存储器接口实验的问题

[复制链接]
1936|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zjb800zjb|  楼主 | 2007-2-7 02:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.实验教程(-)的P108有一句
ip=(volatile uint16 *)(FLASH_ADDR|(Addr&0x1ffff));
*ip=Data;  //第四个写周期,地址Addr,数据Data
要是写成ip=(volatile uint16 *)(FLASH_ADDR|(Addr));我是绝对可以理解的,可是为什么要写成(Addr&0x1ffff)呢?与1做&的话,是1的还是1,是0的还是0,不是跟没做一个样么?

2.芯片SST39VF160有三个引脚为CE#,OE#,WE#,用于片选,输出使能,写使能。可是在书上的C语言程序中也没见到对这三个控制信号有什么操作,是不是不用我们自己管?ARM自己会处理?(因为我注意到图3.18中,与CE#,OE#,WE#三个引脚相连的ARM的引脚分别为CS1,OE,WE,这些东西是不是要在启动代码中做设置的?而因为我按书上做实验时用的是周立功给好的工程模块,所以没有需要我自己动手。)

相关帖子

沙发
平常人| | 2007-2-7 08:09 | 只看该作者

馒头掰碎了放在你的嘴边让你吃,结果连馒头是什么样都不

使用特权

评论回复
板凳
zlgARM| | 2007-2-7 08:44 | 只看该作者

RE

答1、
0xff & 0xff =?
0xff & 0x1f =?
这两个算式的结果是一样的吗?

答2、
没错。


楼主,建议您先系统浏览一下《微机原理与接口技术》或者上网搜索一下。不然,您以后的疑惑会更多。
给您推荐几个非常适合初学者的网站。用百度搜索:南方的老树、hotpower、程序匠人、computer00。浏览一下网站,确定自己的基础知识结构有哪些大洞需要弥补,然后自己先系统学习一下。

使用特权

评论回复
地板
zjb800zjb|  楼主 | 2007-2-11 04:45 | 只看该作者

把源程序又看了一下

我在一楼的提问中写错了,应为:
(FLASH_ADDR|(Addr&0x1fffff)),我在一楼的提问中少写了一个f。
Addr是与0x1fffff求&,而EasyARM2200中FALSH是位于BANK0,BANK0起始地址为0x81000000(这也是FLASH_ADDR的值)。也就是说做为要与FLASH_ADDR求“|”的Addr是绝不能影响0x81000000的前面的"0x81"这一段数字的,否则写入的数据很可能会写到别的寄存器或者外设里去了。这里将Addr与0x1fffff(是六位六进制数字哦,正好跟0x81000000的后面6个0相对应,Addr应该被限制于只能影响后面那6个0)求&,就可避免Addr影响0x81000000中的"0x81"字段。简单的来说,(FLASH_ADDR|(Addr&0x1fffff))是为了保证向FLASH写入数据时,不会写到别的外设或寄存器里去,因为可能会导致意想不到的后果(因为编程者可能不小心把Addr的值取得很大)。

我提这个问题不是出于C语言语法上的考虑的,是出于对这句话功能的考虑。原先没有想到Addr值可能会被取得过大这一点上去。不过我也不知道我这么想对不对。

使用特权

评论回复
5
平常人| | 2007-2-11 09:48 | 只看该作者

楼主开始向正确的方向思考了

注意:0x1fffff是21个bit,作为地址可以表示2MB的范围;而你的FLASH_ADDR中的6个0是24个bit,可以表示16MB的范围。
 
所以这个操作不但要限制Addr不影响到0x81部分,而且要限制地址变化范围不能超过2MB。

使用特权

评论回复
6
zjb800zjb|  楼主 | 2007-2-11 15:29 | 只看该作者

晚上又想了一下!

是了,就是楼上的朋友说的那样,是为了保证地址不超过0x81000000~0x811fffff这个范围!哇,终于想明白了。。。谢谢大家的教导。

使用特权

评论回复
7
zjb800zjb|  楼主 | 2007-2-11 15:57 | 只看该作者

源程序中我始终觉得有个地方不对。。。

#include "config.h"
#define BEEPCON 0x00000080

void delayns(uint32 dly)
{ uint32 i;
  for(;dly>0;dly--) 
   for(i=0;i<5000;i++);
}

#define FLASH_ADDR 0x81000000
#define GetAddr(addr) (volatile uint16 *)(FLASH_ADDR|(addr<<1))

uint8 WordProgram(uint32 Addr,uint16 Data)
{ volatile uint16 *ip;
  uint16 temp1,temp2;
  ip=GetAddr(0x5555);
  ip[0]=0xaaaa;
  ip=GetAddr(0x2aaa);
  ip[0]=0x5555;
  ip=GetAddr(0x5555); //地址0x5555要转换,因为LPC2210的A1连FLASH的A0 
  ip[0]=0xa0a0;
  ip=(volatile uint16 *)(FLASH_ADDR|(Addr&0x1fffff)); //此处为什么                            Addr不用转换?
  *ip=Data;
  
  while(1)
  { temp1=*ip;
    temp2=*ip;
    if(temp1==temp2)
    { if(temp1!=Data) return(FALSE);
       else return(TRUE);      
    }
  }
  return(TRUE);
}

uint8 ChipErase(void)
{ volatile uint16 *ip;
  uint16 temp1,temp2;
  ip=GetAddr(0x5555);
  ip[0]=0xaaaa;
  ip=GetAddr(0x2aaa);
  ip[0]=0x5555;
  ip=GetAddr(0x5555);
  ip[0]=0x8080;
  ip=GetAddr(0x5555);
  ip[0]=0xaaaa;
  ip=GetAddr(0x2aaa);
  ip[0]=0x5555;
  ip=GetAddr(0x5555);
  ip[0]=0x1010;
  
  while(1)
  { temp1=*ip;
    temp2=*ip;
    if(temp1==temp2)
    { if(temp1!=0xffff) return(FALSE);
       else return(TRUE);
    }
  }
  return(TRUE);
}

int main(void)
{ uint8 i;
  uint8 err=0;
  volatile uint16 *addr;
  PINSEL0=0x00000000;
  IO0DIR=BEEPCON;
  ChipErase();
  addr=(volatile uint16 *)FLASH_ADDR+0;
  for(i=0;i<100;i++)
  { if(0xffff!=(*addr)) err=1;
    addr++;
  }
  
  WordProgram(0x0,0x55aa);
  addr=(volatile uint16 *)FLASH_ADDR+0;
  if(0x55aa!=(*addr)) err=1;
  if(0==err)
  { IO0CLR=BEEPCON;
    delayns(20);
    IO0SET=BEEPCON;
    delayns(20);
  } 
   else
   { while(1)
     { IO0CLR=BEEPCON;
       delayns(10);
       IO0SET=BEEPCON;
       delayns(10);
     }
   }
  while(1);
  return(0);
}

我在程序里标出来了,此处为什么Addr不用转换?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

36

帖子

0

粉丝