📄 fat.c
字号:
{
t=7;//从最后一个短文件名开始,找空格,并丢掉
while(t>0)
{
if(Source->deName[t]!=' ')break;
t--;
}
for(i=0;i<t+1;i++)Desti->F_Name[i] = Source->deName[i];//复制短文件名
if(Desti->F_Attr==0X20&&(Source->deExtension[0]!=0x20))//归档文件且文件后缀不为空
{
Desti->F_Name[i++]='.';//加入"."
for(t=0;t<3;t++)Desti->F_Name[i+t] = Source->deExtension[t];//复制后缀
Desti->F_Name[i+t]='\0';//加入结束符
}else Desti->F_Name[i]='\0';//加入结束符
}
}
return ;
}
//浏览目标文件夹下面的一个文件类
//dir_clust:当前目录所在簇号
//FileInfo :目标文件的实体对象(FileInfoStruct体)
//type :要查找的文件类型:1<<0,mp1;1<<1,mp2;1<<2,mp3;1<<3,mp4;1<<4,m4a;1<<5,3gp;
// 1<<6,3g2;1<<7,ogg;1<<8,acc;1<<9,wma;1<<10,wav;1<<11,mid;
// 1<<12,flac;1<<13,lrc;1<<14,txt;1<<15,c;1<<16,h;1<<17,file;
// 1<<18,fon;1<<19,sys;1<<20,bmp;1<<21,jpg;1<<22,jpeg;
//count :0,返回当前目录下,该类型文件的个数;不为零时,返回第count个文件的详细信息
//返回值 :1,操作成功.0,操作失败
u8 Get_File_Info(u32 dir_clust,FileInfoStruct *FileInfo,u32 type,u16 *count)
{
DWORD sector;
DWORD cluster=dir_clust;
DWORD tempclust;
unsigned char cnt;
unsigned int offset;
unsigned short cont=0;//文件索引标志 <65536
unsigned char j; //long name fat_buffer offset;
unsigned char *p;//long name fat_buffer pointer
direntry *item = 0;
winentry *we =0;
cont=0;
LongNameFlag = 0;//清空长文件名标志
//SD_Init();//初始化SD卡,在意外拔出之后可以正常使用
//goto SD;
if(cluster==0 && FAT32_Enable==0)//FAT16根目录读取
{
for(cnt=0;cnt<RootDirSectors;cnt++)
{
if(SD_ReadSingleBlock(FirstDirSector+cnt,fat_buffer))return 0;//读数错误
for(offset=0;offset<512;offset+=32)
{
item=(direntry *)(&fat_buffer[offset]);//指针转换
//找到一个可用的文件
if((item->deName[0]!=0x2E)&&(item->deName[0]!=0x00)&&(item->deName[0]!=0xe5)
||((item->deName[0]==0x2E)&&(item->deName[1]==0x2E)))//找到一个合法文件.忽略".",使用".."
{
if(item->deAttributes == 0x0f)//找到一个长文件名
{
we = (winentry *)(&fat_buffer[offset]);
j = 26 *( (we->weCnt-1) & WIN_CNT);//长文件名的长度
if(j<MAX_LONG_NAME_SIZE-25)
{
p = &LongNameBuffer[j];//偏移到目标地址
for (j=0;j<10;j++) *p++ = we->wePart1[j];
for (j=0;j<12;j++) *p++ = we->wePart2[j];
for (j=0;j<4;j++) *p++ = we->wePart3[j];
if (we->weCnt & 0x40) (*(unsigned int *)p) = 0;
if ((we->weCnt & WIN_CNT) == 1) LongNameFlag = 1;//最后一个长文件项找到了
}
}else
{
if(type&FileType_Tell(item->deExtension))//找到一个目标文件
{
cont++;//文件索引增加
}
//查找该目录下,type类型的文件个数
if(*count&&cont==*count)
{
////printf("\ncount:%d",*count);
CopyDirentruyItem(FileInfo,item);//复制目录项,提取详细信息
return 1;//找到目标文件成功
}
LongNameFlag=0;//清空长文件名
}
}
}
}
}
else//其他文件夹/FAT32系统
{
tempclust=cluster;
while(1)
{
sector=fatClustToSect(tempclust);
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(SD_ReadSingleBlock(sector+cnt,fat_buffer))return 0;
for(offset=0;offset<512;offset+=32)
{
item=(direntry *)(&fat_buffer[offset]);
if((item->deName[0]!=0x2E)&&(item->deName[0]!=0x00)&&(item->deName[0]!=0xe5)
||((item->deName[0]==0x2E)&&(item->deName[1]==0x2E)))//找到一个合法文件.忽略".",使用".."
{
if(item->deAttributes == 0x0f) //得到一个长文件名
{
we = (winentry *)(&fat_buffer[offset]);
j = 26 *( (we->weCnt-1) & WIN_CNT);
if(j<MAX_LONG_NAME_SIZE-25)
{
p = &LongNameBuffer[j];//p指向长文件名的存放地址
for (j=0;j<10;j++) *p++ = we->wePart1[j];
for (j=0;j<12;j++) *p++ = we->wePart2[j];
for (j=0;j<4;j++) *p++ = we->wePart3[j];
if (we->weCnt & 0x40) (*(unsigned int *)p) = 0;
if ((we->weCnt & WIN_CNT) == 1) LongNameFlag = 1;
}
}
else
{
if(type&FileType_Tell(item->deExtension))//找到一个目标文件
{
cont++;//文件索引增加
}
//查找该目录下,type类型的文件个数
if(*count&&cont==*count)
{
CopyDirentruyItem(FileInfo,item);//复制目录项,提取详细信息
return 1;//找到目标文件成功
}
LongNameFlag=0;//清空长文件名
}
}
}
}
tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
}
}
if(*count==0)
{
*count=cont;//得到总共文件数目
return 1; //操作成功,找到cont个符合条件的文件了
}else return 0; //操作失败,没找到文件,或者出错
}
//打开文件
//FileInfo:文件信息
void F_Open(FileInfoStruct *FileInfo)
{
FileInfo->F_CurClust=FileInfo->F_StartCluster;//当前簇为首簇
FileInfo->F_Offset=0;//偏移扇区为0
}
//读取512个字节
//FileInfo:要读取的文件
//buf :数据缓存区
//返回值 :0,操作失败,1,操作成功
unsigned char F_Read(FileInfoStruct *FileInfo,u8 *buf)
{
DWORD sector;
sector=fatClustToSect(FileInfo->F_CurClust);//得到当前簇号对应的扇区号
if(SD_ReadSingleBlock(sector+FileInfo->F_Offset,buf))return 0;//读数错误
FileInfo->F_Offset++;
if(FileInfo->F_Offset==SectorsPerClust) //簇的尽头,换簇
{
FileInfo->F_Offset=0;
FileInfo->F_CurClust=FAT_NextCluster(FileInfo->F_CurClust);//读取下一个簇号
if((FAT32_Enable==0&&FileInfo->F_CurClust==0xffff) \
||FileInfo->F_CurClust==0x0ffffff8||FileInfo->F_CurClust == 0x0fffffff)return 0;//error
}
return 1;//读取成功
}
//比较两个字符串相等不
//相等,返回1,不相等,返回0;
u8 mystrcmp(u8*s1,u8*s2)
{
u8 len1,len2;
len1=len2=0;
while(*s1!='\0')
{
len1++;s1++;
}
while(*s2!='\0')
{
len2++;s2++;
}
if(len1!=len2)return 0;//不相等
s1-=len1;s2-=len1;
while(*s1!='\0')
{
if(*s1!=*s2)return 0;//不相等
s1++;s2++;
}
return 1;
}
//查找系统文件
//在指定目录下,找寻一个指定类型的指定名字的文件
//cluster:文件夹的簇号!!!
//Name :文件的名字
//type :文件类型
//返回值 :该文件的详细信息/如果 FileInfo.F_StartCluster=0 则说明此次寻找失败
FileInfoStruct F_Search(u32 cluster,unsigned char *Name,u32 type)
{
DWORD sector;
DWORD tempclust;
unsigned char cnt;
unsigned int offset;
direntry *item = 0;
FileInfoStruct FileInfo;
if(cluster==0 && FAT32_Enable==0)//FAT16根目录读取
{
for(cnt=0;cnt<RootDirSectors;cnt++)
{
if(SD_ReadSingleBlock(FirstDirSector+cnt,fat_buffer))
{
FileInfo.F_StartCluster=0;//读数错误
return FileInfo;
}
for(offset=0;offset<512;offset+=32)
{
item=(direntry *)(&fat_buffer[offset]);//指针转换
//找到一个可用的文件
if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))//找到一个合法文件
{
if(item->deAttributes != AM_LFN)//忽略长文件名
{
CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息
if(FileInfo.F_Type&type)//找到一个合适的类型了
{
// //printf("File Name:%s\n",FileInfo.F_Name);
//找到了文件,返回这个文件的首簇
if(mystrcmp(Name,FileInfo.F_Name))
{
return FileInfo;
}
}
LongNameFlag=0;//清空长文件名
}
}
}
}
}else//其他文件夹/FAT32系统
{
tempclust=cluster;
while(1)
{
sector=fatClustToSect(tempclust);
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(SD_ReadSingleBlock(sector+cnt,fat_buffer))
{
FileInfo.F_StartCluster=0;//读数错误
return FileInfo;
}
for(offset=0;offset<512;offset+=32)
{
item=(direntry *)(&fat_buffer[offset]);
if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))
{
if(item->deAttributes != AM_LFN) //忽略长文件名
{
CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息
if(FileInfo.F_Type&type)//找到一个合适的类型了
{ /*
//printf("F_Info->F_Name:%s\n",FileInfo.F_Name);
//printf("F_Info->F_Type:%d\n",FileInfo.F_Type);
//printf("F_Info->F_Size:%d\n",FileInfo.F_Size);
//printf("F_Info->F_StartClusterH:%x\n",FileInfo.F_StartCluster>>8);
//printf("F_Info->F_StartClusterL:%x\n\n",FileInfo.F_StartCluster&0xff); */
//找到了文件,返回这个文件的首簇
if(mystrcmp(Name,FileInfo.F_Name))
{
return FileInfo;
}
}
LongNameFlag=0;//清空长文件名
}
}
}
}
tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
}
}
FileInfo.F_StartCluster=0;//读数错误
return FileInfo;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -