欢迎光临
我们一直在努力

[置顶] ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)

上一篇文章主要学习了NAND Falsh的基础知识,今天则来总结NAND Flash的初始化,以及块擦除,页的读写操作,以及芯片id号的获取。

6. NAND FLASH 的操作接口

我们知道,函数在调用时需要使用栈,当项目的函数调用关系复杂时,尤其是存在多级

函数调用时,容易导致栈溢出,此处函数调用的开销也会逐渐加大。

为了更好的解决上述问题,一般使用宏的形式来实现规模较小的函数,因为宏调用时在

预处理阶段,由预处理器对源程序中的宏进行展开,所以宏展开不占用运行时间。

因为每一次宏调用都需要进行宏展开,所以会加大程序的代码量,因此规模较大的函数

不宜使用宏的形式来实现

① NAND FLASH 使能函数

#define NF_Enable() {rNFCONT &=~(1<<1);} //选中芯片

② NAND FLASH 失能函数

#define NF_Disable() {rNFCONT |=(1<<1);}

[置顶]        ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)

③ NAND FLASH 发送命令函数

#define NF_Send_Cmd(cmd) {rNFCMD = (cmd);}

④ NAND FLASH 发送地址函数

#define NF_Send_Addr(addr) {rNFADDR =addr;}

⑤ NAND FLASH 发送数据函数

#define NF_Send_Data(data) {rNFDATA8 =(data);}

⑥ NAND FLASH 使能忙检测函数

#define NF_Enable_RB() {rNFSTAT |= (1<< 4);}

[置顶]        ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)

⑦ NAND FLASH 判忙函数

#define NF_Check_Busy() {while(!(rNFSTAT& (1 << 0)));} // 0 busy ,1 ready

⑧ NAND FLASH 读字节函数

#define NF_Read_Byte() (rNFDATA8)

 

7. 怎样对 NAND 进行复位?

① 选中 NAND FLASH

② 使能 NAND 判忙检测

③ 发送复位命令(0xff)

④ 等待复位完成

⑤ 取消选中 NAND FLASH

 

8. 怎样对 NAND 进行初始化?

① 配置 GPA 相关 IO 口

② 设置相关时间参数

③ 关闭 NAND 中断,打开 NAND 控制器

④ NAND 相关状态清零

⑤ 复位 NAND

 

9. 怎样擦除一个块?

① 复位 NAND

② 选中 NAND FLASH

③ 使能 NAND 判忙检测

④ 发送块擦除发起命令(0x60)

⑤ 发送块地址

⑥ 发送块擦除确认命令(0xd0)

⑦ 等待擦除完成

⑧ 取消选中芯片

 

10. 怎样写一页?

① 复位 NAND FLASH

② 选中 NAND FLASH

③ 使能 NAND 判忙检测

④ 发送写页发起命令(0x80)

⑤ 发送页地址

⑥ 发送 2048 个数据

⑦ 发送写页确认命令(0x10)

⑧ 等待写完成

⑨ 取消选中芯片

 

11. 怎样读一页

① 复位 NAND FLASH

② 选中 NAND FLASH

③ 发送页读取发起命令(0x00)

④ 发送读地址

⑤ 发送页读取确认命令(0x30)

⑥ 等待命令完成

⑦ 读取 2048 个命令

⑧ 取消选中芯片

 

12.NAND FLASH 的地址模式

[置顶]        ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)

源代码分析(代码编译环境:win8,keil4):

宏定义,具体参数查DATASHEET,不再赘叙。

#define rNFCONF	 (*(volatile unsigned long *)(0x4e000000))
#define rNFCONT	 (*(volatile unsigned long *)(0x4e000004))
#define rNFCMD	 (*(volatile unsigned long *)(0x4e000008))
#define rNFADDR	 (*(volatile unsigned long *)(0x4e00000c))
#define rNFDATA8  (*(volatile unsigned char *)(0x4e000010))
#define rNFSTAT   (*(volatile unsigned long *)(0x4e000028))
#define rGPACON  (*(volatile unsigned long *)(0x56000000))

//NAND FLASH 使能函数
#define 		NF_Enable() 			{rNFCONT &amp;= ~(1&lt;&lt;1);} //选中芯片
//NAND FLASH 失能函数
#define 		NF_Disable() 			{rNFCONT |= (1&lt;&lt;1);}
//NAND FLASH 发送命令函数
#define 		NF_Send_Cmd(cmd) 	{rNFCMD = (cmd);}
//NAND FLASH 发送地址函数
#define 		NF_Send_Addr(addr) 	{rNFADDR = addr;}
//NAND FLASH 发送数据函数
#define 		NF_Send_Data(data) 	{rNFDATA8 = (data);}
//NAND FLASH 使能忙检测函数
#define 		NF_Enable_RB() 		{rNFSTAT |= (1 &lt;&lt; 4);}
//NAND FLASH 判忙函数
#define 		NF_Check_Busy() 	{while(!(rNFSTAT &amp; (1 &lt;&lt; 0)));} // 0 busy ,1 ready
//NAND FLASH 读字节函数
#define 		NF_Read_Byte()		 (rNFDATA8)		//因为需要赋值操作,所以不加;

[置顶]        ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)[置顶]        ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)

一些操作命令

注意:某些命令需要发送两次,操作前后各发送一次,成对出现,第二次发送的是确认命令。

NAND Flash复位函数

#define NF_CMD_RESET         0xff

void nand_reset(void)		//nand复位函数
{
	NF_Enable();		//选中芯片
	NF_Check_RB();		//忙检测
	NF_Send_Cmd(NF_CMD_RESET);	//发送复位命令
	NF_Check_Busy();		//忙等待
	NF_Disable();		//取消选中芯片
}

NAND Flash初始化函数

#define TACLS 1		
#define TWRPH0 4
#define TAWTH1 1

#define NAND_INT_DIABLE 0
#define NAND_ENABLE 1


void nand_init(void)
{
	rGPACON &amp;= ~(0x3f&lt;&lt;17);	//未操作将操作的位置清零
	rGPACON |= (0x3f&lt;&lt;17);	//初始化GPA
	rNFCONT = (TACLS&lt;&lt;12)|(TWRPH0&lt;&lt;8)|(TAWTH1&lt;&lt;4);	
	rNFCONT = (NAND_INT_DIABLE&lt;&lt;12)|(NAND_ENABLE&lt;&lt;0);
	rNFSTAT = 0x0;	//NAND相关状态清零
	nand_reset();	//复位
}


擦除一块内容

#define NF_CMD_ERASE1        0x60
#define NF_CMD_ERASE2        0xd0

void nand_erase(unsigned int block)	//块擦除
{
	unsigned int blocknum = (block&lt;&lt;6);	//左移6位(A12-A17)到A18
	
	nand_reset();	
	NF_Enable();	
	NF_Check_RB();
	NF_Send_Cmd(NF_CMD_ERASE1);	//发送块擦除指令
	NF_Send_Addr(blocknum &amp; 0xff);	//&amp;0xff是为了擦除高百位	第一次发送实际只发送A18 A19两位
	NF_Send_Addr((blocknum&gt;&gt;8) &amp; 0xff);	//发送接下来的8位地址
	NF_Send_Addr((blocknum&gt;&gt;16) &amp; 0xff);	
	NF_Send_Cmd(NF_CMD_ERASE2);		//发送确认块擦除指令
	NF_Check_Busy();		//忙等待
	NF_Disable();			//取消选中芯片
}

A0-A11用来页内寻址

A18-A28用来块寻址

A12-A17用来表示某块中的第几页

[置顶]        ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)

NAND寻址需要发送5次,一次发送8位数据(8个I/O口)。

block<<6,block左移6位,原本第三次(因为发送了指令,根据NAND内部机制,直接从第三次开始发送)A12的数据成了A18的数据,而A18-A28用来块寻址。

blocknum>>8,blocknum右移8位,即将block左移的6位再加上第三次发送的2位地址。


向NAND写入一页内容

#define NF_CMD_WRITE1        0x80
#define NF_CMD_WRITE2        0x10

void nand_write_page(unsigned int block,unsigned int page,unsigned char * str)	//写一页
{
	unsigned int pagenum = (block&lt;&lt;6) + page;		
	unsigned int i;
	
	nand_reset();		//nand复位
	NF_Enable();		//选中芯片
	NF_Check_RB();		//忙检测
	NF_Send_Cmd(NF_CMD_WRITE1);		//发送读操作指令
	NF_Send_Addr(0x0);
	NF_Send_Addr(0x0);
	NF_Send_Addr(pagenum &amp; 0xff);
	NF_Send_Addr((pagenum&gt;&gt;8) &amp; 0xff);
	NF_Send_Addr((pagenum&gt;&gt;16) &amp; 0xff);
	for(i=0; i&lt;2048; i++)
	{
		NF_Send_Data(str[i]);		//发送数据
	}
	NF_Send_Cmd(NF_CMD_WRITE2);		//发送读操作确认命令
	NF_Check_Busy();			//忙等待
	NF_Disable();			//取消选中芯片
}

读取一页内容

#define NF_CMD_READ1         0x00
#define NF_CMD_READ2         0x30

void nand_read_page(unsigned int block,unsigned int page,unsigned char * str)		//读一页
{
	unsigned int pagenum = (block&lt;&lt;6) + page;
	unsigned int i;
	
	nand_reset();		//nand复位
	NF_Enable();		//选中芯片
	NF_Check_RB();	//忙检测
	NF_Send_Cmd(NF_CMD_READ1);	//发送读操作指令
	NF_Send_Addr(0x0);		
	NF_Send_Addr(0x0);
	NF_Send_Addr(pagenum &amp; 0xff);
	NF_Send_Addr((pagenum&gt;&gt;8) &amp; 0xff);
	NF_Send_Addr((pagenum&gt;&gt;16) &amp; 0xff);
	NF_Send_Cmd(NF_CMD_READ2);	
	NF_Check_Busy();		//忙等待
	for(i=0; i&lt;2048; i++)
	{
		str[i] = NF_Read_Byte();	//读字节
	}
	NF_Disable();		//取消选中芯片
}

读取NAND Flash的ID号

#define NF_CMD_READ_ID  		0x90

void nand_read_ID(unsigned char * str)		//读取nand flash芯片id
{
	unsigned int i;
	
	NF_Enable();	//选中nand flash
	NF_Check_RB();	//忙检测
	NF_Send_Cmd(NF_CMD_READ_ID);	//发送读取芯片id命令
	NF_Send_Addr(0x0);	
	NF_Check_Busy();		//忙等待
	for(i=0; i&lt;2048; i++)
	{
		str[i] = NF_Read_Byte();	//读字节
	}
	NF_Disable();		//取消选中芯片
}

该文章由WP-AutoPost插件自动采集发布

原文地址:http://blog.csdn.net/yhj110911119/article/details/51989078

未经允许不得转载:SRE空间 » [置顶] ARMmini2451学习——NAND Flash初始化,块擦除,页读写(2)

分享到:更多 ()

评论 抢沙发

评论前必须登录!

 

oracle

联系我们联系我们