/*********************************************************************** 函数功能:根目录下文件夹和文件数量搜索 操作内容:1、搜索根目录项的目录项数以及属性 2、可以判断文件类型,如文件夹、txt文件、BMP文件、MP3文件等 3、返回文件数量 ***********************************************************************/ void FileCountSearch(void) {/* uint16 BytePerClus, SecPerClus, ClusNum, ClusNext,ClusID,ClusIDValue ,m,Index; uint32 LBA, i; DIR FileDir; SecPerClus = BPB_SecPerClus; BytePerClus = BPB_SecPerClus * BPB_BytesPerSec; //每簇的字节数 Index = GetFileID(Name, &FileDir); //文件根目录位置0~511 */ uint16 DirSecCut, DirStart, i, m;//, Count = 0; DirSecCut = 32; //根目录扇区总数,这里限制FAT16和FAT32都最多为512个根目录项 DirStart = DirStartSec(); //根目录开始扇区地址,FAT16为512 DirectoryCount = 0,FileCount = 0; for(i = 0; i < DirSecCut; i++) //在整个扇区空间搜索 { ReadBlock(DirStart + i); //读根目录扇区 for(m = 0; m < 16; m++) { if((BUFFER[m * 32] != 0) && (BUFFER[m * 32] != 0xe5))//搜索为0x00区域或者0xe5区域,根目录为32位长度的”文件“ { if(BUFFER[m * 32+11] == 0x10) //0x10为文件夹 DirectoryCount++; if(BUFFER[m * 32+11] == 0x20) //0x20为文件 FileCount++; // else //Count=0; } } } }
void WriteDirectoryDIR32(uint16 Index, DIR32* Value) { uint32 LBA = DirStartSec() + Index / 16; ReadBlock(LBA); CopyBytes(Value, &BUFFER[(Index % 16) * 32], 32); WriteBlock(LBA); }
void FormatCard(void) { uint16 i,DirStart,DirSecNum,FatStart,FatSecNum; //ReadBPB(); for(i = 0; i < 512;i++ )BUFFER[i]=0; //清除根目录,填入数据0 DirSecNum = GetDirSecCount(); //FAT16的根目录项数位512,占32个扇区,FAT32根目录项数不定 DirStart = DirStartSec(); //获取根目录开始地址 for(i=0;i<DirSecNum;i++) //按扇区依次填入0 { WriteBlock(DirStart+i); } FatStart = BPB_HiddSec + BPB_RsvdSecCnt; //清除FAT表 FatSecNum = BPB_FATSz16; //FAT表所占扇区数大小 for(i=0;i<FatSecNum;i++) { WriteBlock(FatStart+i); } WriteFAT(0,0xfff8); //FAT表的第一个字固定为0xfff8 WriteFAT(1,0xffff); //FAT表的第二个字固定为0xffff CopyFAT(); //备份FAT表,保持与FAT1一致 }
uint16 GetEmptyDIR() { uint16 DirSecCut, DirStart, i, m, ID = 0; DirSecCut = 32; //GetDirSecCount(); //根目录扇区总数,这里限制FAT16和FAT32都最多为512个根目录项 DirStart = DirStartSec(); //根目录开始扇区地址,FAT16为512 for(i = 0; i < DirSecCut; i++) //在整个扇区空间搜索 { ReadBlock(DirStart + i); //读根目录扇区 for(m = 0; m < 16; m++) { if((BUFFER[m * 32] == 0) || (BUFFER[m * 32] == 0xe5))//搜索为0x00区域或者0xe5区域,根目录为32位长度的”文件“ return ID; //返回可以使用扇区ID else ID++; } } return ID; //表示没有空闲可以使用的项 }
uint8 GetFileID32(uint8 Name[11], DIR32* ID) { uint16 DirSecCut, DirStart, i, m,Index; DirSecCut = 32; //GetDirSecCount();根目录总扇区数,这里将FAT16/32统一到512个根目录项 DirStart = DirStartSec(); //根目录开始扇区 for(i = 0; i < DirSecCut; i++) { ReadBlock(DirStart + i); //读取扇区数据 for(m = 0; m <16; m++) //一个扇区里面有16个项,因为每个项的长度是32位 { if(IsEqual(Name, &((DIR32*)&BUFFER[m * 32])->FileName, 11)) //进行比较,相等返回1 { *ID = *((DIR32*)&BUFFER[m * 32]); //ID实际就是根目录项 Index = i*16+m; //FAT16下一般最大是511,也就是说FAT16下根目录项数一般为512,为保证兼容性 return Index; //找到对应的目录项,返回目录的位置. } } } return 0; //没有找到对应的目录项,返回0. }
void ReadDIR(uint16 Index, DIR* Value) { uint32 DirStart = DirStartSec(); ReadBlock(DirStart + Index / 16); CopyBytes(&BUFFER[(Index % 16) * 32], Value, 32); }
uint32 DataStartSec(void) { return (uint32)(DirStartSec() + (BPB_RootEntCnt * 32) / BPB_BytesPerSec); //乘以32是因为根目录是32位长度文件 }
/******************************************************************************* * Function Name : DataStartSec * Description : Get the data area's start sector NO. * Input : None * Output : None * Return : The data area's start sector NO. *******************************************************************************/ static u32 DataStartSec(void) { return DirStartSec() + BPB_RootEntCnt * 32 / 512; }