📄 at45.#3
字号:
//--------------------------------------------
// 文件名: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 + -