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

📄 at45.#3

📁 F020集成以太网接口核心模块DataFlash例程源代码
💻 #3
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------
// 文件名:AT45DB.C
// 操作:基于SPI硬件总线的AT45DB操作文件
// 注意:本文件中定义的操作是针对161D处于DataFlash格式的操作,即每个PAGE的页面大小为528B
//       如果用户使用的PAGE为512B,则要进行相应的修改
// scj
// 07/05/04
//-----------------------------------------------------------------------
// 修改记录
// 版本     时间        人员                内容
// 1.0      07/05/03    scj            041B操作基本函数
// 1.1      07/05/05    scj            增加了041B,081B,161B函数操作
//                                     根据g_cFlashType来标识Flash类型
//----------------------------------------------------------------------
#include "f020.h"
#include "datatype.h"
#include "at45.h"
#include <ctype.h>

//--------------------------------------------
// 宏定义
//--------------------------------------------

#define DF_RESET 		 {P5 &=~(0x1);_nop_();P5 |= 0x1;_nop_();}    // P50,AT45DB复位控制引脚
#define DF_PROTECT       {P5 &=~(0x02);_nop_();}             // P51,AT45DB保护控制
#define DF_NONPROTECT    {P5 |=0x02;_nop_();}                // P51,取消AT45DB保护
#define DF_CHIP_SELECT 	 {P5 &= ~(0x04);_nop_();} 		     // P52,AT45DB片选信号
#define DF_CHIP_NOSELECT {P5 |= 0x04;_nop_()} 				 // P52,取消AT45DB片选信号



// 器件类型
code char FLASH_STRING[][20]={"Unknown","AT45DB041","AT45DB081","AT45DB161"};
// 器件页面个数
code WORD FLASH_PAGE[]={0,2048,4096,4096};
// 器件页面字节数
code WORD FLASH_PAGE_BYTE[]={0,264,264,528};
// 器件BLOCK数
code WORD FLASH_BLOCK[]={0,256,512,512};
// 页面地址
code BYTE PAGE_SHIFT[]={0,1,1,2};
// 字节地址
code BYTE BYTE_SHIFT[]={0,8,8,8};
// 块移位地址
code BYTE BLOCK_SHIFT[]={0,4,4,5};
//---------------------------------------------
// 变量定义
//---------------------------------------------
char g_cFlashType=0;              // Flash类型,目前支持AT45DB041,AT45DB081,AT45DB161

//---------------------------------------------
// 函数声明
//---------------------------------------------

//---------------------------------------------
// 函数实现
//---------------------------------------------

//---------------------------------------------
// SPI操作函数
//---------------------------------------------
void SendSPIByte(BYTE ch)
{
	SPIF = 0;
	SPI0DAT = ch;
	while (SPIF == 0);	  // wait for data transfer to be completed   				       	
} 

BYTE GetSPIByte(void)
{
    SPIF = 0;
	SPI0DAT = 0;
	while (SPIF == 0);
	return  SPI0DAT;      // read data from SPI
}

//-----------------------------------------------------------------
// Flash操作
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// 功能:获取Flash类型,注意,在使用本文件中定义的函数时必须首先调用该函数
//       否则,其它函数无法正确判断Flash类型可能导致操作错误
// 参数:无
// 返回值:Flash类型的描述字符串,该缓冲区是只读的,内容不允许修改
//------------------------------------------------------------------
const char *GetFlashType()
{
	BYTE nDeviceID;

	nDeviceID =GetFlashInfo();

	if((nDeviceID&0x20)==0x20)
	{
		nDeviceID&=0x1F;

		if((nDeviceID>=4)&&(nDeviceID<=6))
		{
			g_cFlashType = nDeviceID-3;

		}
		else
		{
			g_cFlashType = 0;
		}
	}
	else
	{
		g_cFlashType = 0;
	}


	return FLASH_STRING[g_cFlashType];
}

//--------------------------------------------------------------------------------
// 功能:  读Flash当前状态 
// 参数:  无
// 返回值:BYTE,Flash当前状态
//         Bit7=1:空闲 0:忙 
//         Bit6=1:比较结果不匹配 0:匹配
//         Bit5Bit4Bit3:芯片标志(101:AT45DB161D;100:AT45DB081;011:AT45DB041B)
//         Bit2=1
//         Bit1: 扇区保护位,1:保护;0:未保护
//         Bit0: page大小,1:2^n;0:2^n+8/16 B
//--------------------------------------------------------------------------------
BYTE GetFlashStatus() 
{
	BYTE ret;

	DF_CHIP_SELECT;

	SendSPIByte(STATUS_REGISTER);
	ret=GetSPIByte();
	
	DF_CHIP_NOSELECT;

	return ret;
}

//-------------------------------------------------------------------------------
// 功能:读取FLASH芯片的生产设备信息
// 参数:无
// 返回值:器件容量,高三位为器件系列;后5位为器件容量
//         001 00100       ;AT45DB041
//         001 00101       ;AT45DB081
//         001 00110       ;AT45DB161
//-------------------------------------------------------------------------------
BYTE GetFlashInfo()
{
	BYTE manufacturers;   // 生产商
	BYTE density;         // 器件容量
	BYTE ret;

	DF_CHIP_SELECT;

	SendSPIByte(FLASH_DEVICEID); // 读取设备信息

	manufacturers=GetSPIByte();  // 生产商
	density=GetSPIByte();        // 器件容量
	ret=GetSPIByte();            // Device Version
	ret=GetSPIByte();

	DF_CHIP_NOSELECT;

	return density;              // 返回器件容量
}


//---------------------------------------------------------------------------
// 功能:从缓冲区1的指定位置star_addr中读入len长度的数据到pBuffer
// 参数:
//       str_addr,WORD:缓冲区起始位置
//       len:     WORD:数据长度
//       pBuffer,  BYTE *:数据缓存指针
// 返回值:BYTE,1:读取成功;0:读取失败
//---------------------------------------------------------------------------
BYTE FlashBuffer1Read(WORD start_addr,WORD len, BYTE *pBuffer) 
{                                       
	WORD i;

	if((start_addr+len)>FLASH_PAGE_BYTE[g_cFlashType])
	{// 地址长度错误
		return 0;
	}

	while((GetFlashStatus()&0x80)==0);  // 检查器件是否准备就绪
	
	DF_CHIP_SELECT; 			        // enable DataFlash

	SendSPIByte(BUFFER_1_READ);		    
	SendSPIByte(0);
	SendSPIByte((BYTE)(start_addr>8));
	SendSPIByte((BYTE)start_addr);
	SendSPIByte(0);
	for (i=0;i<len;i++)
	{
		*pBuffer++ = GetSPIByte();       // read data from SPI
	}

	DF_CHIP_NOSELECT;

	return 1;

}
//----------------------------------------------------------------------
// 功能:从缓冲区2的指定位置start_addr中读入len长度的数据到pBuffer
// 参数:
//       str_addr,WORD:缓冲区起始位置
//       len:     WORD:数据长度
//       pBuffer,  BYTE *:数据缓存指针
// 返回值:BYTE,1:读取成功;0:读取失败
//----------------------------------------------------------------------
BYTE FlashBuffer2Read(WORD start_addr,WORD len, BYTE *pBuffer)
{                                       
	WORD i;

	if((start_addr+len)>FLASH_PAGE_BYTE[g_cFlashType])
	{// 地址长度错误
		return 0;
	}

	while((GetFlashStatus()&0x80)==0);  // 检查器件是否准备就绪

	DF_CHIP_SELECT; 			        // 使能片选
	SendSPIByte(BUFFER_2_READ);		    //缓冲区1为54H  缓冲区2为56H
	SendSPIByte(0);
	SendSPIByte((BYTE)(start_addr>>8));
	SendSPIByte((BYTE)start_addr);
	SendSPIByte(0);
	for (i=0;i<len;i++)
	{
		*pBuffer++ = GetSPIByte();         
	}
	DF_CHIP_NOSELECT;                   // 取消片选

	return 1;
}

//--------------------------------------------------------------
// 功能:将pBuffer中的长度为len的数据写入到Flash缓冲区1中
// 参数:
//       str_addr,WORD:缓冲区起始位置
//       len:     WORD:数据长度
//       pBuffer,  BYTE *:数据缓存指针
// 返回值:BYTE,1:写入成功;0:写入失败
//
//--------------------------------------------------------------
BYTE FlashBuffer1Write(WORD start_addr, WORD len,BYTE *pBuffer) 
{
	WORD  i;

	if(start_addr+len>FLASH_PAGE_BYTE[g_cFlashType])
	{// 地址长度错误
		return 0;
	}

	while((GetFlashStatus()&0x80)==0);  // 检查器件是否准备就绪

	DF_CHIP_SELECT;					    
	SendSPIByte(BUFFER_1_WRITE);
	SendSPIByte(0x00);
	SendSPIByte((BYTE)(start_addr>>8));
	SendSPIByte((BYTE)start_addr);
	for (i=0;i<len;i++)
	{
		SendSPIByte(*pBuffer++);
	}

	DF_CHIP_NOSELECT;

	return 1;
}
//---------------------------------------------------------------
// 功能:将pBuffer中的长度为len的数据写入到Flash缓冲区2中
// 参数:
//       str_addr,WORD:缓冲区起始位置
//       len:     WORD:数据长度
//       pBuffer,  BYTE *:数据缓存指针
// 返回值:BYTE,1:写入成功;0:写入失败
//
//--------------------------------------------------------------
BYTE FlashBuffer2Write(WORD start_addr, WORD len,BYTE *pBuffer)
{
	WORD  i;

	if(start_addr+len>FLASH_PAGE_BYTE[g_cFlashType])
	{// 地址长度错误
		return 0;
	}

	while((GetFlashStatus()&0x80)==0);  // 检查器件是否准备就绪

	DF_CHIP_SELECT;					    
	SendSPIByte(BUFFER_2_WRITE);
	SendSPIByte(0x00);
	SendSPIByte((BYTE)(start_addr>>8));
	SendSPIByte((BYTE)start_addr);
	for (i=0;i<len;i++)
	{
		SendSPIByte(*pBuffer++);
	}

	DF_CHIP_NOSELECT;

⌨️ 快捷键说明

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