⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 基于LPC214X的K9F1G08的驱动
💻 C
字号:
#include	"config.h"
//P0

#define FALE 1<<12
#define FCLE 1<<21
#define FCE 1<<22
#define FRE 1<<16
#define FRB 1<<15


//P1
#define FWE 1<<24




/*Flash 数据线号线定义*/
#define	FIO		(16)			//P0.16~P0.23

/*控制信号线操作宏定义*/

#define	SET_FALE()		IO0SET=IO0SET|FALE		//FALE
#define	CLR_FALE()		IO0CLR=IO0CLR|FALE
#define	SET_FCLE()		IO0SET=IO0SET|FCLE		//FCLE
#define	CLR_FCLE()		IO0CLR=IO0CLR|FCLE
#define	SET_FCE()		IO0SET=IO0SET|FCE		//FCE
#define	CLR_FCE()		IO0CLR=IO0CLR|FCE
#define	SET_FWE()		IO1SET=IO1SET|FWE		//FWE
#define	CLR_FWE()		IO1CLR=IO1CLR|FWE
#define	SET_FRE()		IO0SET=IO0SET|FRE		//FRE
#define	CLR_FRE()		IO0CLR=IO0CLR|FRE
#define	SET_FRB()		IO0SET=IO0SET|FRB		//FRB
#define	CLR_FRB()		IO0CLR=IO0CLR|FRB

/************************************************************************
//delay,小延时函数!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*************************************************************************/
static void delay(void)	//LPC2136的IO口进行In/Out变换时需要反应时间,否则会发生反应来不及的情况,实践所得!!!
{						//因此凡是在涉及到IO口方向变化时必须调用本函数,实践得这个循环输至少为30,我们这取80
	uint8 dly=80;
	while(dly--);
}

/*数据信号线操作宏定义*/
#define	SETFI()		{IO1DIR=IO1DIR&(~(0xFF<<FIO));delay();}		//Set P0.16~P0.23 as input
#define	SETFO()		{IO1DIR=IO1DIR|(0xFF<<FIO);delay();}		//Set P0.16~P0.23 as output
#define	WFIO(dat)	IO1PIN=(IO1PIN&(~(0xFF<<FIO)))|((dat)<<FIO)	//向数据口写字节dat
#define	RFIO(dat)	(dat)=(IO1PIN>>FIO)&0xFF					//从数据口读字节到dat

/*我们采用40MHz主频,每执行一条指令25ns,故本内嵌函数相当于延时
25ns.一般情况下Flash需要的时间延时<100ns,nop()几次就足够了*/
#define	nop()	__asm		\
				{			\
					NOP		\
				}
				
/*Status命令字*/
#define	SPstatusCMD		0x70		//signal plane status command
#define	MPstatusCMD		0x71		//multi plane status command

/*Flash功能函数*/
static void WriteCmd(uint8 cmd);			//向Flash写命令字节
static void WriteData(uint8 data);
static void WriteByteAddr(uint8 ByteAddr);	//向Flash写地址字节
static void WriteAddr(uint32 addr);		//向Flash写地址(26bits--64M)

/************************************************************************
//InitFlash,初始化控制信号
*************************************************************************/
void InitFlash(void)
{
	IO0DIR=IO0DIR | FALE | FCLE | FCE | FRE;		//Config P0.28,29,30 as output
	IO1DIR=IO1DIR | FWE;		//Cofig P1.21,22,23 as output
	//IO0DIR=IO0DIR & ( ~FRB );		//Cofig P1.24 as input
	
	
	
	SETFO();			//Config P0.16~23 as output
	
	/*控制信号初始态,除写保护信号有效,其余信号均为其无效电平*/
	//CLR_FWP();	//WP=0,write protected
	CLR_FCLE();	//CLE=0
	CLR_FALE();	//ALE=0
	SET_FCE();	//CE=0
	SET_FRE();	//RE=1
	SET_FWE();	//WE=1
}

/************************************************************************
//WriteCmd,写命令
*************************************************************************/
static void WriteCmd(uint8 cmd)
{	
	SET_FCLE();		//CLE=1,锁入的是命令
	CLR_FWE();		//WE=0,以便生成一个上升沿发送命令	
	
	WFIO(cmd);		//送出数据
	
	SET_FWE();		//恢复所有信号为初始化状态,上升沿锁存命令至Flash
	CLR_FCLE();
}

/************************************************************************
//WriteData
*************************************************************************/
void WriteData(uint8 data)
{
	CLR_FWE();
	
	WFIO(data);
	
	SET_FWE();	//上升沿送出数据
}
/************************************************************************
//一个字节一个字节地写地址
*************************************************************************/
static void WriteByteAddr(uint8 ByteAddr)
{
	SET_FALE();		//ALE=1,is address
	CLR_FWE();
	
	WFIO(ByteAddr);
	
	SET_FWE();		//Rising edage
	CLR_FALE();
}

/************************************************************************
//WriteAddr,写26位地址
*************************************************************************/
static void WriteAddr(uint32 addr)
{	
	SET_FALE();
	
	CLR_FWE();
	WFIO(addr&0xFF);		//A0-A7,Column addr
	SET_FWE();
	
	CLR_FWE();
	WFIO((addr>>8)&0x0F);	//A8-A11,the following is Page addr
	SET_FWE();
	
	CLR_FWE();
	WFIO((addr>>12)&0xFF);	//A12-A19
	SET_FWE();
	
	CLR_FWE();
	WFIO((addr>>20)&0xff);	//A20-A27
	SET_FWE();
	
	CLR_FALE();
}
/************************************************************************
//ReadID
*************************************************************************/
uint32 ReadID(void)////////////////////
{
	uint32 ID;
	uint8 a,b,c,d;
	CLR_FCE();
	WriteCmd(0x90);
	WriteByteAddr(0);
	
	SETFI();
	
	//*****Read ID start
	/*Make Code*/
	CLR_FRE();
	nop();
	SET_FRE();
	RFIO(a);
	/*Device Code*/
	CLR_FRE();
	nop();
	SET_FRE();
	RFIO(b);
	/*Reserved Code*/
	CLR_FRE();
	nop();
	SET_FRE();
	RFIO(c);
	/*Multi-Plane Code*/
	CLR_FRE();
	nop();
	SET_FRE();
	RFIO(d);
	//*****Read ID end	
	SETFO();
	ID = (a << 24) + (b << 16) + (c << 8) + d;
	SET_FCE();
	return ID;
}

/************************************************************************
//ReadStatus()	
*************************************************************************/
uint8 ReadStatus(uint8 cmd)///////////////////////////////////////////////
{
	uint8 status;
	WriteCmd(cmd);
	SETFI();
	CLR_FRE();	//CE下降沿读状态数据
	nop();
	nop();
	RFIO(status);
	SETFO();
	SET_FRE();
	return(status);
}
/************************************************************************
//ReadNameData,读取Data空间指定地址指定数量字节
*************************************************************************/
BOOL ReadNameData(uint32 PageAddr,uint16 offset,uint16 num,uint8 *buf)
{
	uint8 data;
	uint16 i;
	CLR_FCE();
	if(offset>2048 || (offset+num)>2112)
	{
		SET_FCE();
		return(false);	
	}
	WriteCmd(0x00);			//Read1 operation
	WriteAddr((PageAddr<<12) | offset);	
	WriteCmd(0x30);
	while(!(FRB & IO0PIN));

	SETFI();		//data口为输入口
	for(i=0;i<num;i++)		
	{
		CLR_FRE();			//read data
		RFIO(data);
		*buf++ =data;
		SET_FRE();			//increased data pointer
	}
	SETFO();		//恢复data为输出口
	SET_FCE();
	return(true);
}
/************************************************************************
//ReadOneData,读取data空间一个字节
*************************************************************************/
uint8 ReadOneData(uint32 PageAddr,uint16 offset)
{
	uint8 buf;
	
	ReadNameData(PageAddr,offset,1,&buf);
		
	return(buf);
}
/************************************************************************
//ReadData,读取data空间512字节
*************************************************************************/
BOOL ReadData(uint32 PageAddr,uint8 *buf)
{
	return(ReadNameData(PageAddr,0,2048,buf));
}



/************************************************************************
//ReadOneSpace,读取space空间一个字节
*************************************************************************/
uint8 ReadOneSpace(uint32 PageAddr,uint8 offset)////////////////////////////
{
	uint8 buf;
	
	ReadNameData(PageAddr,offset + 2048,1,&buf);
	
	return(buf);
	
}
	
/************************************************************************
//ReadSpace,读取space空间16字节
*************************************************************************/
BOOL ReadSpace(uint32 PageAddr,uint8 *buf)
{
	return(ReadNameData(PageAddr,2048,64,buf));
}

/************************************************************************
//ProData,data空间页编程2048字节
*************************************************************************/
BOOL ProData(uint32 PageAddr,uint8 *buf)
{
	uint16 i;
	CLR_FCE();
	WriteCmd(0x80);					//数据输入指令
	WriteAddr(PageAddr<<12);		//地址输入
	for(i=0;i<2048;i++)
		WriteData(*buf++);
	WriteCmd(0x10);					//自动编程命令	
	while(!(ReadStatus(SPstatusCMD)&(1<<6)));	//wait for read page completed
	if(ReadStatus(SPstatusCMD)&0x01)			//编程错误
	{
		SET_FCE();
		return(false);
	}
	SET_FCE();
	return(true);	
}

BOOL CopyBackProData(uint32 SPageAddr,uint32 DPageAddr)
{
	CLR_FCE();
	WriteCmd(0x00);					//数据输入指令
	WriteAddr(SPageAddr<<12);		//地址输入
	WriteCmd(0x35);					//自动编程命令	
	while(!(FRB & IO0PIN));	
	WriteCmd(0x85);					//数据输入指令
	WriteAddr(DPageAddr<<12);		//地址输入
	WriteCmd(0x10);					//自动编程命令	
	while(!(ReadStatus(SPstatusCMD)&(1<<6)));	//wait for read page completed
	if(ReadStatus(SPstatusCMD)&0x01)			//编程错误
	{
		SET_FCE();
		return(false);
	}
	SET_FCE();
	return(true);	
}


/************************************************************************
//ProSpace,space空间编程16字节
*************************************************************************/
BOOL ProSpace(uint32 PageAddr,uint8 *buf)
{
	uint16 i;
	CLR_FCE();
	WriteCmd(0x80);					//数据输入指令
	WriteAddr((PageAddr<<12) | 2048);		//地址输入
	for(i=0;i<64;i++)
		WriteData(*buf++);
	WriteCmd(0x10);					//自动编程命令	
	while(!(ReadStatus(SPstatusCMD)&(1<<6)));	//wait for read page completed
	if(ReadStatus(SPstatusCMD)&0x01)			//编程错误
	{
		SET_FCE();
		return(false);
	}
	SET_FCE();
	return(true);	
}
/************************************************************************
//EraseBlk
*************************************************************************/
BOOL EraseBlk(uint16 blks)
{
	CLR_FCE();
	WriteCmd(0x60);		//建立擦除命令		
	WriteByteAddr((uint8)(blks&0xff));	//A12-A19
	WriteByteAddr((uint8)((blks>>8)&0xFF));	//A20-A27
	WriteCmd(0xD0);		//启动擦除命令	
	while(!(ReadStatus(SPstatusCMD)&(1<<6)));	//wait for read page completed
	if(ReadStatus(SPstatusCMD)&0x01)			//编程错误
	{
		SET_FCE();
		return(false);
	}
	SET_FCE();
	return(true);
}
/************************************************************************
//END
*************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -