NOR Flash的学习
NOR Flash简介
NOR FLASH是INTEL在1988年推出的一款商业性闪存芯片,它需要很长的时间进行抹写,大半生它能够提供完整的寻址与数据总线,并允许随机存取存储器上的任何区域,而且它可以忍受一万次到一百万次抹写循环,是早期的可移除式闪存储媒体的基础.
NOR Flash的原理
逻辑上,单层NOR FLASH单元在默认状态代表二进制码中的"1"值,因为在以特定的电压值控制闸极时,电流会流经通道.经由以下流程,NOR FLASH 单元可以被设置为二进制码中的"0"值.
2. 现在通道是开的,所以电子可以从源极流入汲极(想像它是NMOS晶体管).
3. 源-汲电流够高了,足以导致某些高能电子越过绝缘层,并进入绝缘层上的FG,这种过程称为热电子注入.
虽然抹写都需要高电压才能进行,不过实际上现今所有闪存芯片是借由芯片内的电荷帮浦产生足够的电压,所以只需要一个单一的电压供应即可.
NOR Flash的访问方式
在NOR FLASH的读取数据的方式来看,它与RAM的方式是相近的,只要能够提供数据的地址,数据总线就能够正确的挥出数据.考虑到以上的种种原因,多数微处理器将NOR FLASH当做原地运行(Execute in place,XIP)存储器使用,这其实以为着存储在NOR FLASH上的程序不需要复制到RAM就可以直接运行.由于NOR FLASH没有本地坏区管理,所以一旦存储区块发生毁损,软件或驱动程序必须接手这个问题,否则可能会导致设备发生异常. 在解锁、抹除或写入NOR FLASH区块时,特殊的指令会先写入已绘测的记忆区的第一页(Page).接着快闪记忆芯片会提供可用的指令清单给实体驱动程序,而这些指令是由一般性闪存接口(Common FLASH memory Interface, CFI)所界定的. 与用于随机存取的ROM不同,NOR FLASH也可以用在存储设备上;不过与NAND FLASH相比,NOR FLASH的写入速度一般来说会慢很多.
NOR Flash 和 NAND Flash
由1988年INTEL公司首先开发出NOR FLASH技术,彻底颠覆了原先EPROM和EEPROM一统天下的局面;紧接1989年东芝公司发表了NAND FLASH结构,强调以成本为主,降低每bit的成本,具有更高的性能,并且能像硬盘一样可以通过接口轻松升级.NOR FLASH和NAND FLASH是目前市面上两种主要的非易失闪存技术.NOR FLASH 的特点是芯片内执行(XIP ,eXecute In Place),这样应用程序可以直接在FLASH闪存内运行,不必再把代码读到系统RAM中.NOR 的传输效率很高,在1~4MB的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响到它的性能.NAND的结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快.应用NAND的困难在于FLASH的管理和需要特殊的系统接口.通常NOR的速度比NAND稍快一些,而NAND的写入速度比NOR快很多,在设计中应该考虑这些情况.
NOR Flash与NAND Flash的比较
NAND结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快.应用NAND的困难在于FLASH的管理和需要特殊的系统接口.
由于擦除NOR器件时是以64~128KB的块进行的,执行一个写入/擦除操作的时间为5s,与此相反,擦除NAND器件是以8~32KB的块进行的,执行相同的操作最多只需要4ms.
NOR FLASH带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节.
NAND器件使用复杂的I/O口来串行地存取数据,各个产品或厂商的方法可能各不相同.8个引脚用来传送控制、地址和数据信息.
NAND读和写操作采用512字节的块,这一点有点像硬盘管理此类操作,很自然地,基于NAND的存储器就可以取代硬盘或其他块设备.
NAND FLASH的单元尺寸几乎是NOR器件的一半,由于生产过程更为简单,NAND结构可以在给定的模具尺寸内提供更高的容量,也就相应地降低了价格.
采用flahs介质时一个需要重点考虑的问题是可靠性.对于需要扩展MTBF的系统来说,FLASH是非常合适的存储方案.可以从寿命(耐用性)、位交换和坏块处理三个方面来比较NOR和NAND的可靠性.
NOR Flash的烧写方式
ARM 可以说是目前最流行的32位嵌入式处理器.在这里只提一下 ARM 处理器的寻址,为后面做个铺垫.从处理器的角度来看,系统中每个地址对应的是一个BYTE的数据单元.这和很多别的处理器都是一样的.
1. 一般来说,ARM处理器内部要设置相应的寄存器,告诉处理器外部扩展的FLASH的位宽(8-BIT/16-BIT/32-BIT) .这样,处理器才知道在访问的时候如何从FLASH正确的读取数据.
3. 如果处理器支持内部设置地址错位,在实际访问的时候,送出的地址实际上是在MCU内部做了错位处理,其作用是等效于硬件连接上的错位的.
上面的描述可能比较抽象,下面让我们来看2个 ARM处理器访问16-BIT FLASH的例子:
例子 1:ARM处理器需要从地址 0x0 读取一个 BYTE
2 – 16-BIT FLASH在自己的地址信号An-A0上看到的地址是0x0,然后将地址0x0对应的16-BIT数据单元输出到D15-D0上;
3 – ARM处理器知道访问的是16-BIT的FLASH,从D7-D0上读取所需要的一个BYTE的数据;
例子 2:ARM处理器需要从地址 0x1 读取一个 BYTE
2 – 16-BIT FLASH在自己的地址信号An-A0上看到的地址依然是0x0, 然后将地址0x0对应的16-BIT数据单元输出到D15-D0上;
3 –ARM处理器知道访问的是16-BIT的FLASH,从D15-D8 上读取所需要的一个BYTE 的数据;
4. 从软件角度来看 ARM 处理器和 NOR FLASH 的连接
1 – ARM处理器访问8-BIT FLASH的时候,地址是一一对应的;
2 – ARM处理器访问16-BIT FLASH的时候,地址肯定是错位的.这一点对理解后面的例子会很有帮助.
5. 8-BIT FLASH 烧写驱动实例 - HY29F040
HY29F040是现代公司的一款8-BIT的NOR FLASH.在这个小节里,我们以这个芯片为例子,介绍如何对8-BIT NOR FLASH进行操作.
下面,我们来看看如何实现基本的擦除和编程操作.在本节后面的描述中,我们使用了下面的2 个定义:
U32 sysbase; //该变量用来表示 FLASH 的起始地址
#define SysAddr8(sysbase, offset) ((volatile U8*)(sysbase)+(offset)) //用来方便对指定的 FALSH 地址进行操作
*SysAddr8(0x10000000, 0x1) = 0xAB;
*SysAddr8(sysbase, 0x5555) = 0xAA; //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55; //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0x80; //将值 0x80 写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x5555) = 0xAA; //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55; //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0x10; //将值 0x10 写到 FLASH 地址 0x5555
6 – 将 0x30 写到要擦除的 SECTOR 对应的地址
*SysAddr8(sysbase, 0x5555) = 0xAA; //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55; //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0x80; //将值 0x80 写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x5555) = 0xAA; //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55; //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, addr) = 0x30; //将值 0x30 写到要擦除的 SECTOR 对应的地址
写一个BYTE 的数据到FLASH中去,需要 4个周期的总线写操作
*SysAddr8(sysbase, 0x5555) = 0xAA; //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55; //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0xA0; //将值 0xA0 写到 FLASH 地址 0x5555
*SysAddr8(sysbase, addr) = data; //将一个 BYTE的数据写到期望的地址
6. 16-BIT FLASH 烧写驱动实例 - SST39VF160
U32 sysbase; //该变量用来表示 FLASH 的起始地址
#define SysAddr16(sysbase, offset) ((volatile U16*)(sysbase)+(offset)) //用来方便对指定的 FALSH 地址进行操作
*SysAddr16(0x10000000, 0x0) = 0xABCD;
*SysAddr16(0x10000000, 0x1) = 0xABCD;
接下来,我们分别从ARM处理器的角度和FLASH的角度来具体分析一下.
处理器输出的地址往右做了一个移位操作,刚好对应的是FLASH的第1 个HALF-WORD.同时,FLASH会在自己的D15-D0上看到数据0xABCD.
2.在SST39VF160的命令定义中,所有的地址都是针对FLASH的HALF-WORD地址,指的是在FLASH自己的地址信号An-A0上看到的地址.
1 – 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555
2 – 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
3 – 将 0x0080 写到 FLASH HALF-WORD地址 0x5555
4 – 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555
5 – 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
6 – 将 0x0010 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x5555) = 0x00AA; //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055; //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x0080; //将值 0x0080 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x5555) = 0x00AA; //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055; //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x0010; //将值 0x0010 写到 FLASH HALF-WORD地址 0x5555
1 – 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555
2 – 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
3 – 将 0x0080 写到 FLASH HALF-WORD地址 0x5555
4 – 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555
5 – 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
6 – 将 0x0030 写到要擦除的 SECTOR 对应的 HALF-WORD地址
*SysAddr16(sysbase, 0x5555) = 0x00AA; //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055; //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x0080; //将值 0x0080 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x5555) = 0x00AA; //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055; //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, addr >> 1) = 0x0030; //将值 0x0030 写到要擦除的 SECTOR 对应的
*SysAddr16(sysbase, 0x0 >> 1) = 0x0030;
*SysAddr16(sysbase, 0x1000 >> 1) = 0x0030;
写一个HALF-WORD的数据到FLASH中去,需要4个周期的总线写操作
1 – 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555
2 – 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
3 – 将 0x00A0 写到 FLASH HALF-WORD 地址 0x5555
4 – 将编程数据(HALF-WORD)写到对应的 HALF-WORD地址
*SysAddr16(sysbase, 0x5555) = 0x00AA; //将值 0x00AA 写到 FLASH 地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055; //将值 0x0055 写到 FLASH 地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x00A0; //将值 0x00A0 写到 FLASH 地址 0x5555
*SysAddr16(sysbase, addr >> 1) = data; //将数据写到对应的 HALF-WORD 地址
举例说明,如果要数据 0x0123 写到地址 0x0 去,对应的是 FLASH 的第 0 个 HAFL-WORD,对应的 HALF-WORD 地址应该是0x0,上面代码的第4条指令应该是:
*SysAddr16(sysbase, 0x0 >> 1) = 0x0123;
如果要数据0x4567写到地址0x2去, 对应的是FLASH的第1个 HALF-WORD, 对应的HALF-WORD地址应该是0x1, 上面代码的第4条指令应该是:
*SysAddr16(sysbase, 0x2 >> 1) = 0x4567;
如果要数据0x89AB写到地址0x4去, 对应的是FLASH的第2个HALF-WORD, 对应的HALF-WORD地址应该是0x2,上面代码的第4条指令应该是:
*SysAddr16(sysbase, 0x4 >> 1) = 0x89AB;
如果要数据 0xCDEF 写到地址 0x6 去,对应的是 FLASH 的第 3 个 HALF-WORD,对应的 HALF-WORD 地址应该是0x3,上面代码的第4条指令应该是:
*SysAddr16(sysbase, 0x6 >> 1) = 0xCDEF;
源代码下载链接:Http://www.hjtag.com/forum/forumdisplay.php?fid=3
这篇文章简单介绍了如何对NOR FLASH进行操作, 但没有包括状态查询, 保护等其他操作. 对于更复杂的多片FLASH并联的情况也没有讨论.有需要的朋友可以自己去研究.
Nor Flash 在实际应用中的读取方式
进入自动选择(Autoselect Command)模式后需要发送复位命令才能回到数据读取状态(Reading Array Data).
3.引脚15为RYBY#输出引脚.用于输出Ready与Busy信号.实际用时可以不接.可用命令查询NorFLASH状态代替.
上图中表明 读id共有4个指令周期,钱3个为写周期,最后一个为读周期;
#define FLASH_base 0x00000000 //FLASH接到bank0上
#define CMD_ADDR0 *((volatile U16 *)(0x555*2+FLASH_base))
#define CMD_ADDR1 *((volatile U16 *)(0x2aa*2+FLASH_base))
#define CMD_ADDR2 *((volatile U16 *)(0xaaa*2+FLASH_base))
CMD_ADDR0 = 0xaa; CMD_ADDR1 = 0x55; CMD_ADDR0 = 0x90;
i = (*(U16 *)(0*2+FLASH_base))<<16;//Manufacturer ID = 01
CMD_ADDR0 = 0xaa; CMD_ADDR1 = 0x55; CMD_ADDR0 = 0x90;
i |= *(U16 *)(1*2+FLASH_base);//device ID = 2249
void Am29LV800D_SectorErase(U32 SA)
CMD_ADDR0 = 0xAA; CMD_ADDR1 = 0x55; CMD_ADDR0 = 0x80;
CMD_ADDR0 = 0xAA; CMD_ADDR1 = 0x55;//Word 模式命令序列
*((volatile U16 *)(SA)) = 0x30;
int Am29LV800D_WordProg (U32 PA,U16 PD)
CMD_ADDR0 = 0xAA; CMD_ADDR1 = 0x55; CMD_ADDR0 = 0xA0;
*((volatile U16 *)(PA)) = PD;// word模式,以上为4个命令周期
return(Waitfor_endofprg());//状态查询
4.写操作状态(WRITE OPERATION STATUS)
DQ7:Data# Polling bit,DQ7在编程时的状态变化.
在编程过程中从正在编程的地址中读出的数据的DQ7为要写入数据的补码.比如写入的数据为0x0000,及输入的DQ7为'0',则在编程中读出的数据为'1';当编程完成时读出的数据又变回输入的数据即'0'.
在擦除过程中DQ7输出为'0';擦除完成后输出为'1';注意读取的地址必须是擦除范围内的地址.
在编程和擦除期间,读任意地址都会导致DQ6的轮转(0,1间相互变换)当操作完成后,DQ6停止转换.
DQ2:轮转位2(Toggle Bit 2).当某个扇区被选中擦除时,读有效地址(地址都在擦除的扇区范围内)会导致DQ2的轮转.
以上讲了这些状态为,实际只需要使用几个就行,比较简单的就是选择DQ5,DQ6/DQ2.如下例.
/****** Am29LV800D 的检测 ******/
old=*((volatile U16 *)0x0);//先读一次状态
FLASHStatus=*((volatile U16 *)0x0);//再读一次状态
if( (old&0x40) == (FLASHStatus&0x40) ) break;//比较DQ6.相同说明设备已经就绪
if( FLASHStatus&0x20 ) //判断DQ5,为'1'则超时
FLASHStatus=*((volatile U16 *)0x0);//在读取比较一次.因为可能在超时前刚好玩
转载于:https://www.cnblogs.com/zhangshitong/p/3923873.html
NOR Flash的学习相关推荐
- Flash/Flex学习笔记(30):不用startDrag和stopDrag的对象拖动
对于从Sprite类继承来的对象,要实现拖放当然是Flash/Flex学习笔记(13):对象拖动(startDrag/stopDrag) 里讲的方法最方便,但是对于不是从Sprite类继承得来的对象, ...
- Flash动画学习指南七:运动路径
转自:http://bbs.9ria.com/thread-76164-1-1.html 本帖最后由 chocoZero 于 2011-3-16 14:18 编辑 准备知识:Flash工作空间的基本知 ...
- Flash动画学习指引六:操作动作补间
转自:http://bbs.9ria.com/thread-75053-1-1.html 要求 需求知识 Flash 工作空间基本知识. 用户级别 开始级 需求 • Flash ...
- Flash/Flex学习笔记(51):3维旋转与透视变换(PerspectiveProjection)
Flash/Flex学习笔记(49):3D基础 里已经介绍了3D透视的基本原理,不过如果每次都要利用象该文中那样写一堆代码,估计很多人不喜欢,事实上AS3的DisplayObject类已经内置了z坐标 ...
- Flash/Flex学习笔记(50):3D线条与填充
3D线条:把上一篇中的3D坐标旋转示例稍做修改,用线把各个小球连接起来即可. var balls:Array; var numBalls:uint=30;var fl:Number=250; var ...
- flash动画学习指南八:动画编辑器
转自:http://bbs.9ria.com/thread-74790-1-1.html --要求: 必要知识:flash工作区的基本知识 需要的工具:flash CS4(下载试用版) 实例文件:mo ...
- Flash XSS 学习整理
0x00 Flash XSS 本来想放弃的,问了大佬,还是说可以研究下...所以硬着头皮来弄了. 什么是flash xss? xss一是指执行恶意js,那flash xss呢?是因为flash有可以调 ...
- Flash/Flex学习笔记(4):如何打开网页及Get/Post数据
flash终究只是客户端技术,所以很多时候还是需要与服务端技术(比如asp,asp.net,jsp,php之类)进行数据交互的,下面的代码演示了如何在flash中打开网页,以及用GET/POST二种方 ...
- Flash/Flex学习笔记(53):利用FMS快速创建一个文本聊天室
先来看客户端fla的构成: 第一帧:登录界面 第一帧的代码: show sourceview source print? 01 import flash.events.MouseEvent; 02 i ...
最新文章
- 70页论文,图灵奖得主Yoshua Bengio一作:“生成流网络”拓展深度学习领域
- jQuery 发送 AJAX 请求
- 多线程:为什么wait()需要放在循环中?
- [转]Postgres-XL 10r1英文文档
- java生成bcp_java-如何将IETF BCP 47语言代码转换为显示字符串?
- linux mail使用笔记
- web应用,HTTP协议以及Django初次认识与安装
- Vi编辑器编写Hello World程序
- 【仿人机器人】机器人基础介绍
- 卖肉了也没火的十大悲催女星
- Work Breakdown Structure
- Linux环境批量下载阿里云盘资源
- 华为移动应用引擎安装第三方apk教程
- dell inspiron 只有一个飞行模式 没有wifi_连上WiFi就能打电话?“手机营业厅”中的神奇功能火了...
- Verilog除法器(32位无符号+带符号)
- 流利阅读 2019.2.23 China’s Forbidden City opens to the general public at night for the first time in 94
- 总结用过的几个视频同步分离电路--LM1881
- ChinaSoft 论坛巡礼 | CCF-华为胡杨林基金-形式化方法专项论坛
- 黑马pink老师:CSS基础 总结Ⅰ
- Python第三方库
热门文章
- 关于Python user32.dll SetWindowPos调用无效的问题的解决方案
- iOS形变之CGAffineTransform
- 法师虽脆弱,但是升级刷怪经验要比其他角色快
- docker-compose使用
- 极速office2021怎么将PPT背景设置为渐变的
- 魔方机器人需要特制魔方吗_资深DIY玩儿家教你如何打造魔方机器人
- Antd DatePicker 限制日期
- C语言期末集训2(大一,超基础,小猫猫大课堂的配套练习)——分支结构
- Java中时间格式 yyyyMMdd和yyyy-MM-dd相互转换
- 2023.7.8每日一题