NOR Flash

发布时间:2024-05-27 13:22:39 作者:汉语成语

NORFLASH是INTEL在1988年推出的一款商业性闪存芯片,它需要很长的时间进行抹写,大半生它能够提供完整的寻址与数据总线,并允许随机存取存储器上的任何区域,而且它可以忍受一万次到一百万次抹写循环,是早期的可移除式闪存储媒体的基础。

访问方式

在NORFLASH的读取数据的方式来看,它与RAM的方式是相近的,只要能够提供数据的地址,数据总线就能够正确的挥出数据。考虑到以上的种种原因,多数微处理器将NORFLASH当做原地运行(Executeinplace,XIP)存储器使用,这其实以为着存储在NORFLASH上的程序不需要复制到RAM就可以直接运行。由于NORFLASH没有本地坏区管理,所以一旦存储区块发生毁损,软件或驱动程序必须接手这个问题,否则可能会导致设备发生异常。在解锁、抹除或写入NORFLASH区块时,特殊的指令会先写入已绘测的记忆区的页(Page)。接着快闪记忆芯片会提供可用的指令清单给实体驱动程序,而这些指令是由一般性闪存接口(CommONFLASHmemoryInterface,CFI)所界定的。与用于随机存取的ROM不同,NORFLASH也可以用在存储设备上;不过与NANDFLASH相比,NORFLASH的写入速度一般来说会慢很多。

烧写方式

相对于硬件工程师和嵌入式软件工程师一般在完成设计之后常常需要验证FLASH是否在工作。在应用当中,也有很多时候需要对FLASH进行写操作。该文章简单介绍了基于ARM芯片的NORFLASH烧写,并提供了2个具体的实例和源代码,希望对有需要的朋友有点帮助。在开始之前,先声明一下,这篇文章只是介绍了如何写NORFLASH的烧写驱动,和H-JTAG/H-FLASHER没有直接的联系。

在后面的介绍里,如无特别说明,处理器指的是ARM处理器,FLASH指的都是NORFLASH。另外,BYTE指的是8-BIT的数据单元,HALF-WORD代表的是16-BIT的数据单元,而WORD则代表了32-BIT的数据单元。

1。NORFLASH的简单介绍

NORFLASH是很常见的一种存储芯片,数据掉电不会丢失。NORFLASH支持ExecuteONChip,即程序可以直接在FLASH片内执行。这点和NANDFLASH不一样。因此,在嵌入是系统中,NORFLASH很适合作为启动程序的存储介质。

NORFLASH的读取和RAM很类似,但不可以直接进行写操作。对NORFLASH的写操作需要遵循特定的命令序列,最终由芯片内部的控制单元完成写操作。从支持的最小访问单元来看,NORFLASH一般分为8位的和16位的(当然,也有很多NORFLASH芯片同时支持8位模式和是16位模式,具体的工作模式通过特定的管脚进行选择)。对8位的NORFLASH芯片,或是工作在8-BIT模式的芯片来说,一个地址对应一个BYTE(8-BIT)的数据。例如一块8-BIT的NORFLASH,假设容量为4个BYTE。那芯片应该有8个数据信号D7-D0和2个地址信号,A1-A0。地址0x0对应第0个BYTE,地址0x1对应于第1BYTE,地址0x2对应于第2个BYTE,而地址0x3则对应于第3个BYTE对16位的NORFLASH芯片,或是工作在16-BIT模式的芯片来说,一个地址对应于一个HALF-WORD(16-BIT)的数据。例如,一块16-BIT的NORFLASH,假设其容量为4个BYTE。那芯片应该有16个数据信号线D15-D0和1个地址信号A0。地址0x0对应于芯片内部的第0个HALF-WORD,地址0x1对应于芯片内部的第1个HALF-WORD。FLASH一般都分为很多个SECTOR,每个SECTOR包括一定数量的存储单元。对有些大容量的FLASH,还分为不同的BANK,每个BANK包括一定数目的SECTOR。FLASH的擦除操作一般都是以SECTOR,BANK或是整片FLASH为单位的。

在对FLASH进行写操作的时候,每个BIT可以通过编程由1变为0,但不可以有0修改为1。为了保证写操作的正确性,在执行写操作前,都要执行擦除操作。擦除操作会把FLASH的一个SECTOR,一个BANK或是整片FLASH的值全修改为0xFF。这样,写操作就可以正确完成了。

2。ARM处理器的寻址

ARM可以说是目前的32位嵌入式处理器。在这里只提一下ARM处理器的寻址,为后面做个铺垫。从处理器的角度来看,系统中每个地址对应的是一个BYTE的数据单元。这和很多别的处理器都是一样的。

3。处理器和NORFLASH的硬件连接

从前面的介绍,我们知道从处理器的角度来看,每个地址对应的是一个BYTE的数据单元。而,NORFLASH的每个地址有可能对应的是一个BYTE的数据单元,也有可能对应的是一个HALF-WORD的数据单元。所以在硬件设计中,连接ARM处理器和NORFLASH时,必须根据实际情况对地址信号做特别的处理。

如果ARM处理器外部扩展的是8-BIT的NORFLASH,数据线和地址线的连接应该如图1所示。从图中我们可以看到,处理器的数据信号D0-D7和FLASH的数据信号D0-D7是一一对应连接的,处理器的地址信号A0-An和NORFLASH的地址信号A0-An也是一一对应连接的。

如果ARM处理器外部扩展的是16-BIT的NORFLASH,数据线必须要错位连接。图2给了一个ARM处理器和16-BITNORFLASH的连接示意图。如图2所示,ARM处理器的数据信号D0-D15和FLASH的数据信号D0-D15是一一对应的。而ARM处理器的地址信号和NORFLASH的地址信号是错位连接的,ARM的A0悬空,ARM的A1连接FLASH的A0,ARM的A2连接FLASH的A1,依次类推。需要错位连接的原因是:ARM处理器的每个地址对应的是一个BYTE的数据单元,而16-BIT的FLASH的每个地址对应的是一个HALF-WORD(16-BIT)的数据单元。为了保持匹配,所以必须错位连接。这样,从ARM处理器发送出来的地址信号的位A0对16-BITFLASH来说就被屏蔽掉了。

补充说明:

1。一般来说,ARM处理器内部要设置相应的寄存器,告诉处理器外部扩展的FLASH的位宽(8-BIT/16-BIT/32-BIT)。这样,处理器才知道在访问的时候如何从FLASH正确的读取数据。

2。有些ARM处理器内部可以设置地址的错位。对于支持软件选择地址错位的处理器,在连接16-BITFLASH的时候,硬件上可以不需要把地址线错位。读者设计的时候,请参考MCU的数据手册,以手册为准,以免造成不必要的麻烦。

3。如果处理器支持内部设置地址错位,在实际访问的时候,送出的地址实际上是在MCU内部做了错位处理,其作用是等效于硬件连接上的错位的。

上面的描述可能比较抽象,下面让我们来看2个ARM处理器访问16-BITFLASH的例子:

例子1:ARM处理器需要从地址0x0读取一个BYTE

1-ARM处理器在地址线An-A0上送出信号0x0;

2–16-BITFLASH在自己的地址信号An-A0上看到的地址是0x0,然后将地址0x0对应的16-BIT数据单元输出到D15-D0上;

3–ARM处理器知道访问的是16-BIT的FLASH,从D7-D0上读取所需要的一个BYTE的数据;

例子2:ARM处理器需要从地址0x1读取一个BYTE

1-ARM处理器在地址线An-A0上送出信号0x1;

2–16-BITFLASH在自己的地址信号An-A0上看到的地址依然是0x0,然后将地址0x0对应的16-BIT数据单元输出到D15-D0上;

3–ARM处理器知道访问的是16-BIT的FLASH,从D15-D8上读取所需要的一个BYTE的数据;

4。从软件角度来看ARM处理器和NORFLASH的连接

在上一个小节里,我们简单了解了ARM处理器和FLASH的硬件连接。在这个小节里面,我们从软件的角度来理解ARM处理器和FLASH的连接。对于8-BIT的FLASH的连接,很好理解,因为ARM处理器和8-BITFLASH的每个地址对应的都是一个BYTE的数据单元。所以地址连接毫无疑问是一一对应的。如果ARM处理器连接的是16-BIT的处理器,因为ARM处理器的每个地址对应的是一个BYTE的数据单元,而16-BITFLASH的每个地址对应的是一个HALF-WORD的16-BIT的数据单元。所以,也毫无疑问,ARM处理器访问16-BIT处理器的时候,地址肯定是要错开一位的。在写FLASH驱动的时候,我们不需要知道地址错位是由硬件实现的,还是是通过设置ARM处理器内部的寄存器来实现的,只需要记住2点:

1–ARM处理器访问8-BITFLASH的时候,地址是一一对应的;

2–ARM处理器访问16-BITFLASH的时候,地址肯定是错位的。这一点对理解后面的例子会很有帮助。

5。8-BITFLASH烧写驱动实例-HY29F040

HY29F040是现代公司的一款8-BIT的NORFLASH。在这个小节里,我们以这个芯片为例子,介绍如何对8-BITNORFLASH进行操作。

HY29F040的容量为512K-BYTE,总共包括8个SECTOR,每个SECTOR的容量是64K-BYTE。该芯片支持SECTOR擦除,整片擦除和以BYTE为基本单位的写操作。HY29F040的命令定义如表-1所示。

下面,我们来看看如何实现基本的擦除和编程操作。在本节后面的描述中,我们使用了下面的2个定义:

U32sysbase;//该变量用来表示FLASH的起始地址

#defineSysADDR8(sysbase,offset)((volatileU8*)(sysbase)+(offset))//用来方便对指定的FALSH地址进行操作

先解释一下SysAddr8的定义。这个宏定义了一个BYTE(8-BIT)指针,其地址为(sysbase+offset)。假设FLASH的起始地址为0x10000000,如果要将0xAB写到FLASH的个BYTE中去,可以用下面的代码:

*SysAddr8(0x10000000,0x1)=0xAB;

注意:

在本节后面的描述中,SYSBASE代表的是FLASH的起始地址,而SysAddr8中的OFFSET则代表了相对于FLASH起始地址的BYTE偏移量。OFFSET也是8-BITFLASH在自己的地址信号An-A0上看到的地址。

整片擦除操作

整片擦除操作共需要6个周期的总线写操作

1–将0xAA写到FLASH地址0x5555

2–将0x55写到FLASH地址0x2AAA

3–将0x80写到FLASH地址0x5555

4–将0xAA写到FLASH地址0x5555

5–将0x55写到FLASH地址0x2AAA

6–将0x10写到FLASH地址0x5555

对应的代码:

*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

SECTOR擦除操作

SECTOR的擦除操作共需要6个周期的总线写操作

1–将0xAA写到FLASH地址0x5555

2–将0x55写到FLASH地址0x2AAA

3–将0x80写到FLASH地址0x5555

4–将0xAA写到FLASH地址0x5555

5–将0x55写到FLASH地址0x2AAA

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编程操作

写一个BYTE的数据到FLASH中去,需要4个周期的总线写操作

1–将0xAA写到FLASH地址0x5555

2–将0x55写到FLASH地址0x2AAA

3–将0xA0写到FLASH地址0x5555

4–将编程数据(BYTE)写到对应的编程地址上去

对应的代码:

*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-BITFLASH烧写驱动实例-SST39VF160

SST39VF160是SST公司的一款16-BIT的NORFLASH。在这个小节里,我们以SST39VF160为例子,介绍如何对16-BITNORFLASH进行操作。对8-BITFLASH的操作很好理解,但对16-BITFLASH的操作理解起来要晦涩很多。我尽力描述得清楚些。

SST39VF160的容量为2M-BYTE,总共包括512个SECTOR,每个SECTOR的容量是4K-BYTE。该芯片支持SECTOR擦除,整片擦除和以HALF-WORD为基本单位的写操作。SST39VF160的命令定义如表-2所示。在表2中,因为所有命令都是从FLASH的角度来定义的。所以,所有的地址都是HALF-WORD地址,指的是16-BITFLASH在自己的地址信号An-A0上看到的地址。

在本节后面的描述中,我们使用了下面的2个定义:

U32sysbase;//该变量用来表示FLASH的起始地址

#defineSysAddr16(sysbase,offset)((volatileU16*)(sysbase)+(offset))//用来方便对指定的FALSH地址进行操作

SysAddr16(sysbase,offset)首先定义了一个16-BITHALF-WORD的指针,指针的地址为sysbase,然后根据offset做个偏移操作。因为HALF-WORD指针的地址是2个BYTE对齐的,所以每个偏移操作会使得地址加2。最终,SysAddr16(sysbase,offset)相当于定义了一个HALF-WORD的指针,其最终地址为(sysbase+2offset)。在使用SysAddr16的时候,将sysbase设置成FLASH的起始地址,offset则可以理解为相对于FLASH起始地址的HALF-WORD偏移量或是偏移地址。假设FLASH的起始地址为0x10000000,SysAddr16(0x10000000,0)指向16-BITFLASH的第0个HALF-WORD,SysAddr16(0x10000000,1指向16-BITFLASH的第1个HALF-WORD。依次类推。如果要将0xABCD分别写到FLASH的第0个和第1个HALF-WORD中去,可以用下面的代码:

*SysAddr16(0x10000000,0x0)=0xABCD;

*SysAddr16(0x10000000,0x1)=0xABCD;

接下来,我们分别从ARM处理器的角度和FLASH的角度来具体分析一下。

从ARM的角度来看:

假设FLASH的起始地址为0x10000000,因为ARM处理器知道FLASH的地址空间为0x10000000~(0x10000000+FLASH容量–1),所以在对这个地址空间进行访问的时候,会设置好FLASH的片选信号,并将低位的地址输出到地址信号上。以*SysAddr16(0x10000000,0x1)=0xABCD为例。从ARM处理器的角度来看,该操作是把0xABCD写到地址0x10000002上去。所以ARM处理器最终会在它的地址信号An-A0输出地址0x2,同时会在D15-D0上输出0xABCD。

从FLASH的角度来看:

还是以*SysAddr16(0x10000000,0x1)=0xABCD为例,FLASH看到的地址是多少呢?接着分析。ARM处理器在执行操作的时候,会设置好相应的FLASH片选使能信号,并在ARM的地址信号An-A0上输出0x2。因为ARM和16-BITFLASH的地址信号的连接是错开一位的,所以,FLASH最终在自己的地址An-A0上看到的信号是0x1,相当于将ARM

处理器输出的地址往右做了一个移位操作,刚好对应的是FLASH的第1个HALF-WORD。同时,FLASH会在自己的D15-D0上看到数据0xABCD。

通过上面的分析,我们知道SysAddr16中指定的offset的值就是16-BITFLASH在自己的地址An-A0上看到的值。所以,我们可以很方便的通过SysAddr16(sysbase,offset)对FLASH进行操作,其中sysbase代表FLASH起始地址,offset则代表了FLASH的第几个HALF-WORD(HALF-WORD偏移量或偏移地址)。

注意:

1。在本节后面的描述中,SysAddr16中的SYSBASE代表的是FLASH的起始地址,而SysAddr16中的OFFSET则代表了相对于FLASH起始地址的HALF-WORD偏移量或偏移地址。OFFSET的值也是16-BITFLASH在自己的地址信号An-A0上看到的值。

2。在SST39VF160的命令定义中,所有的地址都是针对FLASH的HALF-WORD地址,指的是在FLASH自己的地址信号An-A0上看到的地址。

整片擦除操作

整片擦除操作共需要6个周期的总线写操作

1–将0x00AA写到FLASHHALF-WORD地址0x5555

2–将0x0055写到FLASHHALF-WORD地址0x2AAA

3–将0x0080写到FLASHHALF-WORD地址0x5555

4–将0x00AA写到FLASHHALF-WORD地址0x5555

5–将0x0055写到FLASHHALF-WORD地址0x2AAA

6–将0x0010写到FLASHHALF-WORD地址0x5555

对应的代码:

*SysAddr16(sysbase,0x5555)=0x00AA;//将值0x00AA写到FLASHHALF-WORD地址0x5555

*SysAddr16(sysbase,0x2AAA)=0x0055;//将值0x0055写到FLASHHALF-WORD地址0x2AAA

*SysAddr16(sysbase,0x5555)=0x0080;//将值0x0080写到FLASHHALF-WORD地址0x5555

*SysAddr16(sysbase,0x5555)=0x00AA;//将值0x00AA写到FLASHHALF-WORD地址0x5555

*SysAddr16(sysbase,0x2AAA)=0x0055;//将值0x0055写到FLASHHALF-WORD地址0x2AAA

*SysAddr16(sysbase,0x5555)=0x0010;//将值0x0010写到FLASHHALF-WORD地址0x5555

SECTOR擦除操作

SECTOR的擦除操作共需要6个周期的总线写操作

1–将0x00AA写到FLASHHALF-WORD地址0x5555

2–将0x0055写到FLASHHALF-WORD地址0x2AAA

3–将0x0080写到FLASHHALF-WORD地址0x5555

4–将0x00AA写到FLASHHALF-WORD地址0x5555

5–将0x0055写到FLASHHALF-WORD地址0x2AAA

6–将0x0030写到要擦除的SECTOR对应的HALF-WORD地址

对应的代码:

*SysAddr16(sysbase,0x5555)=0x00AA;//将值0x00AA写到FLASHHALF-WORD地址0x5555

*SysAddr16(sysbase,0x2AAA)=0x0055;//将值0x0055写到FLASHHALF-WORD地址0x2AAA

*SysAddr16(sysbase,0x5555)=0x0080;//将值0x0080写到FLASHHALF-WORD地址0x5555

*SysAddr16(sysbase,0x5555)=0x00AA;//将值0x00AA写到FLASHHALF-WORD地址0x5555

*SysAddr16(sysbase,0x2AAA)=0x0055;//将值0x0055写到FLASHHALF-WORD地址0x2AAA

*SysAddr16(sysbase,addr>>1)=0x0030;//将值0x0030写到要擦除的SECTOR对应的

HALF-WORD地址

注意:

上面的代码中第6个操作周期中的ADDR是从ARM处理器的角度来看的BYTE地址,因为在擦除的时候,用户希望指定的是从ARM的角度看到的地址,这样更方便和更直观。而在SysAddr16的宏定义中,OFFSET表示的是相对于FLASH起始地址的HALF-WORD偏移量,或是FLASH在自己的地址信号An-A0上看到的地址。所以需要执行一个右移操作,把ADDR转换成HALF-WORD地址。

举例说明,SST39VF160每个SECTOR的大小是4K-BYTE。从ARM处器的角度和用户的角度来看,SECTOR-0相对于FLASH起始地址的BYTE地址是0x0;从FLASH来看SECTOR-0的HALF-WORD地址是0x0。从ARM处理器的角度和用户的角度来看,FLASHSECTOR-1相对于FLASH起始地址的BYTE地址0x1000;从FLASH来看,SECTOR-1的HALF-WORD地址应该是(0x1000>>1)=0x800。

如果要擦除SECTOR-0,上面代码的第6条指令应该是:

*SysAddr16(sysbase,0x0>>1)=0x0030;

如果要擦除SECTOR-1,上面代码的第6条指令应该是:

*SysAddr16(sysbase,0x1000>>1)=0x0030;

HALF-WORD编程操作

写一个HALF-WORD的数据到FLASH中去,需要4个周期的总线写操作

1–将0x00AA写到FLASHHALF-WORD地址0x5555

2–将0x0055写到FLASHHALF-WORD地址0x2AAA

3–将0x00A0写到FLASHHALF-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地址

注意:

上面的代码中第4个操作周期中的ADDR是从ARM处理器的角度来看的BYTE地址,因为在执行写操作的时候,用户希望指定的是从ARM的角度看到的地址,这样会更方便和更直观。而在SysAddr16的宏定义中,OFFSET表示的是相对于FLASH起始地址的HALF-WORD偏移量。所以需要执行一个右移操作,把它转换成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;

7。ADS版源代码下载

如果用户有需要,可以去下载在前面讨论的2个实例的ADS版的完整源代码和FLASH数据手册。提供给用户的程序都是在实际使用过程中经过测试的。源代码只供用户参考,并不一定能直接使用在用户的开发板上。用户需要根据自己实际使用的芯片进行相应的修改。

8。结束语

这篇文章简单介绍了如何对NORFLASH进行操作,但没有包括状态查询,保护等其他操作。对于更复杂的多片FLASH并联的情况也没有讨论。有需要的朋友可以自己去研究。

原理

从物理层面解释,NOR闸闪存的每个存储单元类似一个标准MOSFET,除了晶体管有两个而不是一个闸极。在顶部的是控制闸(CONTROLGate,CG),它的徐阿奴阿布是土匪以氧化物层与周遭绝缘的浮闸(FloathingGate,FG)。由于这个FG在电气程度上是出于绝缘层独立的,所以湖边人员的毒啊班组会被困在里面,在一般的条件下,电荷经过很长时间都不会产生逃逸的情况。将FG放在CG与MOSFET通道之间。当FG抓到电荷时,它部分屏蔽掉来自CG的电场,并改变这个单元的阀电压(VT)。在读出期间。利用向CG的电压,MOSFET通道会变的导电或保持绝缘。这视乎该单元的VT而定(而该单元的VT受到FG上的电荷控制)。这股电流流过MOSFET通道,并以二进制码的方式读出、再现存储的数据。在每单元存储1位以上的数据的MLC设备中,为了能够更精确的测定FG中的电荷位准,则是以感应电流的量(而非单纯的有或无)达成的。

逻辑上,单层NORFLASH单元在默认状态代表二进制码中的"1"值,因为在以特定的电压值控制闸极时,电流会流经通道。经由以下流程,NORFLASH单元可以被设置为二进制码中的"0"值。

1。对CG施加高电压(通常大于5V)。

2。现在通道是开的,所以电子可以从源极流入汲极(想像它是NMOS晶体管)。

3。源-汲电流够高了,足以导致某些高能电子越过绝缘层,并进入绝缘层上的FG,这种过程称为热电子注入。

由于汲极与CG间有一个大的、相反的极性电压,借由量子穿隧效应可以将电子拉出FG,所以能够地用这个特性抹除NORFLASH单元(将其重设为"1"状态)。现代的NORFLASH芯片被分为若干抹除片段(常称为区扇(Blocksorsectors)),抹除操作只能以这些区块为基础进行;所有区块内的记忆单元都会被一起抹除。不过一般而言,写入NORFLASH单元的动作却可以单一字节的方式进行。

虽然抹写都需要高电压才能进行,不过实际上现今所有闪存芯片是借由芯片内的电荷帮浦产生足够的电压,所以只需要一个单一的电压供应即可。