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

📄 flash.c

📁 用LPC213X处理器对AT45DB161的操作程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************

**--------------File Info-------------------------------------------------------------------------------
** File name:			Flash.c
** Last modified Date:  2006-03-20
** Last Version:		1.0
** Descriptions:		
**
**------------------------------------------------------------------------------------------------------
** Created by:			
** Created date:		2006-03-20
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:			
** Modified date:		2006-03-20
** Version:
** Descriptions:		
**
********************************************************************************************************/
#include  "Flash.h"
#include  "string.h"

static const uint8 FlashSizeAttr[] = {FLASH_4M, FLASH_8M, FLASH_16M, FLASH_32M};
static const uint16  BlockSize[] = {		256, 		512, 	512, 		1024,};

static const uint8 FlashDef[3][2]= {	//与操作FLASH相关的变量。
MEM_TO_BUFF1, MEM_TO_BUFF2,
BUFF1_TO_MEM_WITH_ERASE, BUFF2_TO_MEM_WITH_ERASE,
BUFF_1_WRITE, BUFF_2_WRITE,};

//与写操作相关定义
static uint16 BufAddr[2];					//两个缓冲所对应的FLASH实际页地址。

/*
 *函数性质:公共
 *入口:无
 *出口:无
 *功能:刷新缓冲,将缓冲中的数据写入到FLASH中。以免断电数据丢失。
 */
void FlushFlash(void)
{
	uint8 i;
	
	for (i = 0; i < 2; i++)
	{
		WriteBuffToFlash(FlashDef[WRITE_FROM_BUF][i], BufAddr[i]);			
		while(!(ReadFlashStuReg() & FLASH_BUSY) )
		{															//等待写入完成。
			CLRWATCHDOG();
		}	
	} 
}	


/*
 *函数性质:公共
 *入口:页地址ulFlashAddr
 *出口:无
 *功能:将给定地址的Flash数据读入到缓冲中。
 */
void UpDateFlashBuf(uint32 FlashAddr)
{
	uint8 i;
	uint16 PageAddr = FlashAddr/PAGE_SIZE;
	
	for (i = 0; i < 2; i++)
	{
		while(!(ReadFlashStuReg() & FLASH_BUSY) )
		{															//等待读入完成。
			CLRWATCHDOG();
		}
		ReadFlashToBuff(FlashDef[READ_TO_BUF][i], PageAddr + i);	
		BufAddr[i] = PageAddr + i;
	}
	while(!(ReadFlashStuReg() & FLASH_BUSY) )
	{																//等待读入完成。
		CLRWATCHDOG();
	}
}


/*
 *函数性质:公共
 *入口:存储器地址Addr, 数据缓冲地址Data, 数据长度Len
 *出口:无
 *功能:从Flash中读出给定个数的数据,并将读得的数据存放到Data中。
 */
void ReadFlashMem(uint32 Addr, uint8 *Data, uint16 Len)
{    
	while(!(ReadFlashStuReg() & FLASH_BUSY) )
	{
		CLRWATCHDOG();
	}	
	ContinueReadFlash(Addr/PAGE_SIZE, Addr%PAGE_SIZE, Data, Len);	
}


/*
 *函数性质:公共
 *入口:存储器地址Addr,数据缓冲地址Data, 数据长度Len
 *出口:无
 *功能:将Data所指向的缓冲数据写入到指定的存储器地址,数据个数由Len决定。
 */
void WriteFlashMem(uint32 Addr, uint8 *Data, uint16 Len)
{
	uint16 PageAddr;
	uint16 j;
	uint16 i;
	uint8 CurBuf;
	
	PageAddr = Addr/PAGE_SIZE;									
	j = Addr%PAGE_SIZE; 											//得出本页偏移地址。
	while(Len)													//写数据
	{
		IO1SET = DFWP;
		i = PAGE_SIZE -j;
		i = (i <= Len) ? i:Len;									//计算出本次需要写入的数据长度。	
		if (BufAddr[0] ==PageAddr)								//当前正使用缓冲1
		{
			CurBuf = 0;
			if (BufAddr[1] != (PageAddr + 1) )					//判断并读入缓冲2 
			{
				while(!(ReadFlashStuReg() & FLASH_BUSY) )
				{
					CLRWATCHDOG();									
				}													
				ReadFlashToBuff(FlashDef[READ_TO_BUF][1], PageAddr + 1);	
				BufAddr[1] = PageAddr + 1;
			}
			WriteFlashBuff(FlashDef[WRITE_BUF][0], j, Data, i);//写数据入缓冲1
		}
		
		else if (BufAddr[1] == PageAddr)
		{	
			CurBuf = 1;											//当前正使用缓冲2
			if (BufAddr[0] != (PageAddr + 1) )					//判断并读入缓冲1
			{
				while(!(ReadFlashStuReg() & FLASH_BUSY) )
				{
					CLRWATCHDOG();									
				}													
				ReadFlashToBuff(FlashDef[READ_TO_BUF][0], PageAddr + 1);
				BufAddr[0] = PageAddr + 1;	
			}
			WriteFlashBuff(FlashDef[WRITE_BUF][1], j, Data, i);//写缓冲1	
		}
		
		else
		{															//当前的两个缓冲均不是需要写入的页,读入需要写入的页
			BufAddr[0] = PageAddr;	
			while(!(ReadFlashStuReg() & FLASH_BUSY) )
			{
				CLRWATCHDOG();									
			}													
			ReadFlashToBuff(FlashDef[READ_TO_BUF][0], PageAddr);  
			continue;
		}	
																			
		j += i;
	//	if (j >= PAGE_SIZE)
		{
			while(!(ReadFlashStuReg() & FLASH_BUSY) )
			{
				CLRWATCHDOG();									
			}														//写入到Flash
			WriteBuffToFlash(FlashDef[WRITE_FROM_BUF][CurBuf], BufAddr[CurBuf]);	
		}
		Len -= i;													//修改各数据指针
		PageAddr += j/PAGE_SIZE;
		j = j%PAGE_SIZE;
		Data += i;
	}
	IO1CLR = DFWP;
}




/* 
 *函数性质:公共
 *入口:无
 *出口:FLASH容量,如果为4M位,则返回0
 *功能:读取Flash容量。
 */
uint8 GetFlashSize(void)
{
	uint8 i;
	uint8 j;
	i = (ReadFlashStuReg() & 0x3C);
	for (j = 0; j < sizeof(FlashSizeAttr); j++)
	{
		if (i == FlashSizeAttr[j])
		{
			return j;	
		}	
	}
	return 0xff;							//读芯片出错,返回非法值。	
}



/*
 *函数性质:公共
 *入口:无
 *出口:无
 *功能:整片擦除FLASH。
 */
void EraseAllFlash(void)
{
	uint16 i;	
//	i  = BlockSize[GetFlashSize()];
	i =0x1000;
	IO1SET = DFWP;
	for (; i > 0; i--)
	{
		while(!(ReadFlashStuReg() & FLASH_BUSY) )
		{
			CLRWATCHDOG();
		}
		FlashBlockErase(i-1);					//擦除块。
	}
	IO1CLR = DFWP;	
}




/*
 *函数性质:公共
 *入口:无
 *出口:无
 *功能:初始化FLASH,将FLASH中的数据读入到缓冲中。
 */
void FlashMemIni(void)
{
	while(!(ReadFlashStuReg() & FLASH_BUSY) )
	{
		CLRWATCHDOG();									
	}													
	ReadFlashToBuff(FlashDef[READ_TO_BUF][0], 0);
	while(!(ReadFlashStuReg() & FLASH_BUSY) )
	{
		CLRWATCHDOG();									
	}													
	ReadFlashToBuff(FlashDef[READ_TO_BUF][1], 1);	
	BufAddr[0] = 0;
	BufAddr[1] = 1;
}

void CLRWATCHDOG(void)
{
     IRQDisable();
	 WDFEED=0xaa;
	 WDFEED=0x55;
	 IRQEnable();
}
/********************************************************************************************************
** 函数名称:MSPI_Init()
** 函数功能:初始化SPI接口,设置为主机。
** 入口参数:无
** 出口参数:无
*********************************************************************************************************/
void  SPI_Init(void)
{  
	PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x15 << 8) ;
    S0PCCR = 0x16;		            // 设置SPI时钟分频
 	S0SPCR  = (0 << 3) |				// CPHA = 1, 数据在SCK 的第2个时钟沿采样
 			(1 << 4) |				// CPOL = 1, SCK 为低有效
 			(1 << 5) |				// MSTR = 1, SPI 处于主模式
 			(0 << 6) |				// LSBF = 0, SPI 数据传输MSB (位7)在先
 			(0 << 7);				// SPIE = 0, SPI 中断被禁止
}

/********************************************************************************************************
** 函数名称:SPI_SendData()
** 函数功能:向SPI总线发送数据。
** 入口参数:data   待发送的数据
** 出口参数:返回值为读取的数据
********************************************************************************************************/
uint8  SPI_SendData(uint8 data)
{  
    S0PDR = data;
    while( 0 == (S0SPSR & 0x80));		// 等待SPIF置位,即等待数据发送完毕
   
    return(S0PDR);
}


/*
 *函数性质:私有
 *入口:待发送的数据缓冲Data,等发送的数据个数Len。
 *出口:无
 *功能:将缓冲中给定个数的数据移位输出到Flash
 */
void ShiftInData(uint8 *Data, uint16 Len)
{
	
	while(Len--)
	{
		SPI_SendData(*Data);
		Data++;		
	}	
}



/*
 *函数性质:私有
 *入口:存放数据的缓冲Data, 需要读取的数据个数Len

⌨️ 快捷键说明

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