📄 fat32.c
字号:
#include "Fat32.h"
#include "mmc.h"
#define ReadSdOffset 2//26 //2 //24 //23279
#define WRITE_SD_BYTES 120 //23279
#define UARTBUF_LENGTH 32*512 //16384 //520//
#define BUFFER_LENGTH 16*512 //8192 //520 //
#define MAX_READ_LENGTH 32*512 //16384 //1024//
#define MAX_WRITE_LENGTH 2048 //1024//
//#define NULL 0
#define TRUE 1
#define FALSE 0
//xdata ShowFileName_Def ShowFileName[MaxLFNum]; //long file struct
SYS_INFO_BLOCK DeviceInfo;
FILE_INFO ThisFile;
DIR_INFO ThisDir;
unsigned char DBUF[512]; //DBUF[BUFFER_LENGTH];1024
//unsigned char CurFatSector[512];
//xdata unsigned char FATBUF[512];
unsigned char UARTBUF[32]; //[512]; //
unsigned int FreeCFsize,TotalCFsize,FileNum;
unsigned char NewFile[32];//DirBuf[5*32],
unsigned char bXXGFlags=0;
unsigned char zzFileFlag;//文件打开成功标识
unsigned int DirStartCluster,NowCluster;
unsigned long NowSector;
unsigned long DirStartCluster32,NowCluster32;
unsigned int zzSecNums,zzFAT1,zzFDT,zzSecPerClus;
//void InitSD(void);
void InitSdFileSystem(void);
//void DelOldFile(void);
void DelOldFile(unsigned char *name);
unsigned char WriteFile(unsigned long writeLength,unsigned char *pBuffer);
unsigned char RemoveFile(unsigned char *pBuffer);
unsigned char Year,Month,Date,gHour,gMin,gSec;
void DisplayHex(unsigned char x,unsigned char y,unsigned char zu);
//extern unsigned char RBC_Write(unsigned long lba,unsigned char len,unsigned char *pBuffer); //写sd卡
//extern unsigned char RBC_Read(unsigned long lba,unsigned char len,unsigned char *pBuffer); //读sd卡
extern void DisNoFat(void);
extern void DisDelFile(void);
extern void DisNoFile(void);
extern unsigned char GetKey(void);
extern void SendData(uchar txdata);
extern void v_Get1302(unsigned char *ucCurtime);
extern void v_Get1302Date(unsigned char *ucCurtime);
extern void DisplayInt(unsigned char x,unsigned char y,unsigned int zu);
extern void DisDelIng(void);
void DelayMs(unsigned char nFactor)
{
unsigned char i;
unsigned int j;
for(i=0; i<nFactor; i++)
{
for(j=0;j<1000;j++)
j=j;
}
}
unsigned int LSwapINT16(unsigned short dData1,unsigned short dData2)
{
unsigned int dData;
dData = ((dData2<<8)&0xff00)|(dData1&0x00ff);
return dData;
}
unsigned long LSwapINT32(unsigned long dData1,unsigned long dData2,unsigned long dData3,unsigned long dData4)
{
unsigned long dData;
dData = ((dData4<<24)&0xff000000)|((dData3<<16)&0xff0000)|((dData2<<8)&0xff00)|(dData1&0xff);
return dData;
}
//得到在数据扇区中,簇号所对应的扇区
unsigned long FirstSectorofCluster32(unsigned long clusterNum)
{
unsigned long temp;
temp=clusterNum-2;
temp=temp*DeviceInfo.BPB_SecPerClus;
temp=temp+DeviceInfo.FirstDataSector;
return temp;
}
//得到在FAT中簇号所对应的扇区
unsigned long ThisFatSecNum32(unsigned long clusterNum)
{
unsigned long temp;
temp=clusterNum*4;
temp=temp/DeviceInfo.BPB_BytesPerSec;
temp=temp+DeviceInfo.FatStartSector;
return temp;
}
//得到在FAT中簇号的偏移位置
unsigned long ThisFatEntOffset32(unsigned long clusterNum)
{
unsigned long temp1,temp2;
temp1=4*clusterNum;
temp2=temp1/DeviceInfo.BPB_BytesPerSec;
temp1=temp1-temp2*DeviceInfo.BPB_BytesPerSec;
return temp1;
}
//得到下一簇的簇号或结束标志(0xFFFF)
unsigned long GetNextClusterNum32(unsigned long clusterNum)
{
unsigned long FatSecNum,FatEntOffset;
FatSecNum=ThisFatSecNum32(clusterNum);
FatEntOffset=ThisFatEntOffset32(clusterNum);
if(ThisFile.FatSectorPointer!=FatSecNum)
{
if(!RBC_Read(FatSecNum,1,DBUF))
return 0xFFFFFFFF;
ThisFile.FatSectorPointer=FatSecNum;
}
///////////////////////////////////////////////////
//有可能是0xFFFF(结束标志)或下一簇的簇号
clusterNum=LSwapINT32(DBUF[FatEntOffset],DBUF[FatEntOffset+1],DBUF[FatEntOffset+2],DBUF[FatEntOffset+3]);
return clusterNum;
}
//pointer--文件要定位的偏移(文件长度)
unsigned char GoToPointer32(unsigned long pointer)
{
unsigned int clusterSize;
clusterSize=DeviceInfo.BPB_SecPerClus*DeviceInfo.BPB_BytesPerSec;//一个簇所占扇区大小16*512
ThisFile.ClusterPointer=ThisFile.StartCluster;//文件的起始簇
while(pointer>clusterSize)
{
pointer-=clusterSize;
ThisFile.ClusterPointer=GetNextClusterNum32(ThisFile.ClusterPointer);
if(ThisFile.ClusterPointer==0xffffffff)//到文件结尾了
{
return FALSE;
}
}
ThisFile.SectorofCluster=pointer/DeviceInfo.BPB_BytesPerSec;//偏移在第几个扇区(=0则在文件的起始扇区)
ThisFile.SectorPointer=FirstSectorofCluster32(ThisFile.ClusterPointer)+ThisFile.SectorofCluster;//定位扇区
ThisFile.OffsetofSector=pointer-ThisFile.SectorofCluster*DeviceInfo.BPB_BytesPerSec;//在扇区中的具体偏移位置
ThisFile.FatSectorPointer=0;
return TRUE;
}
unsigned char DeleteClusterLink32(unsigned long clusterNum)
{
unsigned long FatSecNum,FatEntOffset;
unsigned char i;
while((clusterNum>1)&&(clusterNum<DeviceInfo.TotCluster))//判别是否属于已分配的簇
{
FatSecNum=ThisFatSecNum32(clusterNum);
FatEntOffset=ThisFatEntOffset32(clusterNum);
if(RBC_Read(FatSecNum,1,DBUF))
clusterNum=LSwapINT32(DBUF[FatEntOffset],DBUF[FatEntOffset+1],DBUF[FatEntOffset+2],DBUF[FatEntOffset+3]);
else
return FALSE;
DBUF[FatEntOffset]=0x00;
DBUF[FatEntOffset+1]=0x00;
DBUF[FatEntOffset+2]=0x00;
DBUF[FatEntOffset+3]=0x00;
for(i=0;i<DeviceInfo.BPB_NumFATs;i++)//两个Fat,BPB_NumFATs=2;
{
DelayMs(5);
if(!RBC_Write((FatSecNum+i*DeviceInfo.BPB_FATSz32),1,DBUF))//BPB_FATSz16=250(248),fat所占的扇区数
return FALSE; //FatSecNum+i*DeviceInfo.BPB_FATSz16,第二个fat相应的偏移扇区
}
}
return TRUE;
}
//取得空闲簇号,写入0xFFFFFFFF
unsigned long GetFreeCusterNum32(void)
{
unsigned long clusterNum,i;
unsigned long sectorNum;
unsigned char j;
clusterNum=0;
sectorNum=DeviceInfo.FatStartSector;
while(sectorNum<(DeviceInfo.BPB_FATSz32+DeviceInfo.FatStartSector))//BPB_FATSz32=250(248),fat所占的扇区数
{
if(!RBC_Read(sectorNum,1,DBUF))
return 0x0;
for(i=0;i<DeviceInfo.BPB_BytesPerSec;i=i+4)
{
if((DBUF[i]==0)&&(DBUF[i+1]==0)&&(DBUF[i+2]==0)&&(DBUF[i+3]==0))
{
DBUF[i]=0xff;DBUF[i+1]=0xff;DBUF[i+2]=0xff;DBUF[i+3]=0xff;
for(j=0;j<DeviceInfo.BPB_NumFATs;j++)
{
DelayMs(5);
if(!RBC_Write((sectorNum+j*DeviceInfo.BPB_FATSz32),1,DBUF))
return FALSE;
}
return clusterNum; //返回空闲簇号
}
clusterNum++; //簇号+1
}
sectorNum=(4*clusterNum)/DeviceInfo.BPB_BytesPerSec+DeviceInfo.FatStartSector;//相当于sectorNum++;下一扇区
DelayMs(10);
}
return 0x0;
}
unsigned long CreateClusterLink32(unsigned long currentCluster)
{
unsigned long newCluster;
unsigned long FatSecNum,FatEntOffset;
unsigned char i;
newCluster=GetFreeCusterNum32();//得到空闲簇簇号
FatSecNum=ThisFatSecNum32(currentCluster);
FatEntOffset=ThisFatEntOffset32(currentCluster);
if(RBC_Read(FatSecNum,1,DBUF))
{
DBUF[FatEntOffset]=newCluster;
DBUF[FatEntOffset+1]=newCluster>>8;
DBUF[FatEntOffset+2]=newCluster>>16;
DBUF[FatEntOffset+3]=newCluster>>24;
for(i=0;i<DeviceInfo.BPB_NumFATs;i++)
{
DelayMs(5);
if(!RBC_Write((FatSecNum+i*DeviceInfo.BPB_FATSz32),1,DBUF))
return FALSE;
}
}
else
return 0x00;
return newCluster;
}
unsigned char OpenFile32(unsigned char *pBuffer)
{
unsigned int i;
unsigned char j,bstop,sector;
//if(!bFlags.bits.SLAVE_IS_ATTACHED)
// return FALSE;
ThisFile.bFileOpen=0;
bstop=0;
NowCluster32=DirStartCluster32;
do
{
NowSector=FirstSectorofCluster32(NowCluster32);
for(sector=0;sector<DeviceInfo.BPB_SecPerClus;sector++)
{
if(!RBC_Read((NowSector+sector),1,DBUF))
return FALSE;
for(i=0;i<DeviceInfo.BPB_BytesPerSec;i=i+32)
{
if(DBUF[i]==0x00)
return FALSE;
j=0;
while(DBUF[i+j]==*(pBuffer+j))//字符相等时,(即找到文件),11个字符
{
j=j+1;
if(j>10)
break;
}
if(j>10&&(DBUF[i+11]&0x10)!=0x10)
{
for(j=0;j<32;j++)
UARTBUF[j]=DBUF[i+j];
bstop=1;
break;
}
}
if(bstop==1)break;
}
if(bstop==1)break;
NowCluster32=GetNextClusterNum32(NowCluster32);
}while(NowCluster32<=DeviceInfo.TotCluster);
if(NowCluster32>DeviceInfo.TotCluster)
return FALSE;
ThisFile.bFileOpen=1;
ThisFile.StartCluster=LSwapINT32(UARTBUF[26],UARTBUF[27],UARTBUF[20],UARTBUF[21]);//起始簇号
ThisFile.LengthInByte=LSwapINT32(UARTBUF[28],UARTBUF[29],UARTBUF[30],UARTBUF[31]);//文件长度
ThisFile.ClusterPointer=ThisFile.StartCluster;
ThisFile.SectorPointer=FirstSectorofCluster32(ThisFile.StartCluster);//得到在数据扇区中,起始簇号所对应的扇区
ThisFile.OffsetofSector=0;
ThisFile.SectorofCluster=0;
ThisFile.FatSectorPointer=0;
ThisFile.pointer=0;
//Response.len=32;
return TRUE;
}
unsigned char ReadFile32(unsigned long readLength,unsigned char *pBuffer)
{
unsigned int len,i;
unsigned int tlen;
//unsigned long blen;
//if(!bFlags.bits.SLAVE_IS_ATTACHED)
// return FALSE;
if(!ThisFile.bFileOpen)
return FALSE;
//blen=readLength;
tlen=0;
if(readLength>MAX_READ_LENGTH)
return FALSE;
if((readLength+ThisFile.pointer)>ThisFile.LengthInByte)
return FALSE;
////////////////////////////////////////////
while(readLength>0)
{
if((readLength+ThisFile.OffsetofSector)>DeviceInfo.BPB_BytesPerSec)
len=DeviceInfo.BPB_BytesPerSec;
else
len=readLength+ThisFile.OffsetofSector;
//////////////////////////////////////////////////////
if(ThisFile.OffsetofSector>0)
{
if(RBC_Read(ThisFile.SectorPointer,1,DBUF))
{
len=len-ThisFile.OffsetofSector;
for(i=0;i<len;i++)
*(pBuffer+i)=DBUF[ThisFile.OffsetofSector+i];
ThisFile.OffsetofSector=ThisFile.OffsetofSector+len;
}
else
return FALSE;
}
else
{
if(!RBC_Read(ThisFile.SectorPointer,1,(pBuffer+tlen)))
return FALSE;
ThisFile.OffsetofSector=len;
}
////////////////////////////////////////////////////////////
readLength-=len;
tlen+=len;
/////////////////////////////////////////////////////////
if((ThisFile.OffsetofSector>(DeviceInfo.BPB_BytesPerSec-1))&&(tlen+ThisFile.pointer<ThisFile.LengthInByte))
{
ThisFile.OffsetofSector-=DeviceInfo.BPB_BytesPerSec;
ThisFile.SectorofCluster+=1;
if(ThisFile.SectorofCluster>DeviceInfo.BPB_SecPerClus-1)
{
ThisFile.SectorofCluster=0;
ThisFile.ClusterPointer=GetNextClusterNum32(ThisFile.ClusterPointer);
if(ThisFile.ClusterPointer>DeviceInfo.TotCluster)
return FALSE;
ThisFile.SectorPointer=FirstSectorofCluster32(ThisFile.ClusterPointer);
}
else
ThisFile.SectorPointer=ThisFile.SectorPointer+1;
}
//////////////////////////////////////////////////////////////////
}//end while
ThisFile.bFileOpen=1;
ThisFile.pointer+=tlen;
//////////////////////////////////////////////
//Response.len=blen;
return TRUE;
}
unsigned char SetFilePointer32(unsigned long pointer)
{
//if(!bFlags.bits.SLAVE_IS_ATTACHED)
// return FALSE;
if(!ThisFile.bFileOpen)
return FALSE;
///////////////////////////////////////////////////////////
ThisFile.pointer=pointer;
if(ThisFile.pointer>ThisFile.LengthInByte)
return FALSE;
if(!GoToPointer32(ThisFile.pointer))
{
ThisFile.bFileOpen=0;
return FALSE;
}
//////////////////////////////////////////////
return TRUE;
}
//len--长文件名所占的字节数,为0 时表示该文件为短文件名
//*pBuffer-32 字节的短文件名目录项
//unsigned char CreateFile32(unsigned long len,unsigned char *pBuffer,unsigned char *pName)
unsigned char CreateFile32(unsigned long len,unsigned char *pBuffer)
{
unsigned int sector,i,j;//,DirCount
unsigned long cnum;
unsigned char bstop;//,InByte,bwrite
unsigned long ClusterPointer;
//if(!bFlags.bits.SLAVE_IS_ATTACHED)
// return FALSE;
if((len%32)!=0)
return FALSE;
if((len+32)>DeviceInfo.BPB_BytesPerSec)
return FALSE;
ThisFile.bFileOpen=0;
bstop=0;
cnum=GetFreeCusterNum32();
if(cnum<0x02)
return FALSE;
pBuffer[21]=(unsigned char)(cnum>>24);
pBuffer[20]=(unsigned char)(cnum>>16);
pBuffer[27]=(unsigned char)(cnum>>8);
pBuffer[26]=(unsigned char)(cnum);
pBuffer[28]=0;pBuffer[29]=0;pBuffer[30]=0;pBuffer[31]=0;
bstop=0;
NowCluster32=DirStartCluster32;
do
{
NowSector=FirstSectorofCluster32(NowCluster32);
ClusterPointer=NowCluster32;
for(sector=0;sector<DeviceInfo.BPB_SecPerClus;sector++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -