📄 flash.c
字号:
/***************************************************************************************
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 + -