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

📄 flash.c

📁 DataFlash芯片AT45DB081读写程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************************
    Module Title        :   flash-management-moudle
    Version             :   0.1
    Written by          :   Ding Jianhong
    Date                :   1-12-9 14:46
    Filename            :   flash.c
    
    Note                :   see below
    Changes to last Ver.:   
    
***************************************************************************************/
#include<at89x52.h>
#include<stdio.h>
#include"typedef.h"
#include"flash.h"
#include"data.h"


#define At45DB081_Select() {ClrSCLK();ClrAt45081CS();}
#define At45DB081_Deselect() {SetAt45081CS();ClrSCLK();}

//all opcode of AT45DB081
#define Opcode_PageRead		0x52
#define Opcode_Buf1Read		0x54
#define Opcode_Buf2Read		0x56
#define Opcode_PageToBuf1	0x53
#define Opcode_PageToBuf2	0x55
#define Opcode_PageComBuf1	0x60
#define Opcode_PageComBuf2	0x61
#define Opcode_Buf1Write	0x84
#define Opcode_Buf2Write	0x87
#define Opcode_Buf1ToPageWithErase	0x83
#define Opcode_Buf2ToPageWithErase	0x86
#define Opcode_Buf1ToPageWithoutErase	0x88
#define Opcode_Buf2ToPageWithoutErase	0x89
#define Opcode_PagePrgForBuf1		0x82
#define Opcode_PagePrgForBuf2		0x85
#define Opcode_AutoPageReWriteForBuf1	0x58
#define Opcode_AutoPageReWriteForBuf2	0x59

#define Opcode_ContinuousRead		0x68

#define Opcode_ReadStatusReg	0x57

//#define FlashTempBufLen	(FlashPageBytes/4)

//uchar idata FlashTempBuf[FlashTempBufLen];
//uchar FlashTempBuf[FlashPageBytes];

uchar _rom FlashDataValidFlag[FlashDataValidFlagNum]=
											{FlashDataValidFlag1,FlashDataValidFlag2,
											 FlashDataValidFlag3,FlashDataValidFlag4};
ulong _rom FlashRangeAdd[FlashDataRangeNum]=
{
	FlashAdd_SystemUsed,FlashAdd_ReservedSector,FlashAdd_RecallRecord,
	FlashAdd_OptRecord,FlashAdd_SelfLrn,FlashAdd_HanZiLib
};

ulong _rom FlashRangeNum[FlashDataRangeNum]=
{
	FlashNum_SystemUsed,FlashNum_ReservedSector,FlashNum_RecallRecord,
	FlashNum_OptRecord,FlashNum_SelfLrn,FlashNum_HanZiLib
};

uchar At45DB081_ReadStatus(void)//do not read status until the Flash is not busy
//return the status,if overtime,return 0xff;
{
	ulong idata TempTimerNum;
	uchar idata i,j;
	At45DB081_Select();
	for(i=0;i<8;i++)//send read status command
	{
		ClrSCLK();
		if(Opcode_ReadStatusReg&Or8BitTab[7-i]) {SetSO();}
		else {ClrSO();}
		SetSCLK();
	}
	//read status 
	TempTimerNum=0;
	ClrSCLK();
	SetSCLK();
	
	do{
		j=0;
		for(i=0;i<8;i++)
		{
			ClrSCLK();
			if(SI) j |= Or8BitTab[7-i];
			SetSCLK();
		}
//printf("Status = %02x\n",(uint)j);
		if(++TempTimerNum==50000)
		{
			At45DB081_Deselect();
			return 0xff;//write overtime:error
		}
	}while(!(j&0x80));//will not read until the Flash is not busy
	At45DB081_Deselect();
	return (j&0xf7);//bit 3 clear to 0
}

void At45DB081_WriteCmd(uchar cmd,ulong Add)
{
	union LongInt idata temp;
	union WordByte idata temp1;
	uchar idata i;
//printf("Write Cmd,cmd=%x,Add=%lx\n",(uint)cmd,(ulong)Add);
	for(i=0;i<8;i++)//send command,MSB
	{
		ClrSCLK();
		if(cmd&Or8BitTab[7-i])
		{
			SetSO();
		}
		else 
		{
			ClrSO();
		}
		SetSCLK();
	}
	temp.Long=Add;
	#ifdef _AT45DB041
	temp.Int.hi &= 0x000f;//the highest 4 bits are reserved
	#endif
	#ifdef _AT45DB081
	temp.Int.hi &= 0x001f;//the highest 3 bits are reserved
	#endif
	#ifdef _AT45DB161
	temp.Int.hi &= 0x003f;//the highest 2 bits are reserved
	#endif
	temp1.Word=temp.Int.hi;
//printf("Write Cmd,High8bit=%x,Low16Bit=%x\n",(uint)temp1.Byte.lo,(uint)temp.Int.lo);
	for(i=0;i<8;i++)//send high 8 bit:MSB
	{
		ClrSCLK();
		if(temp1.Byte.lo&Or8BitTab[7-i]) 
		{
			SetSO();
		}
		else
		{
			ClrSO();
		}
		SetSCLK();
	}
	temp1.Word=temp.Int.lo;
	for(i=0;i<8;i++)//send Low 16 bit:high 8 bit
	{
		ClrSCLK();
		if(temp1.Byte.hi&Or8BitTab[7-i]) 
		{
			SetSO();
		}
		else
		{
			ClrSO();
		}
		SetSCLK();
	}
	for(i=0;i<8;i++)//send Low 16 bit:low 8 bit
	{
		ClrSCLK();
		if(temp1.Byte.lo&Or8BitTab[7-i]) 
		{
			SetSO();
		}
		else
		{
			ClrSO();
		}
		SetSCLK();
	}
/*
	for(i=0;i<16;i++)//send low 16 bit:MSB
	{
		ClrSCLK();
		if(temp.Int.lo&Or16BitTab[15-i])
		{
			SetSO();
		}
		else
		{
			ClrSO();
		}
		SetSCLK();
	}
*/	
}

void At45DB081_SendDoNotCareBits(uchar bitnum)
{
	uchar idata i;
	for(i=0;i<bitnum;i++)
	{
		ClrSCLK();
		_nop();
		SetSCLK();
	}
}


uchar At45DB081_AutoPageReWrite(void)//auto page rewrite 
//return 1:true,return 0:error
{
	uchar idata temp[FlashReWritePageNumByteNum];
	uchar i,j;
	union WordByte idata Word;
	At45DB081_ReadBytesInPage(FlashAdd_ReWritePageNum,FlashReWritePageNumByteNum,temp);//read AutoPage rewrite page number
	Word.Byte.lo=temp[0];
	Word.Byte.hi=temp[1];
	if(Word.Word>=FlashMaxPage)
		Word.Word=0;
	else
		Word.Word += 2;
	temp[0]=Word.Byte.lo;
	temp[1]=Word.Byte.hi;
//printf("Autopage Num=%x\n",(uint)Word.Word);
//write the page number of autopage rewritten 
	//read main page to buffer1
	At45DB081_Select();
	At45DB081_WriteCmd(Opcode_PageToBuf1,FlashAdd_ReWritePageNum);
	At45DB081_Deselect();
	if(At45DB081_ReadStatus()==0xff)return False;//fail to write
	//write buffer1 to main page
	At45DB081_Select();
	At45DB081_WriteCmd(Opcode_PagePrgForBuf1,FlashAdd_ReWritePageNum);
	for(j=0;j<FlashReWritePageNumByteNum;j++)
	{
		for(i=0;i<8;i++)//send bytes,MSB
		{
			ClrSCLK();
			if(temp[j] & Or8BitTab[7-i])
			{
				SetSO();
			}
			else
			{
				ClrSO();
			}
			SetSCLK();
		}
	}
	At45DB081_Deselect();
	if(At45DB081_ReadStatus()==0xff)return False;//fail to write
	
//autopage rewrite
	Word.Word<<=9;//write page num to flash
//printf("Autopage Add1=%x\n",(uint)Word.Word);
	At45DB081_Select();
	At45DB081_WriteCmd(Opcode_AutoPageReWriteForBuf2,Word.Word);
	At45DB081_Deselect();
	if(At45DB081_ReadStatus()==0xff)return False;

//printf("Autopage Add2=%x\n",(uint)(Word.Word+0x200));
	At45DB081_Select();
	At45DB081_WriteCmd(Opcode_AutoPageReWriteForBuf2,Word.Word+0x200);
	At45DB081_Deselect();
	if(At45DB081_ReadStatus()==0xff)return False;

	return True;
}


void At45DB081_ReadBytesInPage(ulong Add,uint ByteNum,uchar * Data)//read bytes from one page
{
	uchar idata i;
	uint idata j;
//printf("Read Bytes In Page!Add=%lx,ByteNum=%x,DataPtr=%x\n",(ulong)Add,(uint)ByteNum,(uint)Data);
	At45DB081_Select();
	At45DB081_WriteCmd(Opcode_PageRead,Add);
	At45DB081_SendDoNotCareBits(32);//wait the AT45DB081 read finish
	ClrSCLK();
	SetSCLK();
	for(j=0;j<ByteNum;j++)
	{
		for(i=0;i<8;i++)//send command,MSB
		{
			ClrSCLK();
			_nop();
			if(SI)  (*(Data+j)) |= Or8BitTab[7-i];
			else (*(Data+j)) &= And8BitTab[7-i];
			SetSCLK();
		}
//printf("%02x ",(uint)*(Data+j));
	}
//printf("\n");
	At45DB081_Deselect();
}


uchar At45DB081_WritBytesInPage(ulong Add,uint ByteNum,uchar * Data)//write bytes to one page
//if return 1:write successfully,return 0:write fail
{
	uchar idata i;
	uint idata j;
//printf("Write Bytes In Page!Add=%lx,ByteNum=%x,DataPtr=%x\n",(ulong)Add,(uint)ByteNum,(uint)Data);
//printf("Write Bytes are:\n");
//for(i=0;i<ByteNum;i++)
//printf("%02x ",(uint)(*(Data+i)));
//printf("\n");
	//read main page to buffer1
	At45DB081_Select();
	At45DB081_WriteCmd(Opcode_PageToBuf1,Add);
	At45DB081_Deselect();

	if(At45DB081_ReadStatus()==0xff)return False;//fail to write
	
	At45DB081_Select();
	At45DB081_WriteCmd(Opcode_PagePrgForBuf1,Add);
	for(j=0;j<ByteNum;j++)
	{
		for(i=0;i<8;i++)//send bytes,MSB
		{
			ClrSCLK();
			if((*(Data+j)) & Or8BitTab[7-i])
			{
				SetSO();
			}
			else
			{
				ClrSO();
			}
			SetSCLK();
		}

⌨️ 快捷键说明

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