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

📄 flash.c

📁 ATMEL系列存储器驱动程序,提供地层和上层驱动
💻 C
字号:
/*
 *CopyRight  Reserved?    凯拓科技版权所有  http://www.ktopcn.com 
 *文件名:flash.c
 *描述:提供Flash操作的上层程序。
 *
 *版本:v1.0
 *作者:ktop
 *日期:2004/11/17
 */
#define		FLASH_C
#include "flash.h"
											//与Flash容量相关的变量
static const uchar scucFlashSizeAttr[] = {FLASH_4M, FLASH_8M, FLASH_16M, FLASH_32M};
static const uint  scuiBlockSize[] = {		256, 		512, 	512, 		1024,};

static const uchar scucFlashDef[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 uint suiBufAddr[2];					//两个缓冲所对应的FLASH实际页地址。



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


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


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


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


/*
 *函数性质:公共
 *入口:存储器地址ulAddr,数据缓冲地址pData, 数据长度uiLen
 *出口:无
 *功能:将pData所指向的缓冲数据写入到指定的存储器地址,数据个数由uiLen决定。
 */
/*void WriteFlashMem(ulong ulAddr, uchar *pData, uint uiLen)
{
	uint  j;						
	while(uiLen)
	{	
		j = ulAddr%PAGE_SIZE;  
		j = PAGE_SIZE -j;
		j = (j <= uiLen) ? j:uiLen;									//计算出需要写入的数据长度。
		while(!(ReadFlashStuReg() & FLASH_BUSY) )
		{
			CLRWATCHDOG();
		}															//忙,则一直等待
		ReadFlashToBuff(MEM_TO_BUFF1, ulAddr/PAGE_SIZE);			//读数据入缓冲。
		while(!(ReadFlashStuReg() & FLASH_BUSY) )
		{
			CLRWATCHDOG();
		}															//忙,则一直等待
		WriteFlashWithBuff(BUFF1_TO_MEM, ulAddr/PAGE_SIZE, ulAddr%PAGE_SIZE,
							pData, j);
		ulAddr += j;												//修改数据地址及各指针
		uiLen -= j;
		pData += j;	
					
	}
}*/




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



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




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

⌨️ 快捷键说明

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