08-Nand flash

本文详细介绍了NAND Flash的操作原理,包括NAND Flash的PCB原理、操作步骤、时序图和U-boot的读ID、读数据过程。内容涉及NAND Flash的地址传输、命令传输、数据线的干扰避免、读写完成的判断以及S3C2440与NAND Flash的交互。此外,还探讨了NAND Flash的初始化、芯片ID读取、数据读取和擦除烧写等操作。
摘要由CSDN通过智能技术生成

声明:

本文是本人在韦东山笔记的基础上加了一些注释,方便理解。原文地址:http://wiki.100ask.org/%E7%AC%AC016%E8%AF%BE_Nand_Flash#.E7.AC.AC001.E8.8A.82_NAND_FLASH.E6.93.8D.E4.BD.9C.E5.8E.9F.E7.90.86

第1节 Nand flash操作原理

1.1 几个问题

首先看一下Nand flash的PCB原理图:
在这里插入图片描述
可以看出,NAND FLASH是一个存储芯片
那么: 这样的操作很合理即----“读地址A的数据,把数据B写到地址A”

问1. 原理图上NAND FLASH和S3C2440之间只有数据线,怎么传输地址?
答1.在DATA0~DATA7上既传输数据,又传输地址。当ALE为高电平时传输的是地址,

那么在数据线上是不是只传输数据和只传输地址呢?
我们参考NAND FLASH的芯片手册可以知道,对NAND FLASH的操作还需要发出命令,下面有个NAND FLASH的命令表格:
在这里插入图片描述
问2. 从NAND FLASH芯片手册可知,要操作NAND FLASH需要先发出命令,那么怎么传入命令?
答2.在DATA0~DATA7上既传输数据,又传输地址,也传输命令:

  1. 当ALE为高电平时传输的是地址。
  2. 当CLE为高电平时传输的是命令。
  3. 当ALE和CLE都为低电平时传输的是数据。

问3. 数据线既接到NAND FLASH,也接到NOR FLASH,还接到SDRAM、DM9000等等, 那么怎么避免干扰?
答3. 这些设备,要访问之必须"选中"(CE片选引脚),没有选中的芯片不会工作,相当于没接一样。

问4. 假设烧写NAND FLASH,把命令、地址、数据发给它之后,NAND FLASH肯定不可能瞬间完成烧写的,怎么判断烧写完成?
答4. 通过状态引脚RnB来判断:它为高电平表示就绪,它为低电平表示正忙。

问5. 怎么操作NAND FLASH呢?
答5. 根据NAND FLASH的芯片手册,一般的过程是:
①发出命令
②发出地址
③发出数据/读数据

看上面的命令表格,不容易看,我们看一下读ID的时序图:
每个NAND FLASH都内嵌一些ID(譬如:厂家ID,设备ID),时序图从左往右看,纵向放是一列一列的看。
在这里插入图片描述
对于我们s3c2440来说,内部集成了一个NAND FLASH控制器,2440和外设连接的简易图,如下图所示:在这里插入图片描述

1.2 Nand flash操作

NAND FLASH控制器,帮我们简化了对NAND FLASH的操作,下面来分析一下不使用NAND FLASH控制器使用NAND FLASH控制器对外设NAND FLASH的操作:

发命令:下图中,左侧是对Nand flash发命令的具体机制原理,右侧是我们对S3C2440d的操作(即仅对NFCMMD寄存器操作,左侧中的具体步骤寄存器帮我们做了)。在这里插入图片描述
发地址,表中左侧和右侧的区别和上面的发命令一样。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3 U-boot读ID

好了,我们来体验一下使用U-boot操作Nand flash。下图(表)的左侧是我们读Nand flash芯片手册得到的读ID的步骤(读操作时序图是下下一幅图),下图(表)的中间是读ID对S3C2440的操作,右侧是如果用u-boot来操作的话u-boot的命令:
在这里插入图片描述
读操作时序图:
在这里插入图片描述
对于存储为256M的NAND FLASH,需要28条地址线,来表示这个地址值,根据原理图可以,只用8根地址线,所以需要4个周期的地址,为了兼容更大容量的NAND FLASH,要发出5个周期的地址:(如下图所示)
在这里插入图片描述

1.4 U-boot读数据

在这里插入图片描述

第02节 NandFlash时序及初始化

本节课源码见:
F:\韦东山\005_ARM裸机1期加强版(又叫新1期,151节,23节免费,已完结)\源码文档图片\源码\源码_20180321_添加传感器\019_nand_flash_016\002_chip_id_016_003

下表的左侧是对于一般存储芯片的编程步骤, 右侧是NAND FLASH存储芯片的编程步骤。

存储芯片的编程步骤 NAND FLASH存储芯片编程
初始化 主控芯片的NAND FLASH控制器的初始化
识别 读取ID
读操作 一次读一个页(page)
读操作 写操作
擦除 一次擦除一个块(block)

那么这节课我们做的就是步骤一:初始化。
在下面的几节课我们会分别讲解下剩下的编程步骤。

先来看时序图:
NAND FLASH控制器的时序,是为了让NAND FLASH这个外设 工作起来,假如外接不同的 NAND FLASH外设(即不同的 NAND FLASH芯片),那么它们的操作时序可能就会不同,所以NAND FLASH控制器发出 的时序图,就是不一样的,所以我们根据NAND FLASH外设来设置NAND FLASH控制器。
在这里插入图片描述
NAND FLASH时序图,如下所示:
在这里插入图片描述
注:下图中的CE上面有一个横杠代表低电平有效。没有横杠的引脚就是高电平有效。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们在汇编语言中已经设置HCLK为100MHZ,一个周期T = 1000/100 = 10s,通过上面四个图可以知道:
TACLS的值可以为0(即中间图的Duration = tcs - twp = 12 - 12 = 0,故TACLS = 0 );
TWRPH0的值可以为1( HCLK*(TWRPH0 + 1) = twp ≥ 12,求得TWRPH0 ≥ 1,取 TWRPH0 = 1 );
TWRPH1的值可以为0(tclh = 5ns, HCLK*(TWRPH1 + 1) ≥ 5, 求得TWRPH1 ≥ 0,取 TWRPH0 = 0)。

好了,我们开始写代码。NFCONF寄存器设置如下:

#define  TACLS   0/*设置宏定义是为了方便你理解*/
#define  TWRPH0  1
#define  TWRPH1  0
/*设置NAND FLASH的时序*/
NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);

到此设置NAND FLASH的时序已经设置完了,我们接着来使能,使能是在NFCONT寄存器。在这里插入图片描述
MODE [0]: 设置为1,使能NAND FLASH。
Reg_nCE [1]: 设置为1,禁止片选。因为我们现在还没有使用。为避免错误的操作。
InitECC [4]: 初始化ECC的编码器,后边要使用,我们设置为1,来初始化。

所以NFCONF寄存器设置如下:

/*使能NAND FLASH控制器,初始化ECC,禁止片选*/
NFCONT = (1<<4) | (1<<1) | (1<<0);

第03节 NandFlash的芯片id读取

本节课源码见:
F:\韦东山\005_ARM裸机1期加强版(又叫新1期,151节,23节免费,已完结)\源码文档图片\源码\源码_20180321_添加传感器\019_nand_flash_016\002_chip_id_016_003

上节课我们讲解了NAND FLASH的初始化,这节课我们来讲解读取NAND FLASH 的ID, 我们可以参考NAND FLASHh的芯片手册,如下图所示:(NAND FLASH读操作时序图)
在这里插入图片描述
我们一般先操作片选使能,只有片选使能之后才能进行后边的操作。为了方便我们写一个片选函数。片选是能代码如下:

void nand_select(void)
{
   
	/*使能片选*/
	NFCONT &=~(1<<1);
}

在写一个禁止片选函数。有使能片选,一定有禁止片选,禁止片选的代码如下:

void nand_deselect(void)
{
   
	/*禁止片选*/
	NFCONT |= (1<<1);
}

读ID的操作时序图,如下图所示:
我们按照从左往右的时间点,来分析,片选信号像一个总开关,只有使能了片选信号,后续的操作才会有意义,我们使能片选信号之后,片选引脚nCE后续一直为低电平,在前面的命令时序图中知道tCLS和tWP最小的时间参数都是12us,就表明CLE和nWE这两个信号可以同时发出,就表示要命令了,对于写什么命令,就要看数据总线上要发送的命令了,当CLE从高电平变为低电平后,表示上次的写操作已经结束了。

对于上面复杂的时序,我们可以使用2440上的NAND FLASH控制器简化操作,只需要往NFCMMD寄存器写入要传输的命令就可以了,NAND FLASH控制器默认把上面复杂的时序发出来。

发命令后,后面就需要发送地址了,当nWE和ALE有效的时候,表示写地址,上图中,要写入的地址是0x00,当ALE从高电平变为低电平的时候,表示写地址结束。我们可以简化为:往NFADDR寄存器中写值就可以了,比如:NFADDR=0x00。
在这里插入图片描述
下面我们写代码:发命令的函数,和发地址的函数代码如下:

void nand_cmd(unsigned char cmd)
{
   
	volatile int i;
	NFCCMD = cmd;
	for(i=0; i<10; i++);
}
void nand_addr_byte(unsigned char addr)
{
   
	volatile int i;
	NFADDR = addr;
	for(i=0; i<10; i++);
}

接下来就可以读取数据(芯片ID)了,数据可以直接通过读取NFDATA寄存器里面数据来获得数据,根据时序图,是读5个字节的数据,代码如下:

unsigned char nand_data(void)
{
   
	return	NFDATA;
}

读芯片ID之前先打开片选, 读取芯片ID函数,代码如下:

void nand_chip_id(void)
{
    
	unsigned char buf[5]={
   0};
	
	nand_select(); //打开片选
	nand_cmd(0x90);
	nand_addr_byte(0x00);

	buf[0] = nand_data();
	buf[1] = nand_data();	
	buf[2] = nand_data();
	buf[3] = nand_data();
	buf[4] = nand_data();	
	nand_deselect(); 	//关闭片选

	printf("maker   id  = 0x%x\n\r",buf[0]);
	printf("device  id  = 0x%x\n\r",buf[1]);	
	printf("3rd byte    = 0x%x\n\r",buf[2]);		
	printf("4th byte    = 0x%x\n\r",buf[3]);	

/*取buf[3]中的信息,下面两行是取nand flash的页和块信息。具体信息你见本节最后的图片*/		
printf("page  size  = %d kb\n\r",1 <<  (buf[3] & 0x03));/*取页信息。1左移x位,x等于(buf[3] & 0x03)*/
	printf(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值