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

📄 fat.c

📁 基于stm32的MP3播放器
💻 C
📖 第 1 页 / 共 2 页
字号:
			}
		}  				 
	}
	else//其他文件夹/FAT32系统
	{
		tempclust=cluster;
		while(1)
		{
			sector=fatClustToSect(tempclust);
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(SD_ReadSingleBlock(sector+cnt,fat_buffer))return 1;
				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];//p指向长文件名的存放地址
								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)
							{
								CopyDirentruyItem(FileInfo,item);//复制目录项,提取详细信息  
								return 1;//找到目标文件成功	 
							}
							LongNameFlag=0;//清空长文件名
						}
					}
				}
			}						  
			tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
			if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
		}  
	}
	if(*count==0)
	{
		*count=cont;//得到总共文件数目
		return 1;   //操作成功,找到cont个符合条件的文件了
	}else return 0; //操作失败,没找到文件,或者出错
}
//打开文件
void F_Open(FileInfoStruct *FileInfo)
{
	FileInfo->F_CurClust=FileInfo->F_StartCluster;//当前簇为首簇
	FileInfo->F_Offset=0;//偏移扇区为0
}
//读取512个字节
//FileInfo:要读取的文件
//buf     :数据缓存区
//返回值  :0,操作失败,1,操作成功
unsigned char F_Read(FileInfoStruct *FileInfo,u8 *buf)
{	
	DWORD sector;			   		  
	sector=fatClustToSect(FileInfo->F_CurClust);//得到当前簇号对应的扇区号	   	 		    
	if(SD_ReadSingleBlock(sector+FileInfo->F_Offset,buf))return 0;//读数错误   
	FileInfo->F_Offset++;
	if(FileInfo->F_Offset==SectorsPerClust)	//簇的尽头,换簇
	{
		FileInfo->F_Offset=0;		    
		FileInfo->F_CurClust=FAT_NextCluster(FileInfo->F_CurClust);//读取下一个簇号
		if((FAT32_Enable==0&&FileInfo->F_CurClust==0xffff) \
		||FileInfo->F_CurClust==0x0ffffff8||FileInfo->F_CurClust == 0x0fffffff)return 0;//error	    
	} 
	return 1;//读取成功
}

//读取前512个字节
//FileInfo:要读取的文件
//buf     :数据缓存区
//返回值  :0,操作失败,1,操作成功
unsigned char F_PrevRead(FileInfoStruct *FileInfo,u8 *buf)
{	
	DWORD sector;  
	if(FileInfo->F_Offset>1)FileInfo->F_Offset-=2;//未超簇,直接跳到上一扇区
	else 					  //超簇了,换到上一簇
	{
		FileInfo->F_CurClust=FAT_PrevCluster(FileInfo->F_CurClust,FileInfo->F_StartCluster);//读取上一个簇号
		if((FAT32_Enable==0&&FileInfo->F_CurClust==0xffff) \
		||FileInfo->F_CurClust==0x0ffffff8||FileInfo->F_CurClust == 0x0fffffff)return 0;//读数错误	 
		if(FileInfo->F_Offset==1)FileInfo->F_Offset=SectorsPerClust-1;//跳到最后一个扇区 
		else FileInfo->F_Offset=SectorsPerClust-2;//读倒数第二簇  
	}  
	sector=fatClustToSect(FileInfo->F_CurClust);//得到当前簇号对应的扇区号	   
	if(SD_ReadSingleBlock(sector+FileInfo->F_Offset,buf))return 0;//读数错误   
	return 1;//读取成功
}

//比较两个字符串相等不
//相等,返回1,不相等,返回0;
u8 mystrcmp(u8*s1,u8*s2)
{
	u8 len1,len2;
	len1=len2=0;
	while(*s1!='\0')
	{
		len1++;s1++;
	}
	while(*s2!='\0')
	{
		len2++;s2++;
	}
	if(len1!=len2)return 0;//不相等 
	s1-=len1;s2-=len1;
	while(*s1!='\0')
	{
		if(*s1!=*s2)return 0;//不相等 
		s1++;s2++;
	}
	return 1;
}	 
//查找系统文件
//在指定目录下,找寻一个指定类型的指定名字的文件
//cluster:文件夹的簇号!!!
//Name   :文件的名字
//type   :文件类型
//返回值 :该文件的开始簇号
u32 F_Search(u32 cluster,unsigned char *Name,u16 type)
{
	DWORD sector;			 
	DWORD tempclust;
	unsigned char cnt;
	unsigned int offset; 

	direntry *item = 0;	  
	FileInfoStruct FileInfo;    			    
	if(cluster==0 && FAT32_Enable==0)//FAT16根目录读取
	{			 
		for(cnt=0;cnt<RootDirSectors;cnt++)
		{
			if(SD_ReadSingleBlock(FirstDirSector+cnt,fat_buffer))return 1;//读数错误    
			for(offset=0;offset<512;offset+=32)
			{
				item=(direntry *)(&fat_buffer[offset]);//指针转换
				//找到一个可用的文件
				if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))//找到一个合法文件
				{		   
					if(item->deAttributes != AM_LFN)//忽略长文件名	 
					{  	 				 
						CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息	   
						if(FileInfo.F_Type&type)//找到一个合适的类型了
						{
						   // printf("File Name:%s\n",FileInfo.F_Name);
	
							//找到了文件,返回这个文件的首簇
							if(mystrcmp(Name,FileInfo.F_Name))return FileInfo.F_StartCluster; 
						} 	  
						LongNameFlag=0;//清空长文件名
					}
				}
			}
		}  				 
	}
	else//其他文件夹/FAT32系统
	{
		tempclust=cluster;
		while(1)
		{
			sector=fatClustToSect(tempclust);
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(SD_ReadSingleBlock(sector+cnt,fat_buffer))return 1;
				for(offset=0;offset<512;offset+=32)
				{
					item=(direntry *)(&fat_buffer[offset]);
					if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))
					{				
						if(item->deAttributes != AM_LFN) //忽略长文件名		    
						{  	 				 
							CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息	  

							if(FileInfo.F_Type&type)//找到一个合适的类型了
							{	/*										   
								printf("F_Info->F_Name:%s\n",FileInfo.F_Name);
								printf("F_Info->F_Type:%d\n",FileInfo.F_Type);
								printf("F_Info->F_Size:%d\n",FileInfo.F_Size);
								printf("F_Info->F_StartClusterH:%x\n",FileInfo.F_StartCluster>>8); 	
								printf("F_Info->F_StartClusterL:%x\n\n",FileInfo.F_StartCluster&0xff); */
								//找到了文件,返回这个文件的首簇
								if(mystrcmp(Name,FileInfo.F_Name))return FileInfo.F_StartCluster; 
							} 	  
							LongNameFlag=0;//清空长文件名
						}
					}
				}
			}						  
			tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
			if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
		}  
	}
	return 0;//失败						    
}

//分块图片编号获取算法
//得到 IMGXX   BMP
//XX:00~16				  
void Get_Game_Pic_Str(u8 t,u8 *str)
{
	*str++='I';
	*str++='M';
	*str++='G';
	*str++=(t/10)%10+'0';
	*str++=t%10+'0';
	*str++=' ';
	*str++=' ';	
	*str++=' ';	
	*str++='B';		
	*str++='M';
	*str++='P';
	*str='\0';//加入结束符
}


//获取系统文件的存储地址
//次步出错,则无法启动!!!
//返回0,失败。返回1,成功
//sel:bit7:0,查找系统文件
//sel:bit7:1,查找游戏文件
//sel:bit 0~6 编号
u8 SysInfoGet(u8 sel)
{			 
	u32 cluster=0;
	u32 syscluster=0;
	u8 t=0;	  
	u8 imgx[9];
	u8 sizex;  //图片大小 也就是难度的大小	 
	//得到根目录的簇号
	if(FAT32_Enable)cluster=FirstDirClust;
	else cluster=0;			   
	cluster=F_Search(cluster,(unsigned char *)folder[0],T_FILE);//查找system文件夹
	if(cluster==0)return 0;//系统文件夹丢失
	syscluster=cluster;//保存系统文件夹所在簇号

	if(sel&0x80)//查找游戏文件
	{	
		sizex=sel&0x7F;//得到size 3*3、4*4、5*5									  
		cluster=F_Search(cluster,(unsigned char *)folder[3],T_FILE);//在system文件夹下查找game文件夹
		if(cluster==0)return 0;  		
					   
		cluster=F_Search(cluster,(unsigned char *)folder[sizex+1],T_FILE);//在game文件夹下查找LEVEL(sizex-2)文件夹	
		if(cluster==0)return 0;//系统文件夹丢失	   	  			   
		sizex*=sizex;//取平方
		for(t=0;t<sizex+1;t++) //X*X图片地址获取
		{
			Get_Game_Pic_Str(t,imgx);//得到图片编号		  
			Pic_Addr[t]=F_Search(cluster,imgx,T_BMP);//在LEVEL1文件夹下查找BMP图片
			if(Pic_Addr[t]==0)return 0;//系统文件夹丢失	 	
		}	 
		printf("level ok\n");
	}else//查找系统文件
	{	 										 
		//先查找字体
		cluster=F_Search(syscluster,(unsigned char *)folder[1],T_FILE);//在system文件夹下查找FONT文件夹
		if(cluster==0)return 0;//字体文件夹丢失	  
		//printf("SYSTEM FILE FOUND OK!\n");
		FONT16CLUSTER=F_Search(cluster,(unsigned char *)sysfile[0],T_FON);//在system文件夹下查找FONT16字体文件
		if(FONT16CLUSTER==0)return 0;//FONT16字体文件丢失		 
		//printf("FONT16 FOUND OK!\n");	  
		FONT12CLUSTER=F_Search(cluster,(unsigned char *)sysfile[1],T_FON);//在system文件夹下查找FONT12字体文件
		if(FONT12CLUSTER==0)return 0;//FONT12字体文件丢失						  	 
		//printf("FONT12 FILE FOUND OK!\n");
	
		cluster=F_Search(syscluster,(unsigned char *)folder[2],T_FILE);//在system文件夹下查找SYSICO文件夹
		if(cluster==0)return 0; 
		for(t=0;t<9;t++)//查找系统图标,九个
		{
			sys_ico[t]=F_Search(cluster,(unsigned char *)sysfile[t+2],T_BMP);//在SYSICO文件夹下查找系统图标
			if(sys_ico[t]==0)return 0;//失败		 
		}
		for(t=11;t<15;t++)//查找系统图标,4个
		{
			file_ico[t-11]=F_Search(cluster,(unsigned char *)sysfile[t],T_BMP);//在SYSICO文件夹下查找文件图标
			if(file_ico[t-11]==0)return 0;//失败 	  
		}
	}
	return 1;//成功
}

⌨️ 快捷键说明

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