32位处理器写16位flash时,为什么需要将数据左移一位
发布时间:2020-12-15 17:42:04 所属栏目:百科 来源:网络整理
导读:http://www.voidcn.com/article/p-agfefrzy-pw.html 代码二://擦除是否为空int SST39VF160_CheckBlank(INT32U addr,INT32U WordSize) {INT32U i,temp;for (i=addr;i(addr+WordSize);i++){temp=*((volatile INT16U *)(i1)); //地址左移一位,也就得到16位的
http://www.voidcn.com/article/p-agfefrzy-pw.html 代码二: //擦除是否为空 int SST39VF160_CheckBlank(INT32U addr,INT32U WordSize) { INT32U i,temp; for (i=addr;i<(addr+WordSize);i++) { temp=*((volatile INT16U *)(i<<1)); //地址左移一位,也就得到16位的数据了。 if(temp!=0xffff) //因为扇区被擦除后,扇区的各位都是1.所以判断temp是否等于0xffff //0xffff return 0; //如果扇区的各个地址都不为0xffff;则返回0 } return 1; } 这个问题和嵌入式体系的地址数据关系有关:控制器方面(这里的S3C440X),它的一个地址只能映射一个字节(嵌入式和计算机体系都采用这个标准),而存储器方面(这里的Flash ROM),是一个地址对应16bit(即两个字节),那么,控制器方向的地址就会有1个地址的缺省。具体如下:
控制器地址 控制器数据 存储器地址 存储器数据
0x00000 0x11 0x00000 0x2211
0x00001 0x22
0x00002 0x33 0x00001 0x4433
0x00003 0x44
……
从上面表中看,显然,控制器方向缺省最后1位,才能与存储器地址对齐,也就是地址左移1位的真相。至于为什么0x11在低地址,0x22在高地址,这个才与芯片内部设计有关。
解答:
关于那个错位,我不知道能不能跟你说清楚。首先,SST39VF16 FLASH是16位的,也就是以两个字节(半字)为最小操作单位的。也就是说你在FLASH地址上给0x00000,则它给出的数据是第一个16位的半字;在FLASH地址上给0x00001,它给出的是第二个16位的半字;在FLASH地址上给0x00002,它给出的是第三个16位的半字。。。但ARM的地址是以字节编址的,它可以以字节单位来读取或者写外设。
假设我们要读取FLASH的第一个
字节
,LDRB R0,[R1];将R1内容写0x00000,这个时候ARM执行的是这样的操作:
1、送出地址0x00000
2、在D0-D15上读取数据
3、将读到的16位数据的
低
8位给R0低8位(高24位为0)
假设我们要读取FLASH的第二个
这个时候ARM执行的是这样的操作:
1、送出地址ox00001
2、在D0-D15上读取数据
3、将读到的16位数据的
高
8位给R0的低8位(高24位为0)
从上面的操作可以看到,如果我们一一对应的将ARM和FLASH得地址连接,那么我们想读FLASH的第2个字节的话,就没有办法读到了。因为你地址给0x00001,FLASH就在数据线上给的是第3个字节和第4个字节的数据,并将高8位(FLASH的第4个字节)给R0;如果你给的地址是0x00000的话,ARM的理解就是将数据线D0-D15的低8位给R0,显然这个16位的数据是FLASH的第1个字节和第2个字节的数据,低8位指的就是第一个自己的数据。显然怎么也读不到FLASH的第2个数据。
我们既要遵循ARM的规则,又要让FLASH给我们正确的数据。你自己想应该怎么办?很简单,把ARM给的地址最低位剪掉,把剩下的给FLASH。要读第2个字节,还是送0x00001,但是最后的1被剪掉了,FLASH得到的地址是ox00000,显然给出的数据是第1个和第二个字节。而ARM觉得送出的地址是0x00001啊,应该把高地址给R0啊,即把第2个字节给了R0。就是一个“欺上瞒下”的过程。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |