📄 fat.c
字号:
#include "fat.h"
unsigned char xdata FAT32_Buffer[512]; //扇区数据读写缓冲区xdata
struct FAT32_Init_Arg Init_Arg; //初始化参数结构体实体
struct FileInfoStruct FileInfo;
/*********************
FAT32中读取扇区的函数
返回对缓冲区的首地址buf
*********************/
unsigned char * FAT32_ReadSector(unsigned long LBA,unsigned char *buf)
{
MMC_get_data_LBA(LBA,512,buf);
return buf;
}
/**********************
FAT32中写扇区的函数
返回0:写扇区成功
返回非0:写扇区失败
**********************/
unsigned char FAT32_WriteSector(unsigned long LBA,unsigned char *buf)
{
return MMC_write_sector(LBA,buf);
}
/***********************
将存储设备读出的数据由小端转为大端
***********************/
unsigned long lb2bb(unsigned char *dat,unsigned char len)//
{
unsigned long temp=0;
unsigned long fact=1;
unsigned char i=0;
for(i=0;i<len;i++)
{
temp+=dat[i]*fact;
fact=fact<<8;
}
return temp;
}
/***************************
查找BPB所在扇区号,这里固定为0扇区
***************************/
unsigned long FAT32_FindBPB() //寻找BPB所在的扇区号
{
FAT32_ReadSector(0,FAT32_Buffer);
return lb2bb(((((struct PartSector *)(FAT32_Buffer))->Part[0]).StartLBA),4);
}
/***********************
存储器的总容量,单位为M
返回为Float型
************************/
unsigned long FAT32_Get_Total_Size()//
{
FAT32_ReadSector(Init_Arg.BPB_Sector_No,FAT32_Buffer);
return ((float)(lb2bb((((struct FAT32_BPB *)(FAT32_Buffer))->BPB_TotSec32),4)))*0.0004883;
}
/*****************************
文件系统初始化
将BPB段的给类信息装入到BPB结构体当中
******************************/
void FAT32_Init(struct FAT32_Init_Arg *arg)
{
struct FAT32_BPB *bpb=(struct FAT32_BPB *)(FAT32_Buffer); //将数据缓冲区指针转为struct FAT32_BPB 型指针
arg->BPB_Sector_No =FAT32_FindBPB(); //FAT32_FindBPB()可以返回BPB所在的扇区号
arg->Total_Size =FAT32_Get_Total_Size(); //FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆
arg->FATsectors =lb2bb((bpb->BPB_FATSz32) ,4); //装入FAT表占用的扇区数到FATsectors中
arg->FirstDirClust =lb2bb((bpb->BPB_RootClus) ,4); //装入根目录簇号到FirstDirClust中
arg->BytesPerSector =lb2bb((bpb->BPB_BytesPerSec),2); //装入每扇区字节数到BytesPerSector中
arg->SectorsPerClust =lb2bb((bpb->BPB_SecPerClus) ,1); //装入每簇扇区数到SectorsPerClust 中
arg->FirstFATSector =lb2bb((bpb->BPB_RsvdSecCnt) ,2)+arg->BPB_Sector_No;//装入第一个FAT表扇区号到FirstFATSector 中
arg->RootDirCount =lb2bb((bpb->BPB_RootEntCnt) ,2); //装入根目录项数到RootDirCount中
arg->RootDirSectors =(arg->RootDirCount)*32>>9; //装入根目录占用的扇区数到RootDirSectors中
arg->FirstDirSector =(arg->FirstFATSector)+(bpb->BPB_NumFATs[0])*(arg->FATsectors); //装入第一个目录扇区到FirstDirSector中
arg->FirstDataSector =(arg->FirstDirSector)+(arg->RootDirSectors); //装入第一个数据扇区到FirstDataSector中
}
/*************************
根文件下目录打印函数
最多可打印一个蔟内的目录
如果一个族的大小为8个扇区,则最多可打印128个目录
*************************/
void FAT32_EnterRootDir()
{
unsigned long iRootDirSector;
unsigned long iDir;
unsigned short y=33;
struct direntry *pDir;
for(iRootDirSector=(Init_Arg.FirstDirSector);iRootDirSector<(Init_Arg.FirstDirSector)+(Init_Arg.SectorsPerClust);iRootDirSector++)
{
FAT32_ReadSector(iRootDirSector,FAT32_Buffer);
for(iDir=0;iDir<Init_Arg.BytesPerSector;iDir+=sizeof(struct direntry))
{
pDir=((struct direntry *)(FAT32_Buffer+iDir));
if((pDir->deName)[0]!=0x00 /*无效目录项*/ && (pDir->deName)[0]!=0xe5 /*无效目录项*/ && (pDir->deName)[0]!=0x0f /*无效属性*/)
{
Printf_File_Name(pDir->deName);/*在此可更换其他显示器件的打印字符串函数*/
pDir->deName[11]=0;
ClearScreen(0,240,y,16,Black);
LCD_PutString(0,y,pDir->deName,White,Black);
y=y+20;
if(y>=288)
{y=33;
//ClearScreen(0,240,0,320,Black);
//button(0,0,"K1",Green);
//button(0,288,"K1",Green);
}
}
}
}
}
/************************
文件名复制函数
*Dname:目的字符串
*filename:源字符串
************************/
void FAT32_CopyName(unsigned char *Dname,unsigned char *filename)
{
unsigned char i=0;
for(;i<11;i++)
{
Dname[i]=filename[i];
}
Dname[i]=0;
}
/************************************
文件名比较函数:用此函数来找到说要查找的文件名以获得其收蔟号
该函数不能对目录名比较
************************************/
unsigned char FAT32_CompareName(unsigned char *sname,unsigned char *dname)
{
unsigned char i,j=8;
unsigned char name_temp[12];
for(i=0;i<11;i++) name_temp[i]=0x20;
name_temp[11]=0;
i=0;
while(sname[i]!='.')//获取文件名并复制到缓冲数组
{
name_temp[i]=sname[i];
i++;
}
i++;
while(sname[i]!=0)//获取扩展文件名并复制到缓冲数组
{
name_temp[j++]=sname[i];
i++;
}
//Printf(name_temp,0);
/*开始进行比较,相同则返回1,不同则返回0*/
for(i=0;i<11;i++)
{
if(name_temp[i]!=dname[i]) return 0;
}
//Printf(name_temp,0);
return 1;
}
/*****************************
获取文件或目录的下一簇号
返回文件下一簇号
实现簇链的功能
*****************************/
unsigned long FAT32_GetNextCluster(unsigned long LastCluster)
{
unsigned long temp;
struct FAT32_FAT *pFAT;
struct FAT32_FAT_Item *pFAT_Item;
temp=((LastCluster/128)+Init_Arg.FirstFATSector);
FAT32_ReadSector(temp,FAT32_Buffer);
pFAT=(struct FAT32_FAT *)FAT32_Buffer;
pFAT_Item=&((pFAT->Items)[LastCluster%128]);
return lb2bb((unsigned char*)pFAT_Item,4);
}
/********
目录名比较函数,用以查找目录确定簇号
*********/
unsigned char FAT32_CompareDir(unsigned char *sname,unsigned char *dname)
{
unsigned char i,j=8;
unsigned char name_temp[12];
for(i=0;i<11;i++) name_temp[i]=0x20;
name_temp[11]=0;
i=0;
while(sname[i]!='\\')
{
name_temp[i]=sname[i];
i++;
}
for(i=0;i<11;i++)
{
if(name_temp[i]!=dname[i]) return 0;
}
//Printf(name_temp,0);
return 1;
}
unsigned long FAT32_EnterDir(char *path)
{
unsigned long iDirSector;
unsigned long iCurSector=Init_Arg.FirstDirSector;
unsigned long iDir;
unsigned short y=32;
struct direntry *pDir;
unsigned char DirName[12],find_flag=0;
unsigned char depth=0,index=0;
unsigned char i=0;
while(path[i]!=0)
{
if(path[i]=='\\')
{
depth++;
index=i+1;
}
i++;
}
if(depth==1)
{
return iCurSector; //如果是根目录,直接返回当前扇区号
}
//if(depth--)
if(depth==2)
{
while(!find_flag)
{for(iCurSector;iCurSector<(Init_Arg.FirstDirSector)+(Init_Arg.SectorsPerClust);iCurSector++)
{FAT32_ReadSector(iCurSector,FAT32_Buffer);
for(iDir=0;iDir<Init_Arg.BytesPerSector;iDir+=sizeof(struct direntry))
{
pDir=((struct direntry *)(FAT32_Buffer+iDir));
if(FAT32_CompareDir(path+1,pDir->deName))//index/path+1
{
FileInfo.FileSize=lb2bb(pDir->deFileSize,4);
strcpy(FileInfo.FileName,path+1);
FileInfo.FileStartCluster=lb2bb(pDir->deLowCluster,2)+lb2bb(pDir->deHighClust,2)*65536;
FileInfo.FileCurCluster=FileInfo.FileStartCluster;
FileInfo.FileNextCluster=FAT32_GetNextCluster(FileInfo.FileCurCluster);
FileInfo.FileOffset=0;
find_flag=1;
break;
}
}
}
}
iCurSector=(FileInfo.FileStartCluster-2)*Init_Arg.SectorsPerClust+Init_Arg.FirstDataSector;
for(iDirSector=iCurSector;iDirSector<iCurSector+(Init_Arg.SectorsPerClust);iDirSector++)
{
FAT32_ReadSector(iDirSector,FAT32_Buffer);//iDirSector
for(iDir=0;iDir<Init_Arg.BytesPerSector;iDir+=sizeof(struct direntry))
{
pDir=((struct direntry *)(FAT32_Buffer+iDir));
if((pDir->deName)[0]!=0x00 /*无效目录项*/ && (pDir->deName)[0]!=0xe5 /*无效目录项*/ && (pDir->deName)[0]!=0x0f /*无效属性*/)
{
Printf_File_Name(pDir->deName);
pDir->deName[11]=0;
ClearScreen(0,240,y,16,Black);
LCD_PutString(0,y,pDir->deName,White,Black);
y=y+20;
if(y>=288)
{y=32;
//ClearScreen(0,240,0,320,Black);
}
}
}
}
}
}
struct FileInfoStruct * FAT32_OpenFile(char *filepath)
{
unsigned char depth=0;
unsigned char i=0,index,len=0;
unsigned long iFileSec,iCurFileSec,iFile;
struct direntry *pFile;
while(filepath[i]!='\0')
{i++;
len++;
}
//unsigned char len=strlen(filepath);
for(i=0;i<len;i++)
{
if(filepath[i]=='\\')
{
depth++;
index=i+1;
}
}
iCurFileSec=FAT32_EnterDir(filepath)/*Init_Arg.FirstDirSector*/;
Printf("iCurFileSec",iCurFileSec);
for(iFileSec=iCurFileSec;iFileSec<iCurFileSec+(Init_Arg.SectorsPerClust);iFileSec++)
{
FAT32_ReadSector(iFileSec,FAT32_Buffer);
for(iFile=0;iFile<Init_Arg.BytesPerSector;iFile+=sizeof(struct direntry))
{
pFile=((struct direntry *)(FAT32_Buffer+iFile));
if(FAT32_CompareName(filepath+index,pFile->deName))
{
PutHex(pFile->deFileSize[0]);
PutHex(pFile->deFileSize[1]);
PutHex(pFile->deFileSize[2]);
PutHex(pFile->deFileSize[3]);
FileInfo.FileSize=lb2bb(pFile->deFileSize,4);
strcpy(FileInfo.FileName,filepath+index);
FileInfo.FileStartCluster=lb2bb(pFile->deLowCluster,2)+lb2bb(pFile->deHighClust,2)*65536;
FileInfo.FileCurCluster=FileInfo.FileStartCluster;
FileInfo.FileNextCluster=FAT32_GetNextCluster(FileInfo.FileCurCluster);
FileInfo.FileOffset=0;
Printf("FileStartCluster",FileInfo.FileStartCluster);
return &FileInfo;
}
}
}
}
void FAT32_ReadFileToBMP(struct FileInfoStruct *pstru,unsigned int x0,unsigned int xlong,unsigned int y0,unsigned int ylong)
{
unsigned long Sub=pstru->FileSize-pstru->FileOffset;
unsigned long iSectorInCluster=0;
unsigned long i=0;
unsigned int x=x0,y=y0;
while(pstru->FileNextCluster!=0x0fffffff) //如果FAT中的簇项为0x0fffffff,说明无后继簇
{
for(iSectorInCluster=0;iSectorInCluster<Init_Arg.SectorsPerClust;iSectorInCluster++) //读出整簇数据
{
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster),FAT32_Buffer);
pstru->FileOffset+=Init_Arg.BytesPerSector;
Sub=pstru->FileSize-pstru->FileOffset;
for(i=0;i<256;i++) //然后写到液晶屏,可以显示256个像素,每个像素16位即2个字节
{
LCD_SetPos(x,x,y,y);
Write_Data(FAT32_Buffer[2*i+1],FAT32_Buffer[2*i]);
x++;
if(x==(x0+xlong)) //检测是否写到屏的边缘 240x320
{
y++;
x=x0;
if(y>=(y0+ylong))
{//y=y0;
goto loop;
}
}
}
}
pstru->FileCurCluster=pstru->FileNextCluster;
pstru->FileNextCluster=FAT32_GetNextCluster(pstru->FileCurCluster); //这里是FAT簇链的传递
}
iSectorInCluster=0;
while(iSectorInCluster<4) //处理不足一簇,而足扇区的数据
{
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster++),FAT32_Buffer);
pstru->FileOffset+=Init_Arg.BytesPerSector;
//Sub=pstru->FileSize-pstru->FileOffset;
for(i=0;i<256;i++) //然后写到液晶屏,可以显示256个像素,每个像素16位即2个字节
{
LCD_SetPos(x,x,y,y);
Write_Data(FAT32_Buffer[2*i+1],FAT32_Buffer[2*i]);
x++;
if(x==(x0+xlong)) //检测是否写到屏的边缘 240x320
{
y++;
x=x0;
if(y>=(y0+ylong))
{//y=y0;
goto loop;
}
}
}
}
loop: y=0;
}
void FAT32_ReadFile(struct FileInfoStruct *pstru)
{
unsigned long Sub=pstru->FileSize-pstru->FileOffset;
unsigned long iSectorInCluster=0;
unsigned long i=0;
unsigned short x=0,y=32;
while(pstru->FileNextCluster!=0x0fffffff) //如果FAT中的簇项为0x0fffffff,说明无后继簇
{
for(iSectorInCluster=0;iSectorInCluster<Init_Arg.SectorsPerClust;iSectorInCluster++) //读出整簇数据
{
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster),FAT32_Buffer);
pstru->FileOffset+=Init_Arg.BytesPerSector;
Sub=pstru->FileSize-pstru->FileOffset;
for(i=0;i<Init_Arg.BytesPerSector;i++)
{
//ClearScreen(0,240,y,16,Black);
LCD_PutChar(x,y,FAT32_Buffer[i],Black,White);
x=x+8;
if(x==240)
{x=0;
y=y+16;
if(y>=288)
{y=32;
//ClearScreen(0,240,0,320,White);
//button(0,0,"K1",Green);
//button(0,288,"K1",Green);
}
}
send(FAT32_Buffer[i]); //将数据发送到终端上显示
}
}
pstru->FileCurCluster=pstru->FileNextCluster;
pstru->FileNextCluster=FAT32_GetNextCluster(pstru->FileCurCluster); //这里是FAT簇链的传递
}
iSectorInCluster=0;
while(Sub>=Init_Arg.BytesPerSector) //处理不足一簇,而足扇区的数据
{
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster++),FAT32_Buffer);
pstru->FileOffset+=Init_Arg.BytesPerSector;
Sub=pstru->FileSize-pstru->FileOffset;
for(i=0;i<Init_Arg.BytesPerSector;i++)
{
//ClearScreen(0,240,y,16,Black);
LCD_PutChar(x,y,FAT32_Buffer[i],Black,White);
x=x+8;
if(x==240)
{x=0;
y=y+16;
if(y>=288)
{y=32;
//ClearScreen(0,240,0,320,White);
//button(0,0,"K1",Green);
//button(0,288,"K1",Green);
}
}
send(FAT32_Buffer[i]);
}
}
FAT32_ReadSector((((pstru->FileCurCluster)-2)*(Init_Arg.SectorsPerClust))+Init_Arg.FirstDataSector+(iSectorInCluster),FAT32_Buffer); //读取最后一个扇区
for(i=0;i<Sub;i++) //Sub为最后剩余的字节数
{
//ClearScreen(0,240,y,16,Black);
LCD_PutChar(x,y,FAT32_Buffer[i],Black,White);
x=x+8;
if(x==240)
{x=0;
y=y+16;
if(y>=288)
{y=32;
//ClearScreen(0,240,0,320,White);
//button(0,0,"K1",Green);
//button(0,288,"K1",Green);
}
}
send(FAT32_Buffer[i]);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -