📄 fat16.c
字号:
/*
* Copyright (c) 2004,北京博创兴业科技有限公司
* All rights reserved.
*
* 文件名称:fat16.c
* 文件标识:fat16
* 摘 要:fat操作的函数实现
*
* 当前版本:2.0
* 作 者:Kent
* 完成日期:2004年5月20日
*
* 取代版本:1.1
* 原作者 :Frank
* 完成日期:2003年8月10日
*/
#include "Fat16.h"
#include "Flash.h"
#include "uart.h"
#include "string.h"
//数据结构与全局变量定义
extern unsigned char Page_Buf[];
extern unsigned char SONG[];
long int Current_Cluster, DataRead = 0, DataRemain = 0, Sector_Offset = 0x21d;
unsigned int TotalCluster, BootSector, RsdSector, SectorofFatSize, TotalCapacity, RootEntry, SecPerClus, TotalSector, BytesPerSec, FirstDataSec;
unsigned char FAT_TYPE;
void Init_FAT_Info(void)
{
//int i;
///////////////////////////////////////////////////
//得到引导扇区所在扇区号,如果介质是不带分区的,则0扇区就是BootSector了。
ReadPage(Begin_Cluster, 0, Page_Buf);
if (!(Page_Buf[0] == 0xeb && Page_Buf[2] == 0x90))
{ //通过判断EB ?? 90来看是否已经是BPB了
//带分区的介质
BootSector = Page_Buf[454] + Page_Buf[455] * 256 + Page_Buf[456] * (256 * 256) + Page_Buf[457] * (256 * 256 * 256);
}
else
{
BootSector = 0;
}
///////////////////////////////////////////////////
////////////////////////////////////////////////
//得到保留扇区数,总扇区数,总扇区数/每簇扇区数得到簇数,是FAT类型的依据
ReadPage(Begin_Cluster, BootSector, Page_Buf);
RsdSector = Page_Buf[14] + Page_Buf[15] * 256;
SecPerClus = Page_Buf[13];
BytesPerSec = Page_Buf[12] * 256 + Page_Buf[11];
TotalSector = (Page_Buf[20] * 256 + Page_Buf[19]);
TotalCapacity = TotalSector * BytesPerSec;
TotalCluster = TotalSector / SecPerClus;//FAT16的簇总数=扇区总数/每簇扇区数
SectorofFatSize = ((Page_Buf[22] + Page_Buf[23] * 256));
RootEntry = (Page_Buf[18] * 256 + Page_Buf[17]);
FirstDataSec = BootSector + RsdSector + (SectorofFatSize * 2) + ((RootEntry * 32 + (BytesPerSec-1)) / BytesPerSec);
if (TotalCluster > 65525)
{ //FAT32的扇区总数和FAT表项长度
FAT_TYPE = FAT32;
if (TotalSector == 0)
{
TotalSector = (Page_Buf[32] + Page_Buf[33] * 256 + Page_Buf[34] * 256 * 256 + Page_Buf[35] * 256 * 256 * 256);
}
TotalCapacity = TotalSector * BytesPerSec;
TotalCluster = TotalSector / SecPerClus;
SectorofFatSize = (Page_Buf[36] + Page_Buf[37] * 256 + Page_Buf[38] * 256 * 256 + Page_Buf[39] * 256 * 256 * 256);
if (SectorofFatSize > (TotalCluster * 16 / 512))
{
SectorofFatSize = ((Page_Buf[22] + Page_Buf[23] * 256));
}
RootEntry = (Page_Buf[44] * 256 + Page_Buf[43]);
FirstDataSec = BootSector+RsdSector + (SectorofFatSize * 2) + ((RootEntry * 32 + (BytesPerSec-1)) / BytesPerSec);
}
else if ((TotalCluster > 0) && (TotalCluster < 4085))
{//FAT12
FAT_TYPE = FAT12;
}
else
{ //FAT16
FAT_TYPE = FAT16;
}
printuf("\nFAT : %x", SectorofFatSize >> 8);
printuf("%x\n", SectorofFatSize & 0xff);
printuf("\nDATA : %x", FirstDataSec >> 8);
printuf("%x\n", FirstDataSec & 0xff);
}
unsigned char GetMP3List(void)
{
unsigned char i = 0, j = 0, l = 0;
int k = 0;
unsigned char MP3[3] = {'M', 'P', '3'};
Init_FAT_Info();
k = BootSector + RsdSector + 2 * SectorofFatSize;
printuf("BootSector : %x", BootSector);
printuf("RsdSector : %x", RsdSector);
printuf("SectorofFatSize : %x", SectorofFatSize);
printuf("RootDIR : %x", (k & 0xff00) >> 8);
printuf("%x\n", k);
ReadPage(0 + k / 32, k % 32, Page_Buf);
while (Page_Buf[0] != 0)
{//遍历整个目录
for (j=0; j<16; j++)
{
if (!Page_Buf[j * 32]) break;
if (Page_Buf[j * 32] == 0xE5) continue;
if (!memcmp(MP3, &Page_Buf[j * 32 + 8], 3))
{ //file find
for (i=0; i<11; i++)
{
SONG[l * 11 + i] = Page_Buf[j * 32 + i];
}
l++;
}
}
k++;
ReadPage(0 + k / 32, k % 32, Page_Buf);
}
return (l);
}
int ReadSector(unsigned char *Name, unsigned char *databuff)
{
int i, k, Page;
unsigned long CurrentSector;
if (DataRead == 0) //第一次读取,先查找文件,然后进行读取
{
Page = BootSector + RsdSector + 2 * SectorofFatSize;
ReadPage(0 + Page / 32, Page % 32, databuff);
while (databuff[0] != 0)
{//遍历整个目录
for (i=0; i<16; i++)
{
if (!memcmp(Name, &databuff[i * 32], 11))
{
Current_Cluster = databuff[32 * i + 27] * 256 + databuff[32 * i + 26];
printuf("Current_Cluster : %x", (Current_Cluster & 0xff00) >> 8);
printuf("%x\n", Current_Cluster);
for (k=31; k>27; k--)
{
DataRemain = (DataRemain << 8) | databuff[i * 32 + k];
}
//ReadPage((Current_Cluster+Sector_Offset)/32,(Current_Cluster+Sector_Offset)%32,databuff);
CurrentSector = (Current_Cluster - 2) * SecPerClus + FirstDataSec;
ReadPage(CurrentSector / 32, CurrentSector % 32, databuff);
DataRead += 512;
DataRemain -= 512;
if (DataRemain < 0)
{
DataRead = 0;
return (DataRemain + 512);
}
else
{
return (512);
}
}
}
Page++;
ReadPage(0 + Page / 32, Page % 32, databuff);
}
printu("\nfile is not found!");
return (0);
}
else
{
// if((Current_Cluster+Sector_Offset+DataRead/BytesPerSec)%32) Current_Cluster=NextCluster(Current_Cluster);
// ReadPage((Current_Cluster+Sector_Offset)/32,(Current_Cluster+Sector_Offset+DataRead/BytesPerSec)%32,databuff);
Current_Cluster++;
CurrentSector = (Current_Cluster - 2) * SecPerClus + FirstDataSec;
ReadPage(CurrentSector / 32, CurrentSector % 32, databuff);
DataRead += 512;
// if(!((Current_Cluster+Sector_Offset+DataRead/BytesPerSec)%32)) Current_Cluster=NextCluster(Current_Cluster+32);
// if(!((Current_Cluster+Sector_Offset+DataRead/BytesPerSec)%32)) Current_Cluster+=32;//默认歌曲文件是顺序存放的。
DataRemain -= 512;
if (DataRemain < 0)
{
DataRead = 0;
return (DataRemain + 512);
}
else return (512);
}
}
unsigned int NextCluster(unsigned int CurrentCluster)
{
unsigned int i, j;
if (FAT_TYPE == FAT12)
{
ReadPage(Begin_Cluster + (BootSector + RsdSector + (CurrentCluster * 3 / 2) / BytesPerSec) / SecPerClus,
(BootSector + RsdSector + (CurrentCluster * 3 / 2) / BytesPerSec) % SecPerClus, Page_Buf);
if (CurrentCluster % 2 == 0)
{
j = Page_Buf[(CurrentCluster * 3 / 2) % BytesPerSec + 1];
i = Page_Buf[(CurrentCluster * 3 / 2) % BytesPerSec] | (j << 8);
i &= 0x0fff;
}
else
{
j = Page_Buf[(CurrentCluster * 3 / 2) % BytesPerSec + 1];
i = Page_Buf[(CurrentCluster * 3 / 2) % BytesPerSec] | (j << 8);
i = (i >> 4);
}
return (i);
}
else if (FAT_TYPE == FAT16)
{
ReadPage(Begin_Cluster + (BootSector+RsdSector + (CurrentCluster * 2) / BytesPerSec) / 32,
(BootSector + RsdSector + (CurrentCluster * 2) / BytesPerSec) % 32, Page_Buf);
i = Page_Buf[(CurrentCluster * 2) % BytesPerSec + 1] * 256 + Page_Buf[(CurrentCluster * 2) % BytesPerSec];
return (i);
}
else if (FAT_TYPE == FAT32)
{
ReadPage(Begin_Cluster + (BootSector+RsdSector + (CurrentCluster * 4) / BytesPerSec) / SecPerClus, (BootSector + RsdSector + (CurrentCluster * 4) / BytesPerSec) % SecPerClus, Page_Buf);
i = Page_Buf[(CurrentCluster * 4) % BytesPerSec + 3] * 256 * 256 * 256 + Page_Buf[(CurrentCluster * 4) % BytesPerSec + 2]
* 256 * 256 + Page_Buf[(CurrentCluster * 4) % BytesPerSec + 1] * 256 + Page_Buf[(CurrentCluster * 4) % BytesPerSec];
return (i);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -