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

📄 at45d161d.c

📁 这是一个C8051F340的SPI接口驱动AT45DB161D的源码
💻 C
字号:

// AT45D161.C
// ================================== FLASH 驱动函数文件 ================================================
#include  "AT45D161D.h"
#include  "Bos.h"

typedef enum
{
    AT45C_ID                = 0x9f,
	AT45C_STATUS			= 0xd7,
	AT45C_BUF1READ			= 0xd4,
	AT45C_BUF2READ			= 0xd6,
	AT45C_ARRAYREAD			= 0xe8,
	AT45C_PAGEREAD			= 0xd2,
	AT45C_BUF1WRITE			= 0x84,
	AT45C_BUF2WRITE			= 0x87,
	AT45C_PAGEERASE			= 0x81,
	AT45C_BLOCKERASE		= 0x50,
	AT45C_BUF1TOPAGEEW		= 0x83,
	AT45C_BUF2TOPAGEEW		= 0x86,
	AT45C_BUF1TOPAGEW		= 0x88,
	AT45C_BUF2TOPAGEW		= 0x89,
	AT45C_PAGEBUFWRITE1		= 0x82,
	AT45C_PAGEBUFWRITE2		= 0x85,
	AT45C_PAGEREWRITEBUF1	= 0x58,
	AT45C_PAGEREWRITEBUF2	= 0x59,
	AT45C_PAGETOBUF1TRANS	= 0x53,
	AT45C_PAGETOBUF2TRANS	= 0x55,
	AT45C_PAGETOBUF1COMP	= 0x60,
	AT45C_PAGETOBUF2COMP	= 0x61
} AT45CMD;

// 字符转化函数
unsigned char HalfToASC(unsigned char cCh)
{
    if(cCh >=0x00 && cCh <= 0x09)
		return '0' + cCh;
	else if(cCh >= 0x0a && cCh <= 0x0f)
		return cCh - 0x0a + 'A';
	else return ' ';
}

// 系统对SPI接口&FLASH初始化函数
void FLS_Init(unsigned char cCLKRate)
{
	SPI0CFG = SPI_M_CLK1_POL0;//SPI_M_CLK1_POL1;	
	SPI0CN  = 0x0D;              // NSS,使能SPI
	//SPI_NSS = false;
    SPI0CKR = cCLKRate;          
}

// SPI写字节函数
void SPI_WriteByte(unsigned char cData)
{
   SPI0DAT  = cData;                   
   while (!SPIF);   
   SPIF = false;  
}

// SPI读字节函数
unsigned char SPI_ReadByte()
{
   SPI0DAT  = 0x00;                       
   while (!SPIF);   
   SPIF     = false;
   
   return (SPI0DAT);
}

// 读FLASH的ID号函数
BOOL FLS_ReadID()
{
	unsigned char i;
	unsigned char nID[2] = {0} ;
	
	NSSMD0 = false; 
    SPI_WriteByte(AT45C_ID);

	for(i = 0;i < 2;i++)
        nID[i] = SPI_ReadByte();

	NSSMD0 = true;

	if (*(unsigned int *)&nID[0]  == AT45D161D_ID)		
		return true;
	else
		return false;
}

// 等待FLASH就绪状态
unsigned char FLS_WaitRDY()
{
	unsigned char cStatus;
	unsigned int nCount;

	for(nCount = 0; nCount < 5000; nCount++)
	{
		cStatus = FLS_GetStatus();
		if (cStatus & AT45DB_RDY)
			break;
	}
	return cStatus;
}

// 查询状态寄存器状态
unsigned char FLS_GetStatus()
{
	unsigned char cStatus = 0;
    
	NSSMD0 = false; 
	SPI_WriteByte(AT45C_STATUS);
	cStatus = SPI_ReadByte();
	NSSMD0 = true; 
	//-----------debug------------------------------
    /*putchar('+');
	putchar(cStatus);
	putchar(SPI0CN);
	putchar(SPI0CFG);
	putchar('+');*/
	//----------------------------------------------
	return cStatus;
}

// 按页面读函数
BOOL FLS_PageRead(unsigned int PageAddr, unsigned int ByteAddr, unsigned char *cBuf, unsigned int nCount)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB2 |= ((ByteAddr >> 8) & 0x03);
	AB3 = (ByteAddr) & 0xff;

	NSSMD0 = false;
	
	SPI_WriteByte(AT45C_PAGEREAD);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);
	
	SPI_WriteByte(0);   // 4Bytes additional
	SPI_WriteByte(0);
	SPI_WriteByte(0);
	SPI_WriteByte(0);

	while (nCount--)
		*cBuf++ = SPI_ReadByte();

	NSSMD0 = true; 

	return false;
}

// 写数据到FLASH缓存区1函数
BOOL FLS_Buf1Write(unsigned int ByteAddr, unsigned char *cBuf, unsigned int nCount)
{
	unsigned char AB1, AB2, AB3;

	AB1 = 0;
	AB2 = (ByteAddr >> 8) & 0x03;
	AB3 = (ByteAddr) & 0xff;

	NSSMD0 = false; 
	SPI_WriteByte(AT45C_BUF1WRITE);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);
	
	while (nCount--)
		SPI_WriteByte(*cBuf++);

	NSSMD0 = true; 

	return false;
}

// FLASH页擦除函数
BOOL FLS_PageErase(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	NSSMD0 = false; 

	SPI_WriteByte(AT45C_PAGEERASE);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	NSSMD0 = true; 

	FLS_WaitRDY();

	return false;
}

// FLASH缓存区1数据写FLASH页函数
BOOL FLS_Buf1ToPageW(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	NSSMD0 = false; 

	SPI_WriteByte(AT45C_BUF1TOPAGEW);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	NSSMD0 = true;
	
	FLS_WaitRDY();

	return false;
}

// FLASH页面数据到缓存区1操作函数
BOOL FLS_PageToBuf1Trans(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	NSSMD0 = false; 
	SPI_WriteByte(AT45C_PAGETOBUF1TRANS);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	NSSMD0 = true; 
	FLS_WaitRDY();

	return false;
}


// FLASH页面数据和缓存区1的数据比较函数
BOOL FLS_PageToBuf1Comp(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	NSSMD0 = false; 
	SPI_WriteByte(AT45C_PAGETOBUF1COMP);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	NSSMD0 = true; 

	return (FLS_WaitRDY() & AT45DB_COMP) ? false : true;
}


// 系统读缓存区数据判断是否需要擦除函数
BOOL FLS_Buf1NeedErase(unsigned long ByteAddr, unsigned char *cData, unsigned int nCount)
{
	unsigned char AB1, AB2, AB3;
	unsigned char c1, c2;
	bool bOK;

	AB1 = 0;
	AB2 = (ByteAddr >> 8) & 0x03;
	AB3 = (ByteAddr) & 0xff;

	NSSMD0 = false; 
	SPI_WriteByte(AT45C_BUF1READ);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);
	SPI_WriteByte(0);				// 1Bytes additional

	for(bOK = false; nCount; nCount--)
	{
		c1 = SPI_ReadByte();
		c2 = *cData++;
		if ((c1 & c2) != c2)	// Compare data
		{
			bOK = true;
			break;
		}
	}

	NSSMD0 = true;
	
	return bOK;
}

unsigned int FLS_Read(unsigned long Address, void *cData, unsigned int nCount)
{
	unsigned int PageAddr, ByteAddr;
	unsigned long xdata  Cnt, RealCnt;
	unsigned char  *p;

	PageAddr = (unsigned int)(Address / AT45D161D_PAGESIZE);
	ByteAddr = (unsigned int)(Address % AT45D161D_PAGESIZE);

	for(p=(unsigned char *)cData,RealCnt=0;nCount;
		RealCnt += Cnt,PageAddr++,ByteAddr=0,p += Cnt,nCount -= Cnt)
	{
		
		Cnt = (AT45D161D_PAGESIZE - ByteAddr);
		Cnt = (Cnt <= nCount) ? Cnt : nCount;

		FLS_PageRead(PageAddr, ByteAddr, (char *)p, Cnt);
	}

	return RealCnt;
}

//-----------------------------------------------------------------------------------
unsigned int FLS_Write(unsigned long Address, void *cData, unsigned int nCount)
{	
	bool bNeedErase;
	unsigned int PageAddr, ByteAddr;
	unsigned long xdata Cnt, RealCnt;
	unsigned char *p;

	PageAddr = (unsigned int)(Address / AT45D161D_PAGESIZE);
	ByteAddr = (unsigned int)(Address % AT45D161D_PAGESIZE);

	for(p=(unsigned char *)cData,RealCnt=0;nCount;
		RealCnt+=Cnt,PageAddr++,ByteAddr=0,p+=Cnt,nCount-=Cnt)
	{
		Cnt = (AT45D161D_PAGESIZE - ByteAddr);
		Cnt = (Cnt <= nCount) ? Cnt : nCount;

		FLS_PageToBuf1Trans(PageAddr);
		bNeedErase = FLS_Buf1NeedErase(ByteAddr, p, Cnt);
		FLS_Buf1Write(ByteAddr, (unsigned char *)p, Cnt);
		if (bNeedErase)
			FLS_PageErase(PageAddr);
		FLS_Buf1ToPageW(PageAddr);
		if (!FLS_PageToBuf1Comp(PageAddr))
			break;
	}

	return RealCnt;
}

//==================================== 备份函数 =============================================
// AT45DBXX 读缓存1函数
/*BOOL FLS_Buf1Read(unsigned int ByteAddr, unsigned char *cBuf, unsigned int nCount)
{
	unsigned char AB1, AB2, AB3;

	AB1 = 0;
	AB2 = (ByteAddr >> 8) & 0x03;
	AB3 = (ByteAddr) & 0xff;

	SPI_WriteByte(AT45C_BUF1READ);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);
	
	SPI_WriteByte(0);// 1Bytes additional

	while (nCount--)
		*cBuf++ = SPI_ReadByte();

	return false;
}

// AT45DBXX 读缓存2函数
BOOL FLS_Buf2Read(unsigned int ByteAddr, unsigned char *cBuf, unsigned int nCount)
{
	unsigned char AB1, AB2, AB3;

	AB1 = 0;
	AB2 = (ByteAddr >> 8) & 0x03;
	AB3 = (ByteAddr) & 0xff;

	SPI_WriteByte(AT45C_BUF2READ);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);
	
	SPI_WriteByte(0);// 1Bytes additional

	while (nCount--)
		*cBuf++ = SPI_ReadByte();

	return false;
} 

// 连续队列读函数
BOOL FLS_ArrayRead(unsigned int PageAddr, unsigned int ByteAddr, unsigned char *cBuf, unsigned int nCount)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB2 |= ((ByteAddr >> 8) & 0x03);
	AB3 = (ByteAddr) & 0xff;

	SPI_WriteByte(AT45C_ARRAYREAD);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);
	
	SPI_WriteByte(0);   // 4Bytes additional
	SPI_WriteByte(0);
	SPI_WriteByte(0);
	SPI_WriteByte(0);
	
	while (nCount--)
		*cBuf++ = SPI_ReadByte();

	return false;
}

  // 写数据到FLASH缓存区2函数
BOOL FLS_Buf2Write(unsigned int ByteAddr, unsigned char *cBuf, unsigned int nCount)
{
	char AB1, AB2, AB3;

	AB1 = 0;
	AB2 = (ByteAddr >> 8) & 0x03;
	AB3 = (ByteAddr) & 0xff;

	SPI_WriteByte(AT45C_BUF2WRITE);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);
	
	while (nCount--)
		SPI_WriteByte(*cBuf++);

	return false;
}

// FLASH块擦除函数
BOOL AT45_BlockErase(unsigned int nBlock)
{
	unsigned char AB1, AB2, AB3;

	nBlock <<= 5;
	AB1 = (nBlock >> 8) & 0x3f;
	AB2 = (nBlock) & 0xe0;
	AB3 = 0;

	SPI_WriteByte(AT45C_BLOCKERASE);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	FLS_WaitRDY();

	return false;
}

 // 带擦除功能的缓存区1数据写FLASH函数
BOOL FLS_Buf1ToPageEW(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	SPI_WriteByte(AT45C_BUF1TOPAGEEW);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	FLS_WaitRDY();

	return false;
}
  // 带擦除功能的缓存区2数据写FLASH函数
BOOL FLS_Buf2ToPageEW(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	SPI_WriteByte(AT45C_BUF2TOPAGEEW);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	FLS_WaitRDY();

	return false;
}

// FLASH页面数据和缓存区2的数据比较函数
BOOL FLS_PageToBuf2Comp(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	SPI_WriteByte(AT45C_PAGETOBUF2COMP);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	return (FLS_WaitRDY() & AT45DB_COMP) ? false : true;
}

// FLASH页面数据到缓存区2操作函数
BOOL FLS_PageToBuf2Trans(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	SPI_WriteByte(AT45C_PAGETOBUF2TRANS);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	FLS_WaitRDY();

	return false;
}

// FLASH缓存区1数据写FLASH页函数
BOOL FLS_Buf2ToPageW(unsigned int PageAddr)
{
	unsigned char AB1, AB2, AB3;

	PageAddr <<= 2;
	AB1 = (PageAddr >> 8) & 0x3f;
	AB2 = (PageAddr) & 0xfc;
	AB3 = 0;

	SPI_WriteByte(AT45C_BUF2TOPAGEW);
	SPI_WriteByte(AB1);
	SPI_WriteByte(AB2);
	SPI_WriteByte(AB3);

	FLS_WaitRDY();

	return false;
}


*/

⌨️ 快捷键说明

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