?? fat.c
字號:
#include"FAT.h"
//FAT部分代碼
//正點原子@SCUT
//全局變量區域
DWORD FirstDirClust; //根目錄簇號
DWORD FirstDataSector; //數據區的第一個扇區
WORD BytesPerSector; //每扇區字節數
DWORD FATsectors; //FAT表所占扇區數
WORD SectorsPerClust; //每簇扇區數
DWORD FirstFATSector; //第一個FAT表(FAT1)所在扇區
DWORD FirstDirSector; //第一個目錄扇區 fat32
DWORD RootDirSectors; //根目錄所在扇區
DWORD RootDirCount; //根目錄下目錄項數
BYTE FAT32_Enable; //FAT32文件系統標志
u32 sys_ico[9]; //系統圖標緩存區!不能篡改!
u32 file_ico[4]; //文件圖標緩存區 folder;mus;pic;book;
const unsigned char *folder[7]=
{
"SYSTEM ",
"FONT ",
"SYSICO ",
"GAME ",
"LEVEL1 ",
"LEVEL2 ",
"LEVEL3 ",
};
//系統文件定義
const unsigned char *sysfile[15]=
{
"FONT16 FON",
"FONT12 FON",
//系統主界面圖標
"MUSIC BMP",
"PICTURE BMP",
"GAME BMP",
"ALARM BMP",
"TIME BMP",
"SETTING BMP",
"TXT BMP",
"RADIO BMP",
"LIGHT BMP",
//系統文件圖標 12開始
"FOLDER BMP",
"MUS BMP",
"PIC BMP",
"BOOK BMP",
};
//文件信息緩存區
FileInfoStruct F_Info[8];
//外部全局變量
//FAT 數據緩存區,不能和jpg_buffer共用.否則在FAT32文件系統里面,可能出錯!!
u8 fat_buffer[512];
u8 LongNameBuffer[MAX_LONG_NAME_SIZE];//長文件名的緩存區
BOOL LongNameFlag = 0;//是否存在長文件名的標志
//顯示一次數據流
void show_data(u8 *p,u16 num)
{
u16 i=0;
printf("TEMP DATA:\n");
delay_ms(1000);
for(i=0;i<num;i++)printf(" %x",*p++);
printf("\ndata over\n");
}
//FAT初始化,不含SD的初始化,用之前應先調用sd的初始化
unsigned char FAT_Init(void)//Initialize of FAT need initialize SD first
{
bootsector710 *bs = 0;
bpb710 *bpb = 0;
partrecord *pr = 0;
DWORD hidsec=0;
DWORD Capacity;
Capacity = SD_GetCapacity();
if(Capacity<0xff)return 1;
if(SD_ReadSingleBlock(0,fat_buffer))return 1;
bs = (bootsector710 *)fat_buffer;
pr = (partrecord *)((partsector *)fat_buffer)->psPart;//first partition
hidsec = pr->prStartLBA;//the hidden sectors
if(hidsec >= Capacity/512)hidsec = 0;
else
{
if(SD_ReadSingleBlock(pr->prStartLBA,fat_buffer))return 1;//read the bpb sector
bs = (bootsector710 *)fat_buffer;
if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)
{
hidsec = 0;
if(SD_ReadSingleBlock(0,fat_buffer))return 1;//read the bpb sector
bs = (bootsector710 *)fat_buffer;
}
}
if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)return 1;//對付沒有bootsect的sd卡 //dead with the card which has no bootsect
bpb = (bpb710 *)bs->bsBPB;
if(bpb->bpbFATsecs)//detemine thd FAT type //do not support FAT12
{
FAT32_Enable=0; //FAT16
FATsectors = bpb->bpbFATsecs;//FAT表占用的扇區數
FirstDirClust = 2;
}
else
{
FAT32_Enable=1; //FAT32
FATsectors = bpb->bpbBigFATsecs;//FAT占用的扇區數 //the sectors number occupied by one fat talbe
FirstDirClust = bpb->bpbRootClust;
}
BytesPerSector = bpb->bpbBytesPerSec; //每扇區字節數
SectorsPerClust = (BYTE)bpb->bpbSecPerClust;//每簇扇區數
FirstFATSector = bpb->bpbResSectors+hidsec;//第一個FAT表扇區
RootDirCount = bpb->bpbRootDirEnts; //根目錄項數
RootDirSectors = (RootDirCount*32)>>9; //根目錄占用的扇區數
FirstDirSector = FirstFATSector+bpb->bpbFATs*FATsectors;//第一個目錄扇區
FirstDataSector = FirstDirSector+RootDirSectors;//第一個數據扇區
return 0;
}
//讀下一簇簇號
//Return the cluster number of next cluster of file
//Suitable for system which has limited RAM
unsigned long FAT_NextCluster(unsigned long cluster)
{
DWORD sector;
DWORD offset;
if(FAT32_Enable)offset = cluster/128;//FAT32的FAT表中,用四個字節表示一個粗地址.512/4=128
else offset = cluster/256; //FAT16的FAT表中,用兩個字節表示一個粗地址.512/2=256
if(cluster<2)return 0x0ffffff8; //簇0,1不能用于存放
sector=FirstFATSector+offset;//計算實際扇區數
if(SD_ReadSingleBlock(sector,fat_buffer))return 0x0ffffff8;//讀取FAT表,發生錯誤是返回0x0ffffff8
if(FAT32_Enable)
{
offset=cluster%128;//查找位置
sector=((unsigned long *)fat_buffer)[offset];
}
else
{
offset=cluster%256;//查找位置
sector=((unsigned short *)fat_buffer)[offset];
}
return (unsigned long)sector;//return the cluste number
}
//讀下一簇簇號
//cluster:當前簇號
//startcluster:文件開始的簇號
//返回值:cluster前一個簇的簇號
//返回0xfffffff8則錯誤!
unsigned long FAT_PrevCluster(unsigned long cluster,unsigned long startcluster)
{
DWORD temp;
DWORD tempcluster;
tempcluster=startcluster;//從起始簇號開始查找
if(cluster==startcluster)return 0x0ffffff8;//查找錯誤
while(1)
{
temp=FAT_NextCluster(tempcluster); //查找當前簇的下一簇
if(temp==cluster)return tempcluster;//下一簇就等于最終簇,返回前一簇,就是最終簇的上一簇
else tempcluster=temp; //繼續下一簇查找
if(temp==0x0ffffff8)return 0x0ffffff8;//查找錯誤
}
}
//將簇號轉變為扇區號
u32 fatClustToSect(u32 cluster)
{
return FirstDataSector+(DWORD)(cluster-2)*(DWORD)SectorsPerClust;
}
//文件類型
//返回值:對應的類型 0,mp3;1,wma;2,wav,3,mid;4,lrc;5,txt;6,c;7,h;8,jpg;9,jpeg;10,bmp;11,file;12,FON;
const unsigned char *filetype[13]={"MP3","WMA","WAV","MID","LRC","TXT","C ","H ","JPG","JPE","BMP"," ","FON"};
//返回擴展名類型
//輸入:exName 文件擴展名
u16 FileType_Tell(u8 * exName)
{
u8 i;
u8 t;
for(i=0;i<13;i++)
{
for(t=0;t<3;t++)if(exName[t]!=filetype[i][t])break;
if(t==3)break;
}
return 1<<i;//返回文件類型
}
//復制記錄項信息
void CopyDirentruyItem(FileInfoStruct *Desti,direntry *Source)
{
BYTE i;
for(i=0;i<8;i++)Desti->F_ShortName[i]=Source->deName[i];//復制短文件名
Desti->F_Type = FileType_Tell(Source->deExtension);
Desti->F_StartCluster = Source->deStartCluster + (((unsigned long)Source->deHighClust)<<16);//不用管
Desti->F_Size = Source->deFileSize;
Desti->F_Attr = Source->deAttributes;
Desti->F_CurClust = 0;//扇區...
Desti->F_Offset = 0;//偏移0
//FAT的簇號不能是0(更目錄簇號)
if(FAT32_Enable&&Desti->F_StartCluster==0)
{
Desti->F_StartCluster=FirstDirClust;//改變這個簇號.使其等于根目錄所在簇號!!
}
if(LongNameFlag)//存在長文件名
{
LongNameBuffer[MAX_LONG_NAME_SIZE-1] = 0;
LongNameBuffer[MAX_LONG_NAME_SIZE-2] = 0;
UniToGB(LongNameBuffer); //把Unicode代碼轉換為ASICII碼
for(i=0;i<80;i++)Desti->F_Name[i] = LongNameBuffer[i];//復制長文件名
}else //短文件名
{
if(Source->deName[0]==0x2e)//得到一個父目錄(修改為:":\")
{
//保存父目錄簇號
Fat_Dir_Cluster=Desti->F_StartCluster;
Desti->F_Name[0]=':';
Desti->F_Name[1]=0x5c;//'\'
Desti->F_Name[2]='\0';//加入結束符
}else //普通文件
{
for(i=0;i<11;i++)Desti->F_Name[i] = Source->deName[i];//復制短文件名
Desti->F_Name[11]='\0';//加入結束符
}
}
return ;
}
//瀏覽目標文件夾下面的一個文件類
//dir_clust:當前目錄所在簇號
//FileInfo :目標文件的實體對象(FileInfoStruct體)
//type :要查找的文件類型:1<<0,mp3;1<<1,wma;1<<2,wav,1<<3,mid;1<<4,1<<lrc;
// 1<<5,txt;1<<6,jpg;1<<7,jpeg;1<<8,bmp;1<<9,file;
//count :0,返回當前目錄下,該類型文件的個數;不為零時,返回第count個文件的詳細信息
//返回值 :1,操作成功.0,操作失敗
u8 Get_File_Info(u32 dir_clust,FileInfoStruct *FileInfo,u16 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 1;//讀數錯誤
//SD: for(offset=0;offset<512;offset++)fat_buffer[offset]=temp_buf[offset];
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;//清空長文件名
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -