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

📄 fat32.h

📁 在基于avr内核的单片机上实现MP3播放器的功能
💻 H
字号:
#define file_delete        0xE5 
//#define BPB_org_secid     0  
#define dir_org_clusId     2 
#define endclus_valu     0x0fffffff
#define docum          0x20
//=============================

//you can not use little a,b you must use AB,or they consider it  use the same name
uint8  sd_buf[512] ; 
uint16 BPB_BytesPerSec=512;
uint8  BPB_SecPerClus;//4
   

uint32 BPB_FAT_sec_size;

uint32 FAT1_org_secid;
uint32 FAT2_org_secid;
volatile uint32 DirStartSecid=1984;
uint32 BPB_org_secid=0;     
//========================


//=======
typedef struct
{
	uint8  BS_jmpBoot[3];
	uint8  BS_OEMName[8];//	
	uint16 BPB_BytesPerSec;
	uint8  BPB_SecPerClus;//
    uint16 BPB_RsvdSecCnt;//38
	uint8  BPB_NumFATs;//	
	uint16 BPB_4null;
	uint16 BPB_5null;//	
	uint8  BPB_Media;
	uint16 BPB_3null;//	
	uint16 BPB_SecPerTrk;
	uint16 BPB_NumHeads;//	
	uint32 BPB_HiddSec;
	uint32 BPB_TotSec32;//	
	uint32 BPB_FAT_sec_size;
	uint16 BS_null;//	
	uint16 BPB_FATversion;
	uint32 BPB_org_clus;//	
	uint16 BS_FilSysinfor;
	uint16 BS_bootbk;//	
	uint8  BS_resnull[12];
	uint8  BS_drivnum;//	
	uint8  BS_2null;
	uint8  BS_Extendid;//	
	uint8  BS_serial_num[4];
	uint8  BS_partion_name[11];//	
	uint8  BS_FAT_name[8];//	
	uint8  ExecutableCode[420];
	uint8  ExecutableMarker[2];
} FAT_BPB;

typedef struct
{
	uint8 NAME[8];
	uint8 TYPE[3];
} FILE_NAME;

typedef struct
{
	FILE_NAME FileName;
	uint8 FileAttrib;
	uint8 Creat_time[8];
	uint16 File_Start_H;
	uint16 FileUpdateData[2];
	uint16 File_Start_L;
	uint32 Size;
} DIR;
typedef struct
{
	uint32 ClusID;
	uint8 SecOfClus;
	uint16 ByteOfSec;
	uint8  state;
} DATA_POSIT;

typedef struct
{   FILE_NAME   name;
	DATA_POSIT  dir_posit;//dir infor for change size
	DATA_POSIT  dat_posit;//data  infor for data
	uint32      size ;
	uint32      file_org_clusid;
    uint32      file_last_clusid;
	uint8       state;
} FILE_HANDLE;

typedef struct
{   uint8       LDIR_Ord;
	uint16      LDIR_Name1[5];//dir infor for change size
	uint8       LDIR_Atrr;//data  infor for data
	uint8       LDIR_Type;
	uint8       LDIR_Chksum;
    uint8       LDIR_Name2[6];
	uint16      LDIR_FstClus;
	uint8       LDIR_Name3[2];
}    LDIR;

//===========================api
DATA_POSIT Is_Same_File_there(FILE_NAME * file_name_ty,uint32 clusid);

DATA_POSIT GetEmptyDIR(uint32 clusid);

FILE_NAME unicode_Filename(uint8 * name_str);

uint8 CreateFile(uint8* FileName_str,uint32 clusid);

FILE_HANDLE OpenFile(uint8* FileName_str,uint32 clusid);

uint8  WriteFile(FILE_HANDLE * file_inforhd,uint8 * dat_str,uint16 size);

uint32 POSIT2LBA(DATA_POSIT *posit);

void CopyBytes(void* S, void* D, uint32 size);
//============================
//********************************************************************************************
//读一个扇区
uint8 ReadBlock(uint32 LBA)
//********************************************************************************************
{
return	SD_Read_Single_Block(LBA,sd_buf);
}

//********************************************************************************************
//写一个扇区
uint8 WriteBlock(uint32 LBA)
//********************************************************************************************
{
return SD_Write_Single_Block(LBA,sd_buf);
}

//*****************************************
#define uart_dubeg_ReadBPB 0
//********************************************************************************************
//读取BPB数据结构
uint8  ReadBPB(void)
//********************************************************************************************
{   uint16 retry=0;
	FAT_BPB* BPB = (FAT_BPB*)sd_buf; //1
	uint8 MSDOS[5]={'M','S','D','O','S'};
     
uint32 BPB_HiddSec;	 
uint16 BPB_RsvdSecCnt;
uint8  BPB_NumofFATs; 
uint32 BPB_TotSec32;
	/* 	CopyBytes("this is aim to find bpb",&sd_buf[0],128);
	WriteBlock(500);*/
	retry=0;
	BPB_org_secid=0;
	
	while(retry++<8)
	{ReadBlock(BPB_org_secid); 
	if(IsEqual(&BPB->BS_OEMName, &MSDOS[0], 5)==error)
	{BPB_org_secid+=8;}
	else break;
	}
    
	   		/*	 ReadBlock(32);
			      diruart[0]=0xaa;
				  diruart[1]=0xaa;
				 
		     CopyBytes((uint8 *)&(retry),&diruart[2],2);
			 uart_send2(&diruart[0],4);	
	
	                          CopyBytes(&sd_buf[0],&diruart[0],128);//FB FC 00 00
			 uart_send2(&diruart[0],128);
			 			     CopyBytes(&sd_buf[128],&diruart[0],128);//FB FC 00 00
			 uart_send2(&diruart[0],128);
			 			     CopyBytes(&sd_buf[256],&diruart[0],128);//FB FC 00 00
			 uart_send2(&diruart[0],128);
			 			     CopyBytes(&sd_buf[384],&diruart[0],128);//FB FC 00 00
			 uart_send2(&diruart[0],128);*/

	//PutString(1,1,"next sec",0xF800,0xFFE0);
    //display_add_string_s(0,0,sd_buf,12);
	//获取参数
	BPB_BytesPerSec = BPB->BPB_BytesPerSec;//3   //每扇区的字节数
	BPB_SecPerClus = BPB->BPB_SecPerClus;   //每个簇的扇区数
	BPB_RsvdSecCnt = BPB->BPB_RsvdSecCnt;  //保留扇区数
	BPB_NumofFATs=BPB->BPB_NumFATs;         // fats个数  ==2 
	
	BPB_TotSec32 = BPB->BPB_TotSec32;   //总扇区数
	BPB_FAT_sec_size = BPB->BPB_FAT_sec_size; //fat占用的扇区数
	BPB_HiddSec = BPB->BPB_HiddSec;  //  隐藏扇区数
	//===
    FAT1_org_secid=BPB_org_secid+BPB_RsvdSecCnt;           //算出fat1_org_secid   32+38=70
	FAT2_org_secid=BPB_org_secid+BPB_RsvdSecCnt+BPB_FAT_sec_size;//算出fat2_org_secid  =1043
    DirStartSecid=BPB_org_secid+BPB_RsvdSecCnt + BPB_FAT_sec_size * BPB_NumofFATs;//32+38+973*2=2016
				    
		#if 	uart_dubeg_ReadBPB==1		
			 diruart[0]=0xff;
		     CopyBytes((uint8 *)&(DirStartSecid),&diruart[1],4);
			 uart_send2(&diruart[0],5);	
  	
		#endif			
         //CopyBytes("this is a test",&sd_buf[0],14);//FB FC 00 00
			//WriteBlock(2024);
			//WriteBlock(2026);
			return ok;
}
//==============

/*=====================================
获取根目录开始扇区号
uint32 DirStartSec(void)
{
	return BPB_org_secid+BPB_RsvdSecCnt + BPB_FAT_sec_size * BPB_NumofFATs;//32+38+973*2=2016
}

=====================================*/

//*******************************************************************************
//获取一个簇的开始扇区
uint32 Clus2LBA(uint32 ClusID)
//****************************************************************
{
	return (DirStartSecid + BPB_SecPerClus * (ClusID - 2));
}

//**************************************************************
uint32 POSIT2LBA(DATA_POSIT *posit)
{
return (Clus2LBA(posit->ClusID)+posit->SecOfClus);
}
//===========================================

void EmptyBytes(void* D, uint32 size)
//********************************************************************************************
{
	uint32 i;
	uint8* data = (uint8*)D;
	for(i = 0; i < size; i++)
	{
		*data++ = 0;
	}
}

//******************************************************************
//********************************************************************************************
uint8 IsEqual(void* A, void* B, uint8 Size)
//********************************************************************************************
{
	uint8 i, *a = A, *b = B;
	for(i = 0; i < Size; i++)
		if(a[i] != b[i])
			return error;
	return ok;
}
//***********************************************************
void CopyBytes(void* S, void* D, uint32 size)
//********************************************************************************************
{
	uint8 *s = S, *d = D;
	uint32 i;
	for(i = 0; i < size; i++)
		*d++ = *s++;
}

//*******************************************
/*
功    能:   写文件分配表的指定簇号的属性
说    明:   用于对fat簇链进行修改  
代入参数:  要修改属性的簇号,写入其属性值,要么是下一个簇链或该链终止endclus_valu
返 回 值:   无 
示    范:   WriteFAT(4, 5) 用了4号簇下一个5
*///=============================================================
void WriteFAT(uint32 clusid, uint32 Value)
//********************************************************************************************
{
	uint32 *RAM = (uint32*)sd_buf;
	uint32 SecID;  
	SecID = FAT1_org_secid + clusid / 128;
	ReadBlock(SecID);
	RAM[clusid % 128] = Value;
		WriteBlock(SecID);    //write fat1
	SecID = FAT2_org_secid + clusid / 128;
	    WriteBlock(SecID);    //write fat2
}

/*==================================================

功    能:   在根目录的指定地址上写入一个目录
说    明:   用于对目录进行修改  
代入参数:  要写入的字节地址, 是一个DATA_POSIT ;目录数据  
返 回 值:   无 
示    范:   WriteFAT(data_posit, new_dir) 
==============================================*/
void WriteDIR(DATA_POSIT data_Index, DIR* dir_dat)
//********************************************************************************************
{
	uint32 LBA =Clus2LBA(data_Index.ClusID)+data_Index.SecOfClus;	
	ReadBlock(LBA);
	CopyBytes(dir_dat, &sd_buf[data_Index.ByteOfSec], 32);		
	WriteBlock(LBA);
}

/*==========================================
功    能:读取文件分配表的指定簇号对应的fat内容
代入参数:簇号
返 回 值: 其簇号对应的fat内容
示    范:   ReadFAT(4)  read the  value of clus 
*///**********************************************
uint32 ReadFAT(uint32 clusid)
{
	uint32 *RAM = (uint32*)sd_buf;//init piont address
	ReadBlock(FAT1_org_secid + clusid /128);
	return RAM[clusid % 128];
}
//==============================================
/*==========================================
功    能:清空一个簇的内容 write 0 to all of clus
代入参数:簇号
返 回 值: no
示    范:   clr_this_clus(4)  clr the  value of clus 
*******************************************/
void clr_this_clus(uint32 clusid)//簇号
{
uint8 i;
for(i = 0; i < BPB_SecPerClus; i++)
	{
	EmptyBytes(sd_buf,512);
	WriteBlock(Clus2LBA(clusid)+i);//清空一个簇
	
	}

}


/*==========================================
功    能:获取一个空的FAT项,只要有空间就可以获得
代入参数:no
返 回 值: 空白簇号
示    范:   ReadFAT(4)  read the  value of clus 
*****************************************/
uint32 Get_blank_FATid(void)
//********************************************************************************************
{   uint16 j;
	uint32 i;
	uint32 *RAM = (uint32*)sd_buf;
	
	for(i = 0; i < BPB_FAT_sec_size; i++)//FAT表总clus项数
	{  ReadBlock(FAT1_org_secid + i);
	    for(j=0;j<128;j++)
		if(RAM[j] == 0)
			return i*128+j;
	}
	return error;
}

/*==========================================
功    能:获取根目录中可以使用的一项的data_posit地址 ; 可以向目录中
         加入新的簇链,,这样只要有磁盘空间就总可以找到目录
代入参数

⌨️ 快捷键说明

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