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

📄 fat._c

📁 AVR单片机系统开发经典实例部分源程序
💻 _C
字号:

//---------------------------- 文件系统程序 -----------------------------
//
//文件系统:兼容性强FAT32
//代码作者:林永彬
//时间:2009.7.8
//
//------------------------------------------------------------------------
#include"fat.h"
#include "Usart.h"
uint32 FAT_MASK;
uint8   Fat_Buffer[512]; 
uint32 NumOfFile;  //文件的数量


//DISK_FAT_INFO结构,用来存储SD卡的信息
struct DISK_FAT_INFO DiskFATInfo;

//MUSIC_INFO结构,用来存储音乐的信息,MusicInfoList用来存放音乐列表,这里限制100首
struct MUSIC_INFO MusicInfoList[3];

//******************************************************************************
//初始化FAT,将SD卡信息,存到DiskFATInfo结构
uint8 Fat_Init(void)
{
  SD_ReadBlock(0,Fat_Buffer);
  if(Fat_Buffer[0] != 0xEB)
  {
   	DiskFATInfo.DBR_LBA = (Fat_Buffer[454]|(Fat_Buffer[455]<<8)|((uint32)Fat_Buffer[456]<<16)|((uint32)Fat_Buffer[457]<<24));
	switch(Fat_Buffer[0x1C2])
	{
	    case 0x0B:
			 DiskFATInfo.FAT_Style = 32;
			 FAT_MASK = FAT32_MASK;
			 break;
		case 0x04:
			 DiskFATInfo.FAT_Style = 16;
			 FAT_MASK = FAT16_MASK;
			 break;
	}
  }
  else 
  {
   DiskFATInfo.DBR_LBA = 0;
   switch(Fat_Buffer[0x55])
   {
   	    case 0x33:
	   		 DiskFATInfo.FAT_Style = 32;
			 FAT_MASK = FAT32_MASK;
			 break;
		case 0x31:
			 DiskFATInfo.FAT_Style = 16;
			 FAT_MASK = FAT16_MASK;
			 break;
	        
   }
  }
  SD_ReadBlock(DiskFATInfo.DBR_LBA,Fat_Buffer);  
  DiskFATInfo.BytesPerSector = Fat_Buffer[0x0B] |(Fat_Buffer[0x0C] << 8);
  DiskFATInfo.SectorsPerClustor = Fat_Buffer[0x0D];
  

  DiskFATInfo.NumOfFATs = Fat_Buffer[0x10] |(Fat_Buffer[0x11] << 8);

  
  DiskFATInfo.SectorsPerFAT = Fat_Buffer[0x24] |Fat_Buffer[0x25] << 8|(uint32)Fat_Buffer[0x26]<<16|(uint32)Fat_Buffer[0x27]<<24;

  
  DiskFATInfo.FAT_LBA = DiskFATInfo.DBR_LBA + (Fat_Buffer[0x0E]|Fat_Buffer[0x0F]<<8);

  DiskFATInfo.FDT_LBA = DiskFATInfo.FAT_LBA + DiskFATInfo.SectorsPerFAT*DiskFATInfo.NumOfFATs;
 

  
  DiskFATInfo.FDT_StartClustor = Fat_Buffer[0x2C] |Fat_Buffer[0x2D] << 8|(uint32)Fat_Buffer[0x2E]<<16|(uint32)Fat_Buffer[0x2F]<<24;

  return 1;
}

//****************************************************************************
//文件扩展名匹配,匹配成功返回真
uint8 FileExt_Compare(uint8 *strExt1,uint8 *strExt2)
{
    uint8 i;
	
    for(i=0; i<3; i++)
    {
        if(strExt1[i]!= strExt2[i]) break;
    }
    if(i == 3)    return 1; 
	    
	return 0; 
}	

//****************************************************************************
//获取音乐文件
void GetMusicFile(void)
{
  uint16  i,j,k;
  uint32  tem;	//记录目录起始位置
  uint32  Index_tmp=1;  //记录目录编号,不从0开始,因为第0项是系统占用的
  uint32  LocalOfFirstLFN;
  uint32 n;
  uint16  LocalOfMusic=0;  //音乐文件的编号
  uint8   FileExt[3]; 

	
  while(1)
  {
    n = DiskFATInfo.FDT_LBA+(Index_tmp/(DiskFATInfo.BytesPerSector/32));

    //读取FDT的相应扇区位置的内容
    SD_ReadBlock(n,Fat_Buffer);
	
	tem=((Index_tmp)*32)%DiskFATInfo.BytesPerSector;      //获取相应的目录
		
	if(Fat_Buffer[tem] == 0)              //后面没有文件了,文件查询完毕
	{
	    Index_tmp = 0;
		break;
	}
	
	if((Fat_Buffer[tem] != 0xe5) && (Fat_Buffer[tem] != 0x05))			   //文件没有删除   
    {
		if(Fat_Buffer[tem+11]!= 0x0F)              //文件不为长文件名的一部分
		{
		 	for(i=0;i<3;i++)                   //读取该文件的扩展名
			{
			  FileExt[i] = Fat_Buffer[tem+8+i];   
			  
		    }
			    
			if(FileExt_Compare(FileExt,"MP3"))   //如果该文件是MP3
			{
			  for(i=0;;i++)          //将文件名赋值给音乐列表的文件名项
    	 	  {
			     if(Fat_Buffer[tem+i] == 0x20 || i>=8)
				 {
				   MusicInfoList[LocalOfMusic].FileName[i] = '.';
				   MusicInfoList[LocalOfMusic].FileName[i+1] = 'm';
				   MusicInfoList[LocalOfMusic].FileName[i+2] = 'p';
				   MusicInfoList[LocalOfMusic].FileName[i+3] = '3';
				   break;
				 }
			     MusicInfoList[LocalOfMusic].FileName[i]=Fat_Buffer[tem+i];
			  }
			  //将文件的起始簇号赋值给音乐列表的起始簇号项
			  MusicInfoList[LocalOfMusic].FileStartClustor = Fat_Buffer[tem+0x1A]|Fat_Buffer[tem+0x1B]<<8|((uint32)Fat_Buffer[tem+0x14]<<16) | ((uint32)Fat_Buffer[tem+0x15]<<24) ;
			  MusicInfoList[LocalOfMusic].FileLength = Fat_Buffer[tem+0x1C]|(Fat_Buffer[tem+0x1D]<<8)|((uint32)Fat_Buffer[tem+0x1E]<<16)|((uint32)Fat_Buffer[tem+0x1F]<<24);
			  LocalOfMusic++;   //开始下一个音乐文件的记录		  
			}
	   	}
		else
		{
    		LocalOfFirstLFN = Index_tmp;
		    while(1)
			{
			   Index_tmp++;
			   n = DiskFATInfo.FDT_LBA+(Index_tmp/(DiskFATInfo.BytesPerSector/32));
               //读取FDT的相应扇区位置的内容
   			   SD_ReadBlock(n,Fat_Buffer);
			   tem = ((Index_tmp)*32)%DiskFATInfo.BytesPerSector;
			   if(Fat_Buffer[tem+11]!= 0x0F)
			   {
		  	      MusicInfoList[LocalOfMusic].FileStartClustor = Fat_Buffer[tem+0x1A]|Fat_Buffer[tem+0x1B]<<8|((uint32)Fat_Buffer[tem+0x14]<<16) | ((uint32)Fat_Buffer[tem+0x15]<<24) ;
			      MusicInfoList[LocalOfMusic].FileLength = Fat_Buffer[tem+0x1C]|(Fat_Buffer[tem+0x1D]<<8)|((uint32)Fat_Buffer[tem+0x1E]<<16)|((uint32)Fat_Buffer[tem+0x1F]<<24);		 
				  break;		
			   }
			   
			}
			k = 0;
			for(i=Index_tmp-1; i>=LocalOfFirstLFN; i--)
			{
			      n = DiskFATInfo.FDT_LBA+(i/(DiskFATInfo.BytesPerSector/32));
               //读取FDT的相应扇区位置的内容
   			      SD_ReadBlock(n,Fat_Buffer);
			      tem = (i*32)%DiskFATInfo.BytesPerSector;
				  
				  for(j=1; j<32; j++)
			 	  {
				     if(j==0x0B|j==0x0C|j==0x0D|j==0x1A|j==0x1B)
					    continue;
					 if(Fat_Buffer[tem+j]<128 && Fat_Buffer[tem+j]!=0)
					 {
					     MusicInfoList[LocalOfMusic].FileName[k] = Fat_Buffer[tem+j];
						 k++;
					 }
					// else if(Fat_Buffer[tem+j]>128 && Fat_Buffer[tem+j]!=)
				  }
			}
			LocalOfMusic++;   //开始下一个音乐文件的记录			
		}
	}
	
	Index_tmp++;  //跳到下一个目录编号
	
  }
  NumOfFile = LocalOfMusic;
}

uint32 ReadBlockforCluster(uint32 Sector,uint32 offset)
{
	uint32  tmp;
   	SD_ReadBlock(Sector,Fat_Buffer);
	tmp=Fat_Buffer[offset] |(Fat_Buffer[offset+1]<<8) |((uint32)Fat_Buffer[offset+2]<<16) |((uint32)Fat_Buffer[offset+3]<<24);
	return tmp;
}


uint32 FatNextCluster(uint32 cluster)
{
    uint32 nextCluster=0;
    uint32 fatOffset=0;
    uint32 sector=0;
    uint16 offset=0;
	
	fatOffset = cluster<<2;
	sector = DiskFATInfo.FAT_LBA + (fatOffset>>9);	
	offset = fatOffset % DiskFATInfo.BytesPerSector;
	nextCluster = ReadBlockforCluster(sector,offset);
	if (nextCluster >= (CLUST_EOFS & FAT_MASK))				// 是否文件的结束簇
    {
        nextCluster = CLUST_EOFE;
    }
    return nextCluster;
}

⌨️ 快捷键说明

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