📄 fat.c
字号:
/************************************************************/
/* FAT */
/* */
/************************************************************/
#include <avr/io.h>
#include <string.h>
#include <avr/eeprom.h>
#include "sd.h"
#include "fat.h"
#include "lcd.h"
extern uchar BUFFER[512];
extern uchar WorkFlag;
unsigned char FatType; //0:FAT12 1:FAT16 2:FAT32
unsigned long FAT_MASK;
unsigned int RootDirEnts; //根目录总的项数(FAT12&FAT16)
unsigned long FirstDataSector; //数据区
unsigned int BytesPerSector;
unsigned int SectorsPerCluster;
unsigned long FirstFATSector;
ROOTDIR_INF RootDir; //目录区FIND_FILE_INFO FindInfo;
//********************************************************************************************
//读一个扇区
void ReadBlock(unsigned long LBA)
//********************************************************************************************
{ unsigned long temp;
temp=LBA<<9;
SD_Read_Block(temp);
}
void ReadBlockToBuff(unsigned long LBA,unsigned char *pbuff)
{
unsigned long temp;
temp=LBA<<9;
SD_Read_Block2(temp,pbuff);
}
unsigned long fatGetRootSector(void)
{
if(FatType == FAT32)
return ((RootDir.Clust-2)* SectorsPerCluster) +FirstDataSector;
return RootDir.Sector;
}
unsigned long fatGetRootClust(void)
{
if(FatType==FAT32) return RootDir.Clust;
return 0x00000000;
}
/*-----------------------------------------------------------------------
查询数据区一个簇开始扇区号
-----------------------------------------------------------------------*/
unsigned long fatClustToSect(unsigned long clust)
{
return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}
/*-----------------------------------------------------------------------
查询一个簇所占扇区数
-----------------------------------------------------------------------*/
unsigned int fatClusterSize(void)
{
// return the number of sectors in a disk cluster
return SectorsPerCluster;
}
//文件系统初始化
unsigned char fatInit()
{
PARTRECORD PartInfo;
BPB710 *bpb=0;
ReadBlock(0); // 读取分区表信息
PartInfo = *((PARTRECORD *) ((PARTSECTOR *)BUFFER)->psPart);
// 引导扇区号在PartInfo.prStartLBA中
ReadBlock(PartInfo.prStartLBA); //ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
bpb = (BPB710 *) &((BOOTSECTOR710 *) BUFFER)->bsBPB;
FirstDataSector = PartInfo.prStartLBA;
if(bpb->bpbFATsecs)
{
// bpbFATsecs非0,为FAT16,FAT表所占的扇区数在bpbFATsecs里
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
}
else
{
// bpbFATsecs是0,为FAT32,FAT表所占的扇区数在bpbBigFATsecs里
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
}
SectorsPerCluster = bpb->bpbSecPerClust;
BytesPerSector = bpb->bpbBytesPerSec;
FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA;
switch (PartInfo.prPartType)
{
case PART_TYPE_FAT12:
RootDir.Sector= FirstDataSector;
FirstDataSector += ((bpb->bpbRootDirEnts*32)/BytesPerSector);
RootDirEnts = bpb->bpbRootDirEnts;
FatType = FAT12;
FAT_MASK=FAT12_MASK;
break;
case PART_TYPE_DOSFAT16:
case PART_TYPE_FAT16:
case PART_TYPE_FAT16LBA:
RootDir.Sector = FirstDataSector;
FirstDataSector += (bpb->bpbRootDirEnts*32)/BytesPerSector;
RootDirEnts = bpb->bpbRootDirEnts;
FatType = FAT16;
FAT_MASK=FAT16_MASK;
break;
case PART_TYPE_FAT32LBA:
case PART_TYPE_FAT32:
RootDir.Clust = bpb->bpbRootClust;
FAT_MASK=FAT32_MASK;
FatType = FAT32;
break;
default:
return 0;
}
return 1;
}
#define MP3_TYPE 0
#define WMA_TYPE 1
#define MID_TYPE 2
#define LRC_TYPE 3
unsigned char filetype[][3] PROGMEM ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};
unsigned char hzk12[][11] PROGMEM =
{{"HZK12 "},
{"UNITOGB BIN"},
{". "},
{".. "}
};
unsigned char IsHzk12File(unsigned char *pbuf)
{
unsigned char i;
for(i=0;i<11;i++){
if(pgm_read_byte(hzk12[0]+i)!=pbuf[i]) break;
}
if(i==11) return 1; //find ok
return 0;
}
unsigned char IsUnitogbFile(unsigned char *pbuf)
{
unsigned char i;
for(i=0;i<11;i++){
if(pgm_read_byte(hzk12[1]+i)!=pbuf[i]) break;
}
if(i==11) return 1; //find ok
return 0;
}
unsigned char IsFatherDir(unsigned char *strName)
{
unsigned char i;
for(i=0;i<3;i++){
if(pgm_read_byte(hzk12[3]+i)!=strName[i]) break;
}
if(i==3) return 1; //是上层目录
return 0;
}
unsigned char IsCurDir(unsigned char *strName)
{
unsigned char i;
for(i=0;i<3;i++){
if(pgm_read_byte(hzk12[2]+i)!=strName[i]) break;
}
if(i==3) return 1; //是当前目录
return 0;
}
unsigned char IsMusicFile(unsigned char *strName)
{
unsigned char i;
for(i=0;i<3;i++){
if(pgm_read_byte(filetype[MP3_TYPE]+i)!=strName[i]) break;
}
if(i==3) return 1; //是MP3文件
for(i=0;i<3;i++){
if(pgm_read_byte(filetype[WMA_TYPE]+i)!=strName[i]) break;
}
if(i==3) return 2; //是WMA文件
/*
for(i=0;i<3;i++){
if(pgm_read_byte(filetype[MID_TYPE]+i)!=strName[i]) break;
}
if(i==3) return 3; //是MIDI文件
*/
return 0;
}
/*-----------------------------------------------------------------------
在FAT表中查询下一个簇号
-----------------------------------------------------------------------*/
unsigned long fatNextCluster(unsigned long cluster)
{
unsigned long nextCluster=0;
unsigned long fatOffset;
unsigned long sector;
unsigned int offset;
if(FatType==FAT32 ) // 一个表项为4bytes(32 bits)
{
fatOffset = cluster << 2;
sector = FirstFATSector + (fatOffset / BytesPerSector); //计算FAT扇区号
offset = fatOffset % BytesPerSector; //计算FAT扇区号中表项的偏移地址
nextCluster=SD_Read_Dword(sector,offset);
//ReadBlock(sector); // 读取下一个簇号
//nextCluster = (*((unsigned long*) &((char*)BUFFER)[offset])) ;
}else if(FatType==FAT16){ // 一个表项为2bytes(16 bits)
fatOffset = cluster << 1; //计算FAT扇区号
sector = FirstFATSector + (fatOffset / BytesPerSector);
offset = fatOffset % BytesPerSector;//计算FAT扇区号中表项的偏移地址
nextCluster=SD_Read_Word(sector,offset);
// ReadBlock(sector);
// nextCluster = (*((unsigned int*) &((char*)BUFFER)[offset])) ;
}else if(FatType==FAT12){ // 一个表项为1.5bytes(12 bits)
fatOffset = cluster+(cluster>>1);
sector = FirstFATSector + (fatOffset / BytesPerSector);
offset = fatOffset % BytesPerSector;
// ReadBlock(sector);
if(offset==(BytesPerSector-1)){
nextCluster=SD_Read_Word(sector,offset-1)>>8;
// nextCluster=(unsigned long)BUFFER[offset]; //低位
// ReadBlock(sector+1);
nextCluster|=((SD_Read_Word(sector+1,0)<<8)&0x0000ffff);
// nextCluster|=(BUFFER[0]<<8)&0x0000ffff; //高位,必须与,否则会出现错误
}else{
nextCluster=SD_Read_Word(sector,offset);
// nextCluster =(*((unsigned int*) &((char*)BUFFER)[offset])) ;
}
if(cluster&0X00000001){ //取低12位地址
nextCluster>>=4;
}else{ //取高12位地址
nextCluster&=0x00000fff;
}
}
// 是否文件的结束簇
if (nextCluster >= (CLUST_EOFS & FAT_MASK))
nextCluster = CLUST_EOFE;
return nextCluster;
}
//在根目录中查找汉字库文件的首簇号及UNITCODE码转换表文件的首簇号---
//
void GetSysFileClust(unsigned long *hzk,unsigned long *unit)
{
DIRENTRY *de=0;
FIND_FILE_INFO fp;
InitSetPath(&fp,fatGetRootClust());
ReadBlock(fp.Sector); //重新读取目录表
(*hzk)=(*unit)=0;
do{
if(!ReadNextDirEntry(&fp)) break;
de = (DIRENTRY *)BUFFER;
de+=fp.Index;
if(*de->deName != 0xe5){
if((de->deAttributes&ATTR_LONG_FILENAME)!=ATTR_LONG_FILENAME){
if((de->deAttributes&ATTR_DIRECTORY)!= ATTR_DIRECTORY)// is it a directory ?
if(*hzk==0){
if(IsHzk12File(de->deName))
*hzk= (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
}
if(*unit==0){
if(IsUnitogbFile(de->deName))
*unit= (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
}
if((*hzk!=0)&&(*unit!=0)) break;
}
}
de++;
fp.Index++;
if(de->deName[0]==0) break;
}while (1);
}
void InitSetPath(FIND_FILE_INFO *fp,unsigned long dircluster)
{
fp->Nums=0x8000; //高位为1表示不是FAT12&fat16的根目录
fp->Clust=dircluster;
if(dircluster==0x00000000){ //根目录区
if(FatType==FAT32){
fp->Sector= fatClustToSect(RootDir.Clust);
fp->Clust = RootDir.Clust;
}else{
fp->Sector = RootDir.Sector; //得到目录区的扇区号
fp->Nums = RootDirEnts;
} //此时根目录项数是确定大小的
}else{
fp->Sector=fatClustToSect(dircluster);
}
fp->Index = 0;
fp->NumSector=0;
}
//在当前的目录中查找歌词文件,找到置相关数据至lyric中
//入口: 1.dircluster 当前目录的首簇号,若是FAT12或FAT16的根目录则为0
void FindLrcFile(unsigned long dircluster,unsigned char *strName)
{
FIND_FILE_INFO fp;
DIRENTRY *de=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -