📄 fat.c
字号:
0: 没有可用的音乐文件
*****************************************************************************************/
INT8U IsMusicFile(INT8U *strName)
{
INT8U i;
for(i=0; i<3; i++)
{
if(filetype[MP3_TYPE][i]!= strName[i]) break;
}
if(i == 3) return 1; // 是MP3文件
for(i=0; i<3; i++)
{
if(filetype[WMA_TYPE][i]!= strName[i]) break;
}
if(i == 3) return 2; // 是WMA文件
/*
for(i=0;i<3;i++)
{
if(filetype[MID_TYPE][i]!=strName[i]) break;
}
if(i == 3) return 3; // 是MIDI文件
*/
return 0;
}
/*****************************************************************************************
* 名称:fatNextCluster
* 功能:在FAT表中查询下一个簇号
* 输入:INT32U cluster : 当前的簇号
* 返回:INT32U nextCluster : 下一个簇号
*****************************************************************************************/
INT32U fatNextCluster(INT32U cluster)
{
INT32U nextCluster = 0;
INT32U fatOffset;
INT32U sector;
INT16U 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); // 读取下一个簇号
}
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);
}
// 是否文件的结束簇
if (nextCluster >= (CLUST_EOFS & FAT_MASK))
{
nextCluster = CLUST_EOFE;
}
return nextCluster;
}
/*****************************************************************************************
* 名称:GetSysFileSector
* 功能:从 EEPROM 中系统文件簇号表中计算扇区地址
* 输入:void *eep,
* INT16U Cluster : 簇的序号
* 返回:INT32U foffset : 该簇号所对应的扇区地址
*****************************************************************************************/
INT32U GetSysFileSector(void *eep,INT16U Cluster)
{
INT32U foffset;
INT16U i;
while(1)
{
eeprom_read_block(&foffset,eep,4); // 取首簇号 // lvhaian
(INT8U *)eep += 4;
i = eeprom_read_byte(eep); // 取连续的簇号数
if(Cluster<=i)
{
foffset = foffset + (INT32U) (Cluster * SectorsPerCluster); // 得到字模的扇区地址
break;
}
else
{
Cluster -= i; // 超过的连续的簇号
(INT8U *)eep = (INT8U *)eep + 1;
}
}
return foffset;
}
/*****************************************************************************************
* 名称:GetSysFileSector 注: 程序当中好像有点问题,已修改 ,吕海安 2007.5.9
* 功能:在根目录中查找汉字库文件的首簇号及UNITCODE码转换表文件的首簇号
* 输入:INT32U *hzk,
* INT32U *unit
* 返回:无
*****************************************************************************************/
void GetSysFileClust(INT32U *hzk,INT32U *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= (INT32U) ((INT32U)de->deHighClust << 16) + de->deStartCluster;
}
}
if(*unit == 0)
{
if(IsUnitogbFile(de->deName))
{
*unit= (INT32U) ((INT32U)de->deHighClust << 16) + de->deStartCluster;
}
}
if((*hzk != 0) && (*unit != 0))
{
break;
}
}
}
}
de++;
fp.Index++;
if(de->deName[0] == 0) // 等所有文件都已经查询完了
{
break;
}
}while (1);
}
/*****************************************************************************************
* 名称:InitSetPath
* 功能:
* 输入:FIND_FILE_INFO *fp,
* INT32U dircluster
* 返回:无
*****************************************************************************************/
void InitSetPath(FIND_FILE_INFO *fp,INT32U 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;
}
/*****************************************************************************************
* 名称:FindLrcFile
* 功能:在当前的目录中查找歌词文件,找到置相关数据至lyric中
* 输入:INT32U dircluster: 当前目录的首簇号,若是FAT12或FAT16的根目录则为 0
* INT8U *strName
* 返回:无
*****************************************************************************************/
void FindLrcFile(INT32U dircluster,INT8U *strName)
{
FIND_FILE_INFO fp;
DIRENTRY *de = 0;
INT8U name[8];
INT8U i = 0;
WorkFlag &= ~bLrc;
for(i=0; i<8; i++)
{
name[i] = strName[i];
}
InitSetPath(&fp,dircluster);
ReadBlock(fp.Sector); //重新读取目录表
do
{
if(!ReadNextDirEntry(&fp))
{
lyric.Clust=0;
return;
}
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 ?
{
for(i=0; i<8; i++)
{
if(name[i] != de->deName[i])
{
break;
}
}
if(i == 8) // 主文件名比较正确
{
for(i=0; i<3; i++)
{
if(filetype[LRC_TYPE][i] != de->deExtension[i])
{
break;
}
}
if(i == 3)
{
break;
}
}
}
}
}
de++;
fp.Index++;
if(de->deName[0] == 0) // 文件的最后一项
{
lyric.Clust=0;
return;
}
}while(1);
lyric.first = 1;
lyric.t_sec = lyric.t_ms = 0;
WorkFlag |= bLrc;
lyric.so = 0;
lyric.sl = 0;
lyric.wl = 0; // 初始位置
lyric.filelen = (INT16U)de->deFileSize; // 保存歌词文件大小
lyric.Clust = (INT32U) ((INT32U)de->deHighClust << 16) + de->deStartCluster;
}
/*****************************************************************************************
* 名称:FindDirIndex
* 功能:查询一个文件夹中一个文件在 FAT 中排列的序号
* 输入:INT32U fatherdir, :文件夹
* INT32U dircluster :簇号
* 返回:INT16U fileNo : 寻找的文件在文件夹中的序号
* 0 : 查询为空
*****************************************************************************************/
INT16U FindDirIndex(INT32U fatherdir,INT32U dircluster)
{
FIND_FILE_INFO fp;
DIRENTRY *de = 0;
INT16U fileNo = 0;
INT32U tempclust;
InitSetPath(&fp,fatherdir);
ReadBlock(fp.Sector); // 读取目录表
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(!IsCurDir(de->deName))
{
fileNo++;
tempclust=((INT32U)de->deHighClust << 16) + de->deStartCluster;
if(tempclust == dircluster)
{
return fileNo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -