[ZLG-ARM] 依然是EasyARM2200外部存储器接口实验的问题

[复制链接]
2971|6
 楼主| zjb800zjb 发表于 2007-2-7 02:51 | 显示全部楼层 |阅读模式
1.实验教程(-)的P108有一句<br />ip=(volatile&nbsp;uint16&nbsp;*)(FLASH_ADDR|(Addr&0x1ffff));<br />*ip=Data;&nbsp;&nbsp;//第四个写周期,地址Addr,数据Data<br />要是写成ip=(volatile&nbsp;uint16&nbsp;*)(FLASH_ADDR|(Addr));我是绝对可以理解的,可是为什么要写成(Addr&0x1ffff)呢?与1做&的话,是1的还是1,是0的还是0,不是跟没做一个样么?<br /><br />2.芯片SST39VF160有三个引脚为CE#,OE#,WE#,用于片选,输出使能,写使能。可是在书上的C语言程序中也没见到对这三个控制信号有什么操作,是不是不用我们自己管?ARM自己会处理?(因为我注意到图3.18中,与CE#,OE#,WE#三个引脚相连的ARM的引脚分别为CS1,OE,WE,这些东西是不是要在启动代码中做设置的?而因为我按书上做实验时用的是周立功给好的工程模块,所以没有需要我自己动手。)<br />
平常人 发表于 2007-2-7 08:09 | 显示全部楼层

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

  
zlgARM 发表于 2007-2-7 08:44 | 显示全部楼层

RE

答1、<br />0xff&nbsp;&&nbsp;0xff&nbsp;=?<br />0xff&nbsp;&&nbsp;0x1f&nbsp;=?<br />这两个算式的结果是一样的吗?<br /><br />答2、<br />没错。<br /><br /><br />楼主,建议您先系统浏览一下《微机原理与接口技术》或者上网搜索一下。不然,您以后的疑惑会更多。<br />给您推荐几个非常适合初学者的网站。用百度搜索:南方的老树、hotpower、程序匠人、computer00。浏览一下网站,确定自己的基础知识结构有哪些大洞需要弥补,然后自己先系统学习一下。<br />
 楼主| zjb800zjb 发表于 2007-2-11 04:45 | 显示全部楼层

把源程序又看了一下

我在一楼的提问中写错了,应为:<br />(FLASH_ADDR|(Addr&0x1fffff)),我在一楼的提问中少写了一个f。<br />Addr是与0x1fffff求&,而EasyARM2200中FALSH是位于BANK0,BANK0起始地址为0x81000000(这也是FLASH_ADDR的值)。也就是说做为要与FLASH_ADDR求“|”的Addr是绝不能影响0x81000000的前面的&quot;0x81&quot;这一段数字的,否则写入的数据很可能会写到别的寄存器或者外设里去了。这里将Addr与0x1fffff(是六位六进制数字哦,正好跟0x81000000的后面6个0相对应,Addr应该被限制于只能影响后面那6个0)求&,就可避免Addr影响0x81000000中的&quot;0x81&quot;字段。简单的来说,(FLASH_ADDR|(Addr&0x1fffff))是为了保证向FLASH写入数据时,不会写到别的外设或寄存器里去,因为可能会导致意想不到的后果(因为编程者可能不小心把Addr的值取得很大)。<br /><br />我提这个问题不是出于C语言语法上的考虑的,是出于对这句话功能的考虑。原先没有想到Addr值可能会被取得过大这一点上去。不过我也不知道我这么想对不对。<br /><br />
平常人 发表于 2007-2-11 09:48 | 显示全部楼层

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

注意:0x1fffff是21个bit,作为地址可以表示2MB的范围;而你的FLASH_ADDR中的6个0是24个bit,可以表示16MB的范围。<br />&nbsp;<br />所以这个操作不但要限制Addr不影响到0x81部分,而且要限制地址变化范围不能超过2MB。
 楼主| zjb800zjb 发表于 2007-2-11 15:29 | 显示全部楼层

晚上又想了一下!

是了,就是楼上的朋友说的那样,是为了保证地址不超过0x81000000~0x811fffff这个范围!哇,终于想明白了。。。谢谢大家的教导。
 楼主| zjb800zjb 发表于 2007-2-11 15:57 | 显示全部楼层

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

#include&nbsp;&quot;config.h&quot;<br />#define&nbsp;BEEPCON&nbsp;0x00000080<br /><br />void&nbsp;delayns(uint32&nbsp;dly)<br />{&nbsp;uint32&nbsp;i;<br />&nbsp;&nbsp;for(;dly&gt0;dly--)&nbsp;<br />&nbsp;&nbsp;&nbsp;for(i=0;i&lt5000;i++);<br />}<br /><br />#define&nbsp;FLASH_ADDR&nbsp;0x81000000<br />#define&nbsp;GetAddr(addr)&nbsp;(volatile&nbsp;uint16&nbsp;*)(FLASH_ADDR|(addr&lt&lt1))<br /><br />uint8&nbsp;WordProgram(uint32&nbsp;Addr,uint16&nbsp;Data)<br />{&nbsp;volatile&nbsp;uint16&nbsp;*ip;<br />&nbsp;&nbsp;uint16&nbsp;temp1,temp2;<br />&nbsp;&nbsp;ip=GetAddr(0x5555);<br />&nbsp;&nbsp;ip[0]=0xaaaa;<br />&nbsp;&nbsp;ip=GetAddr(0x2aaa);<br />&nbsp;&nbsp;ip[0]=0x5555;<br />&nbsp;&nbsp;ip=GetAddr(0x5555); //地址0x5555要转换,因为LPC2210的A1连FLASH的A0&nbsp;<br />&nbsp;&nbsp;ip[0]=0xa0a0;<br />&nbsp;&nbsp;ip=(volatile&nbsp;uint16&nbsp;*)(FLASH_ADDR|(Addr&0x1fffff)); //此处为什么                            Addr不用转换?<br />&nbsp;&nbsp;*ip=Data;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;while(1)<br />&nbsp;&nbsp;{&nbsp;temp1=*ip;<br />&nbsp;&nbsp;&nbsp;&nbsp;temp2=*ip;<br />&nbsp;&nbsp;&nbsp;&nbsp;if(temp1==temp2)<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;if(temp1!=Data)&nbsp;return(FALSE);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;return(TRUE);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;return(TRUE);<br />}<br /><br />uint8&nbsp;ChipErase(void)<br />{&nbsp;volatile&nbsp;uint16&nbsp;*ip;<br />&nbsp;&nbsp;uint16&nbsp;temp1,temp2;<br />&nbsp;&nbsp;ip=GetAddr(0x5555);<br />&nbsp;&nbsp;ip[0]=0xaaaa;<br />&nbsp;&nbsp;ip=GetAddr(0x2aaa);<br />&nbsp;&nbsp;ip[0]=0x5555;<br />&nbsp;&nbsp;ip=GetAddr(0x5555);<br />&nbsp;&nbsp;ip[0]=0x8080;<br />&nbsp;&nbsp;ip=GetAddr(0x5555);<br />&nbsp;&nbsp;ip[0]=0xaaaa;<br />&nbsp;&nbsp;ip=GetAddr(0x2aaa);<br />&nbsp;&nbsp;ip[0]=0x5555;<br />&nbsp;&nbsp;ip=GetAddr(0x5555);<br />&nbsp;&nbsp;ip[0]=0x1010;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;while(1)<br />&nbsp;&nbsp;{&nbsp;temp1=*ip;<br />&nbsp;&nbsp;&nbsp;&nbsp;temp2=*ip;<br />&nbsp;&nbsp;&nbsp;&nbsp;if(temp1==temp2)<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;if(temp1!=0xffff)&nbsp;return(FALSE);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;return(TRUE);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;return(TRUE);<br />}<br /><br />int&nbsp;main(void)<br />{&nbsp;uint8&nbsp;i;<br />&nbsp;&nbsp;uint8&nbsp;err=0;<br />&nbsp;&nbsp;volatile&nbsp;uint16&nbsp;*addr;<br />&nbsp;&nbsp;PINSEL0=0x00000000;<br />&nbsp;&nbsp;IO0DIR=BEEPCON;<br />&nbsp;&nbsp;ChipErase();<br />&nbsp;&nbsp;addr=(volatile&nbsp;uint16&nbsp;*)FLASH_ADDR+0;<br />&nbsp;&nbsp;for(i=0;i&lt100;i++)<br />&nbsp;&nbsp;{&nbsp;if(0xffff!=(*addr))&nbsp;err=1;<br />&nbsp;&nbsp;&nbsp;&nbsp;addr++;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;WordProgram(0x0,0x55aa);<br />&nbsp;&nbsp;addr=(volatile&nbsp;uint16&nbsp;*)FLASH_ADDR+0;<br />&nbsp;&nbsp;if(0x55aa!=(*addr))&nbsp;err=1;<br />&nbsp;&nbsp;if(0==err)<br />&nbsp;&nbsp;{&nbsp;IO0CLR=BEEPCON;<br />&nbsp;&nbsp;&nbsp;&nbsp;delayns(20);<br />&nbsp;&nbsp;&nbsp;&nbsp;IO0SET=BEEPCON;<br />&nbsp;&nbsp;&nbsp;&nbsp;delayns(20);<br />&nbsp;&nbsp;}&nbsp;<br />&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;{&nbsp;while(1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;IO0CLR=BEEPCON;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delayns(10);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IO0SET=BEEPCON;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delayns(10);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;while(1);<br />&nbsp;&nbsp;return(0);<br />}<br /><br />我在程序里标出来了,此处为什么Addr不用转换?<br />
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

36

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部