[国嵌攻略][052][NandFlash驱动设计_读]

NandFlash读数据方式

1.页读,读出页中主数据区的所有数据,提供页地址(行地址)

2.随机读,读出页中指定的存储单元的数据,提供页地址(行地址)和页内偏移(行地址)

代码编写

1.根据NandFlash中的读时序图写出工作流程,可以通过在芯片手册中搜索operation找到相关描述

2.主要关心的是IO脚上时序的变化

3.初始化闪存分为初始化闪存控制器和闪存芯片

4.对位操作

4.1.清零

x &= ~(y<<z)   对x的z位开始的y清零

4.2.置1

x |= y<<z   对x的z位开始的y置1

4.3.取数

x & y<<z   取出x的第z位开始的y

4.4.置数

x = y

/********************************************************************
*名称:flash
*作者:D
*时间:2015.11.08
*功能:闪存驱动
********************************************************************/

/********************************************************************
*							 宏定义
********************************************************************/
#define NFCONF ( *((volatile unsigned long *)0x4E000000) )   //闪存配置寄存器
#define NFCONT ( *((volatile unsigned long *)0x4E000004) )   //闪存控制寄存器
#define NFCMMD ( *((volatile unsigned long *)0x4E000008) )   //闪存命令寄存器
#define NFADDR ( *((volatile unsigned long *)0x4E00000C) )   //闪存地址寄存器
#define NFDATA ( *((volatile unsigned char *)0x4E000010) )   //闪存数据寄存器
#define NFSTAT ( *((volatile unsigned long *)0x4E000020) )   //闪存状态寄存器

#define PAGE_SIZE 2048   //页大小

/********************************************************************
*						  函数原型声明
********************************************************************/
void init_flash();
void init_flash_controller();
void reset_flash_chip();

void read_flash(unsigned long src, unsigned long dst, int len);
void read_page_flash(unsigned long page, unsigned char *buf);

/********************************************************************
*名称:init_flash
*功能:初始化闪存
*********************************************************************/
void init_flash(){
	//初始化闪存控制器
	init_flash_controller();
	
	//重置闪存芯片
	reset_flash_chip();
}

/********************************************************************
*名称:init_flash_controller
*功能:初始化闪存控制器
*********************************************************************/
void init_flash_controller(){
	//初始化闪存配置寄存器
	NFCONF = (1<<12)|(1<<8)|(1<<4);   //设置TACLS:1 TWRPH0:1 TWRPH1:1
	
	//初始化闪存控制寄存器
	NFCONT = (1<<1)|(1<<0);   //设置Reg_nCE:1 MODE:1
}

/********************************************************************
*名称:reset_flash_chip
*功能:重置闪存芯片
*********************************************************************/
void reset_flash_chip(){
	//选中闪存芯片
	NFCONT &= ~(1<<1);   //设置Reg_nCE:0
	
	//清除忙信号
	NFSTAT |= (1<<2);    //设置RnB_TransDetect:0

	//发送重启命令
	NFCMMD = 0xFF;
	
	//等待忙信号
	while( !(NFSTAT&(1<<2)) );   //当RnB_TransDetect等于1时,结束循环
	
	//释放闪存芯片
	NFCONT |= 1<<1;   //设置Reg_nCE:1
}

/********************************************************************
*名称:read_flash
*参数:
*	src   源地址
*	dst   目的地址
*	len   读取长度
*返回:
*	null
*功能:读闪存
*********************************************************************/
void read_flash(unsigned long src, unsigned long dst, int len){
	unsigned long page;   //页号
	unsigned char *buf;   //页缓存
	
	while(len > 0){
		page = src>>11;               //设置页号
		buf = (unsigned char *)dst;   //设置页缓存
		read_page_flash(page, buf);
		
		src +=PAGE_SIZE;
		dst +=PAGE_SIZE;
		len -=PAGE_SIZE;
	}
}

/********************************************************************
*名称:read_page_flash
*参数:
*	page   页号
*	buf    页缓存,2048字节
*返回:
*	none
*功能:页读闪存
*********************************************************************/
void read_page_flash(unsigned long page, unsigned char *buf){
	int i;   //循环计数器

	//选中闪存芯片
	NFCONT &= ~(1<<1);   //设置Reg_nCE:0
	
	//清除忙信号
	NFSTAT |= (1<<2);    //设置RnB_TransDetect:0

	//发送读命令(0x00)
	NFCMMD = 0x00;
	
	//发送列地址
	NFADDR = 0x00;   //Col.Add1
	NFADDR = 0x00;   //Col.Add2
	
	//发送行地址
	NFADDR = (page>>0)&0xFF;    //Row.Add1
	NFADDR = (page>>8)&0xFF;    //Row.Add2
	NFADDR = (page>>16)&0xFF;   //Row.Add3
	
	//发送读命令(0x30)
	NFCMMD = 0x30;
	
	//等待忙信号
	while( !(NFSTAT&(1<<2)) );   //当RnB_TransDetect等于1时,结束循环
	
	//读取数据
	for(i = 0; i < PAGE_SIZE; i++){
		buf[i] = NFDATA;   //注意,NFDATA寄存器数据类型要和buf匹配,一个读周期读出一个字节
	}
	
	//释放闪存芯片
	NFCONT |= 1<<1;   //设置Reg_nCE:1
}
原文地址:https://www.cnblogs.com/d442130165/p/4953413.html