1.  
  1. 代码一:
  2. #define Writeflash(addr,dat) *((volatile INT16U *)(addr<<1))=(INT16U)dat
  3. #define Readflash(addr) (*((volatile INT16U *)(addr<<1)))
  4. /*addr为读写操作的半字地址,data则为要写入的半字数据。因为ARM处理器是以字节为单位
  5. 进行数据处理的,而SST39VF160是16位数据宽度,所以,addr地址必须左移1位。*/
  6.  
  7. 代码二:
  8. //擦除是否为空
  9. int SST39VF160_CheckBlank(INT32U addr,INT32U WordSize)
  10. {
  11. INT32U i,temp;
  12. for (i=addr;i<(addr+WordSize);i++)
  13. {
  14. temp=*((volatile INT16U *)(i<<1)); //地址左移一位,也就得到16位的数据了。
  15. if(temp!=0xffff) //因为扇区被擦除后,扇区的各位都是1.所以判断temp是否等于0xffff //0xffff
  16. return 0; //如果扇区的各个地址都不为0xffff;则返回0
  17. }
  18. return 1;
  19. }
  1. 在网上看到这么一段话,我琢磨不透。“S3C44B0X是按照字节编址的,而Flash ROM是以16位为一个存储单元”是怎样推出要“偏移一位”呢?代码一的注释和上一段一样,也没有给出是如何推导出来的。而且代码二中的下面这行代码的注释更是让我不解。前面的i被定义成INT32U 型,怎么通过左移一位就可以得到16的数据呢?恳请各位大侠给出较为详细的解释.
  2. temp=*((volatile INT16U *)(i<<1)); //地址左移一位,也就得到16位的数据了。
  3.  
  4. 解答:
  5. 关于那个错位,我不知道能不能跟你说清楚。首先,SST39VF16 FLASH16位的,也就是以两个字节(半字)为最小操作单位的。也就是说你在FLASH地址上给0x00000,则它给出的数据是第一个16位的半字;在FLASH地址上给0x00001,它给出的是第二个16位的半字;在FLASH地址上给0x00002,它给出的是第三个16位的半字。。。但ARM的地址是以字节编址的,它可以以字节单位来读取或者写外设。
  6. 假设我们要读取FLASH的第一个字节,LDRB R0,[R1];将R1内容写0x00000,这个时候ARM执行的是这样的操作:
  7. 1、送出地址0x00000
  8. 2、在D0-D15上读取数据
  9. 3、将读到的16位数据的低8位给R08位(高24位为0
  10.  
  11. 假设我们要读取FLASH的第二个字节,LDRB R0,[R1];将R1内容写0x00001
  12. 这个时候ARM执行的是这样的操作:
  13. 1、送出地址ox00001
  14. 2、在D0-D15上读取数据
  15. 3、将读到的16位数据的高8位给R0的低8位(高24位为0
  16.  
  17. 从上面的操作可以看到,如果我们一一对应的将ARMFLASH得地址连接,那么我们想读FLASH的第2个字节的话,就没有办法读到了。因为你地址给0x00001,FLASH就在数据线上给的是第3个字节和第4个字节的数据,并将高8位(FLASH的第4个字节)给R0;如果你给的地址是0x00000的话,ARM的理解就是将数据线D0-D15的低8位给R0,显然这个16位的数据是FLASH的第1个字节和第2个字节的数据,低8位指的就是第一个自己的数据。显然怎么也读不到FLASH的第2个数据。
  18. 我们既要遵循ARM的规则,又要让FLASH给我们正确的数据。你自己想应该怎么办?很简单,把ARM给的地址最低位剪掉,把剩下的给FLASH。要读第2个字节,还是送0x00001,但是最后的1被剪掉了,FLASH得到的地址是ox00000,显然给出的数据是第1个和第二个字节。而ARM觉得送出的地址是0x00001啊,应该把高地址给R0啊,即把第2个字节给了R0。就是一个“欺上瞒下”的过程。

为何写flash的时候要地址左移一位?的更多相关文章

  1. yii2怎样写规则可以隐藏url地址里的控制器名字

    yii2怎样写规则可以隐藏url地址里的控制器名字,例如现在的是***.com/site/index.html要变成***.com/index.html '<action:index>.h ...

  2. DSP/BIOS使用之初窥门径——滴答时钟及烧写Flash

    操作平台和环境 DSP型号:TMS320C6713 仿真器:XDS510PLUS Flash型号:AM29LV800BT或AM29LV800BT都试过(一般接口一样,区别不大) RAM型号:MT48L ...

  3. 晶振虚焊导致TI 28335 DSP 烧写FLASH后,连接仿真器时正常工作,拔掉仿真器却不能启动运行

    遇到个诡异的问题,28335的DSP,之前程序调试一切正常,但是烧写FLASH后,拔掉仿真器却始终部工作. 解决思路: 1) 检查配置文件貌似没什么问题,复制到其他工程,在开发板上拔掉仿真器启动正常. ...

  4. 编写一函数用来实现左右循环移位。函数原型为move(value,n);n>0时右移n位,n<0时左移|n|位。

    #include<stdio.h> #include<stdlib.h> int main(){ setbuf(stdout,NULL); int move(int,int); ...

  5. Adobe/Flash Media Server 5.0 linux 64位系统下的安装

    一.下载 Adobe/Flash MS5.0下载地址: http://fs1.d-h.st/download/00036/VOt/adobemediaserver_5_ls1_linux64.tar. ...

  6. c语言1左移32位(1<<32)是多少,左移-1位呢

    C语言中 << 是逻辑移位,不是循环移位.1 左移 32 位后为 0,左移 -1 位实际是左移 255 位(互补),当然也是0.这种问题可以写一段小程序,单步执行,看一下每一步的结果.先说 ...

  7. int左移32位的行为未定义/Coverity

    int左移32位的行为未定义 Coverity 代码静态安全检测 Is Shifting more than 32 bits of a uint64_t integer on an x86 machi ...

  8. 数组循环左移 i 位

    数组左移 i 位 3 种方法 1.临时数组存储 先将前 i 个元素用数组存起来 再将后 n - i 个元素左移 i 位 最后将存起来的数组添加到后面去即可 2.通过多次调用左移 1 位的函数 3.翻转 ...

  9. 剑指offer43:左旋转字符串(字符串):对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。

    1 题目描述 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”a ...

随机推荐

  1. Linux学习之CentOS(八)----文件与目录的默认权限与隐藏权限(转)

    文件与目录的默认权限与隐藏权限 一个文件有若干个属性, 包括读写运行(r, w, x)等基本权限,及是否为目录 (d) 与文件 (-) 或者是连结档 (l) 等等的属性! 要修改属性的方法在前面也约略 ...

  2. 《Python黑帽子》_1设置Python环境安装wingIDE

    1首先你得有个Kali 检测python版本 安装pip 2安装wingIDE 网站 http://www.wingware.com 获取WingIDE 3解压wingide并且解决依赖关系 下载后在 ...

  3. lodop打印收费小票

    //收费系统打印机功能:收费/退费,需要使用到lodop var LODOP;//打印机 $(function () { //初始化 $("body").append('<o ...

  4. Qt与FFmpeg联合开发指南(二)——解码(2):封装和界面设计

    与解码相关的主要代码在上一篇博客中已经做了介绍,本篇我们会先讨论一下如何控制解码速度再提供一个我个人的封装思路.最后回归到界面设计环节重点看一下如何保证播放器界面在缩放和拖动的过程中保证视频画面的宽高 ...

  5. Rabbitmq集群

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 Rabbitmq集群高 ...

  6. MySQL 数学函数

    MySQL 数学函数 所有的数学函数在发生错误的情况下,均返回 NULL. -元减.改变参数的符号 mysql> SELECT - 2; -> -2 注意,如果这个操作符被用于一个 BIG ...

  7. MongoDB $type条件操作符

    描述 在本章节中,我们将继续讨论MongoDB中条件操作符 $type. $type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果. MongoDB 中可以使用的类型如下表所示: 类型 ...

  8. 将luarocks整合进openresty

    缘由 随着功能需求的深入, openresty领域的包已经不够用了, 需要lua领域本身累积的库, 也就是luarocks. 本文讲解了windows 10桌面和ubuntu server两套系统的方 ...

  9. 开源一个自己造的轮子:基于图的任务流引擎GraphScheduleEngine

    GraphScheduleEngine是什么: GraphScheduleEngine是一个基于DAG图的任务流引擎,不同语言编写.运行于不同机器上的模块.程序,均可以通过订阅GraphSchedul ...

  10. Android自定义View(RollWeekView-炫酷的星期日期选择控件)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义Cus ...