⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 mp3代码 要用的干净下啊 希望用东西共享啊
💻 C
字号:


#include "config.h"


uint8 FAT_ReadBlock(uint32 LBA);
uint8 FAT_WriteBlock(uint32 LBA);
uint8 IsEqual(void* A, void* B, uint8 Size);
void ReadBPB(void);
uint32 ClusConvLBA(uint16 ClusID);
uint16 FAT_ReadFAT(uint16 Index);
uint8 GetFileID(uint8 Name[11], DIR* ID);



static uint8    BUFFER[512];
static FileSystemInfo  Info;
static FATFileIndex     FileIndex;
//******************************************************************************************** 
//初始化驱动,建立必要数据结构 
//void FAT_Init(void); 
//******************************************************************************************** 
void FAT_Init(void) {
        ReadBPB();
}

//********************************************************************************************  
//读一个扇区  
//******************************************************************************************** 
uint8 FAT_ReadBlock(uint32 LBA) {
        return(MMC_Read_Sector(LBA , BUFFER));
}
//********************************************************************************************  
//写一个扇区  
//********************************************************************************************  

uint8 FAT_WriteBlock(uint32 LBA) 
{
        return(MMC_Write_Sector(LBA, BUFFER));
}

uint8 IsEqual(void* A, void* B, uint8 Size) 
{
        uint8 i, *a = A, *b = B;
        for(i = 0; i < Size; i++)
                if(*a++!= *b++)
                        return FALSE;
        return TRUE;
}
//********************************************************************************************  
//读取BPB数据结构  
//static void ReadBPB(void)  
//********************************************************************************************  

void ReadBPB(void) 
{
        FAT_BPB* BPB = (FAT_BPB*)BUFFER;
        FAT_ReadBlock(0);

        //缓存相关参数
        Info.BPB_SecPerClus     =   BPB->BPB_SecPerClus;
        Info.BPB_RsvdSecCnt     =   BPB->BPB_RsvdSecCnt;
        Info.BPB_NumFATs        =   BPB->BPB_NumFATs;
        Info.BPB_RootEntCnt     =   BPB->BPB_RootEntCnt;
        Info.BPB_TotSec16       =   BPB->BPB_TotSec16;
        Info.BPB_FATSz16        =   BPB->BPB_FATSz16;
        Info.BPB_HiddSec        =   BPB->BPB_HiddSec;

    Info.DirStartSec        =   Info.BPB_RsvdSecCnt + Info.BPB_NumFATs * Info.BPB_FATSz16;  //获取根目录开始扇区号  
    Info.DataStartSec       =   Info.DirStartSec + Info.BPB_RootEntCnt * 32 / 512;          //获取数据区开始扇区号  
    Info.DirSecCount        =   Info.BPB_RootEntCnt * 32 / 512;    	   	 	  				//目录项占用的扇区数  
}
//********************************************************************************************  
//获取一个簇的开始扇区  
//********************************************************************************************  

uint32 ClusConvLBA(uint16 ClusID) 
{
        return Info.DataStartSec + Info.BPB_SecPerClus * (ClusID - 2);
}
//********************************************************************************************  
//读取文件分配表的指定项  
//********************************************************************************************  
uint16 FAT_ReadFAT(uint16 Index) 
{
        uint16 *RAM = (uint16*)BUFFER;
        FAT_ReadBlock(Info.BPB_RsvdSecCnt + Index / 256);
        return RAM[Index % 256];
}
//********************************************************************************************  
//获得和文件名对应的目录项  
//********************************************************************************************  
uint8 GetFileID(uint8 * Name, DIR* ID) 
{
        uint16 DirSecCut, DirStart, i, m;
        DirSecCut = Info.DirSecCount;           //目录占扇区总数
        DirStart = Info.DirStartSec;            //目录开始扇区
        for(i = 0; i < DirSecCut; i++) 
		{
                if(!FAT_ReadBlock(DirStart + i))
				{
				        break;
				}
                for(m = 0; m <16; m++) 
				{
                      //  if(IsEqual(Name, &((DIR*)&BUFFER[m * 32])->FileName, 11)) 
						if(IsEqual(Name, &BUFFER[m * 32], 11)) 
						{
                                *ID = *((DIR*)&BUFFER[m * 32]);
                                return TRUE; 
                        }
                }
        }
        return FALSE;
}
//********************************************************************************************  
//打开指定文件  
//********************************************************************************************  
uint32 FAT_FileOpen(uint8 * Name, uint32 Start) 
{
        uint16 BytePerClus, ClusNum;
        DIR FileDir;
        BytePerClus = Info.BPB_SecPerClus * 512; // 每簇的字节数
        if (!GetFileID(Name, &FileDir))
		    {
			return FALSE;
			}

        //计算开始位置所在簇的簇号
        ClusNum = Start / BytePerClus;
        FileIndex.ClusID = FileDir.Start;
        for(FileIndex.i = 0; FileIndex.i < ClusNum; FileIndex.i++)
                FileIndex.ClusID = FAT_ReadFAT(FileIndex.ClusID);


        FileIndex.i = (Start % BytePerClus) / 512; //开始位置所在扇区簇内偏移
        FileIndex.m = (Start % BytePerClus) % 512; //开始位置扇区内偏移

        FileIndex.LBA = ClusConvLBA(FileIndex.ClusID) + FileIndex.i; //开始位置所在的扇区号
        FAT_ReadBlock(FileIndex.LBA); //预读取一个扇区的内容
		return (FileDir.Size);
}
//********************************************************************************************  
//读取文件的数据  
//********************************************************************************************  
uint16 FAT_FileRead(uint32 Length, void* Data) 
{
        uint8 *data = Data;
        goto FAT_FileRead_Start;

        while(1) 
		{
                FileIndex.ClusID = FAT_ReadFAT(FileIndex.ClusID); //下一簇簇号
				if (FileIndex.ClusID==0xFFFF)
				       {
					    return FALSE;                                 //文件结束
						}
                FileIndex.LBA = ClusConvLBA(FileIndex.ClusID);  //簇的开始扇区号
                FileIndex.i = 0;                                //簇内扇区偏移
                while(FileIndex.i < Info.BPB_SecPerClus) 
				{
                        FAT_ReadBlock(FileIndex.LBA);           //读当前簇
                        FileIndex.m = 0;                        //当前扇区内的数据偏移
FAT_FileRead_Start:
                        while(FileIndex.m < 512) 
						{
                                *data++ = BUFFER[FileIndex.m];  
                                FileIndex.m++;
                                //如果读取完成就退出
                                if(--Length == 0)
								        {
										return (FileIndex.m);
										}
                        }
                        FileIndex.LBA++;                         //下一扇区号
                        FileIndex.i++;
                }
        }
return FALSE;
}
//********************************************************************************************  
//写文件的数据  
//********************************************************************************************  
void FAT_FileWrite(uint32 Length, void* Data) {
        uint8 *data = Data;

        goto FAT_FileWrite_Start;

        while(1) {
                FileIndex.ClusID = FAT_ReadFAT(FileIndex.ClusID); //下一簇簇号
                FileIndex.LBA = ClusConvLBA(FileIndex.ClusID);
                FileIndex.i = 0;
                while(FileIndex.i < Info.BPB_SecPerClus) {
                        FAT_ReadBlock(FileIndex.LBA);
                        FileIndex.m = 0;
FAT_FileWrite_Start:                    
                        while(FileIndex.m < 512) {
                                BUFFER[FileIndex.m] = *data++;
                                FileIndex.m++;
                                //如果读取完成就退出
                                if(--Length == 0) {
                                        FAT_WriteBlock(FileIndex.LBA); //回写扇区
                                        return;
                                }
                        }
                        FAT_WriteBlock(FileIndex.LBA++); //回写扇区,指针下移
                        FileIndex.i++;
                }
        }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -