陆鹏
摘 要
本文通过分析8位并口NAND Flash的工作时序,设计其在dsPIC30F 6010A单片机下的软件驱动,能够实现对NAND Flash的读写擦除等各种操作。
关键词
NAND Flash;dsPIC30F6010A;并口;驱动
中图分类号: TP316.2 文献标识码: A
DOI:10.19694/j.cnki.issn2095-2457.2020.09.044
0 前言
NAND Flash是嵌入式设计中常见的存储器。8位并口NAND Flash是指數据线宽度为8位,通信接口为并行接口的NAND Flash,在其与微处理器的配合应用中,NAND Fla sh与微处理器一般采用如图1所示的连接方式。微处理器软件驱动的设计是根据NAND Flash的工作时序,通过配置相关寄存器进行相应操作来实现的。本文中NAND Flash使用Micron公司的MT29F2G08系列进行说明,微处理器则使用了Microchip公司的16位高性能单片机dsPIC30F6010A。
1 NAND Flash信号时序
从软件驱动角度来讲,NAND Flash最基本的操作有四种,即命令输入、地址输入、数据输入、数据输出。所有的NAND Flash接口命令都是由这四种操作组合而成,以MT29F2G08的READ PAGE命令为例,它是由两个命令输入操作(0x00,0x30)、五个地址输入操作以及若干数据输出操作组成,READ PAGE命令时序如图2所示。
因此如果在微处理上实现这四种基本操作,就能实现所有的接口命令,即实现了NAND Flash的驱动设计。
为了实现这四种操作,我们需要明确两个内容:一,四种操作中接口信号的电平;二,接口信号及各信号之间的时间要求。这两项内容均在NAND Flash的器件手册上有明确要求。以MT29F2G08为例,在它的的异步接口模式列表中(表1),我们可以得到四种操作的接口信号电平要求。以命令输入(Comm and Input)为例,从表1中可以得到接口信号电平要求为:当CE#为低,CLE为高,ALE为低,WE#的上升沿,WP#为高时,完成命令输入操作。
接口信号及各信号之间的时间要求通过时序定义来得到。命令输入的时序定义如图3所示,接口信号的时间要求在表2中列出。因命令输入发生在WE#上升沿,因此与WE#上升沿相关的几个时间是设计的关键所在:tWP写使能脉冲宽度时间-最小为10ns;tDS数据建立时间-最小7ns,即命令输入后WE#需至少保持使能7ns才可以置高;tDH数据保持时间-最少5ns,即WE#置高后命令需要至少保持5ns;tCLS命令锁存使能建立时间-最少10ns;tCLH命令锁存使能保持时间-最小为5ns,即WE#置高后CLE需至少保持为高5ns。
得到接口信号的电平和时间要求后,就可以在微处理器上编程实现对NAND Flash的各种操作。
2 软件驱动实现
在进行NAND Flash驱动编程之前,我们需要对微处理器dsPIC30F6010A的I/O按照图1所示的连接方式进行配置,分别将CE#、RE#, WE#、R/B#、ALE、CLE、WP#、I/O[7:0]配置到所需的I/O口,其中CE#、RE#、WE#、ALE、CLE、WP#为输出端口,R/B#为输入端口,I/O[7:0]在命令输入、地址输入、数据输入三种操作时为输出端口,在数据输出操作时为输入端口。时间方面,本例中dsPIC30F6010A系统时钟设置为24MHz,因此指令周期FCY为24MHz/4为6MHz,即一条指令所用时间为167ns。
以命令输入操作为例,将其定义为函数FlashWriteCmd(),为函数定义一个参数cmd,根据上一小节所讲,按照命令输入的时序要求,将函数编写如下:
void FlashWriteCmd(unsigned char cmd)
{
TRISDATA &= ~(0x00FF) ; // RE0~RE7输出
ALE=0;
CLE=1;
_nop_(); _nop_(); //tCLS
WE=0;
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();//tWP
DATAOUT= ((DATAOUT & 0xFF00) | cmd);
_nop_(); _nop_(); //tDS
WE=1;
_nop_(); _nop_(); _nop_();// tDH, tCLH
CLE=0;
}
按同样思路完成其他三种基本操作的函数编程,分别定义为:地址输入函数FlashWriteAddr(),数据输入函数Flash Wr itePort(),数据输出函数FlashReadPort(),以这四个函数为基础即可实现所有接口命令函数,下面以接口命令READ PAGE为例说明。
将READ PAGE命令定义为函数FlashReadByte(),为函数定义五个参数,Read_num读取字节数量,ByteAddr字节地址,PageAddr页地址,BlockAddr块地址,以及buf字节存储位置。如图1所示,READ PAGE命令需要首先发送命令0x00,然后发送五个周期的地址,再发送命令0x30,之后等待R/B#(RDY)信号为高后才能进行数据读取,依此函数编程如下:
void FlashReadByte(unsigned int
Read_number,unsigned int ByteAddr,unsigned
char PageAddr,unsigned int BlockAddr,unsigned
char *buf)
{
unsigned int j,
CE=0;
FlashWriteCmd(0x00); //讀命令周期1
FlashWriteAddr(ByteAddr&0xff); //写字节低位地址
FlashWriteAddr((ByteAddr>>8)&0x3f); //写字节高位地址
FlashWriteAddr(PageAddr); //写页地址
FlashWriteAddr((BlockAddr>>1)&0xff); //写块低位地址
FlashWriteAddr((BlockAddr>>9)&0x0F); //写块高位地址
FlashWriteCmd(0x30); //读命令周期2
delay_us(20);
NAND_WAITREADY();//等待RDY信号置高
for(j=0;j { ClrWdt(); *buf=FlashReadPort(); //读取数据 buf++; } CE=1; } 依照类似方法可实现NAND Flash规定的所有接口命令。需要注意的是在实现函数时,要将时间留出余量,以免出现异常错误。 3 结论 本文介绍的驱动程序已经应用在项目中,实际结果显示程序功能正确、稳定可靠。虽然驱动是基于dsPIC30F6010A单片机,但其方法可以用于任意微处理器,此外驱动可适用于任何符合ONFI1.0标准的NAND Flash器件,有良好的通用性。 参考文献 [1]Rino Micheloni,Luca Crippa,Alessia Marelli.Inside NAND Flash Memories. [2]MT29F2G08 NAND Flash Memory Datasheet.Micron Technology,Inc. [3]dsPIC30F6010A/6015 Datasheet.Microchip Technology,Inc.