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

📄 fat.c

📁 ch375读U盘程序
💻 C
字号:
#include "fat.h"
#include "ch375wr.h"

unsigned int	fat_offset;
unsigned int	data_offset;
unsigned char	FatFlags;
unsigned long	blocknow;
unsigned char	SecPerClus;
unsigned int	VBRadd;

//############################################################################
//从BPB中获取FDT表的地址,同时判断FAT制式
unsigned int fat_root_dir_addr(unsigned char *buff) 
//############################################################################
{
	struct BootSec *bootp; //根目录文件表结构
	struct BootSec32 *bootp32;
	unsigned int	FirstRootDirSecNum;
	mmcReadSector(BIOS_PARAMETER_BLOCK,buff);
	if(buff[0] != 0xEB)	//this is mbr
	{
		VBRadd = buff[0x1C6] + (buff[0x1C7] << 8);			//real BPB address
	}
	else
	{
		VBRadd = 0;
	}
	mmcReadSector(VBRadd,buff);

	bootp=(struct BootSec *)buff;
	bootp32=(struct BootSec32 *)buff;

	if(bootp->BPB_RootEntCnt == 0)
	{
		FatFlags = FAT_Flg_32;
		fat_offset = bootp32->BPB_RsvdSecCnt + VBRadd;	//偏移扇区数
		//FDT偏移地址=保留扇区+FAT占用扇区
		FirstRootDirSecNum = VBRadd + (bootp32->BPB_RsvdSecCnt +
	                       (bootp32->BPB_NumFATs * bootp32->BPB_FATSz32));
	}
	else
	{
		if(bootp->BPB_SysID[4] == '2')
			FatFlags = FAT_Flg_12;
		else
			FatFlags = FAT_Flg_16;
		fat_offset = bootp->BPB_RsvdSecCnt + VBRadd;
		//FDT偏移地址=保留扇区+FAT占用扇区
		FirstRootDirSecNum = VBRadd + (bootp->BPB_RsvdSecCnt +
	                       (bootp->BPB_NumFATs * bootp->BPB_FATSz16));
	}
	
	SecPerClus = bootp->BPB_SecPerClus;	
	data_offset = FirstRootDirSecNum + 32;	//+FDT size
		
	return(FirstRootDirSecNum);
}

//############################################################################
//解析FAT链表
void fat_load(unsigned long Cluster, 		//文件起始扇区
				unsigned long *Block,		//返回文件下一扇区
				unsigned char *TMP_Buffer) 	//函数所需buffer
//############################################################################
{
	unsigned int FAT_Byte_Addresse;	
	unsigned long FAT_Block_Addresse;

	//读取FAT表,根据FAT制式搜寻扇区
	if(FatFlags == FAT_Flg_16)
	{
		if(Cluster == 0xFFFF)
		{
			return; //文件已经到达末尾
		}
		FAT_Byte_Addresse = ((Cluster<<1) & 0x1FF);		FAT_Block_Addresse = ((Cluster<<1)/BlockSize) + fat_offset;
		mmcReadSector(FAT_Block_Addresse,TMP_Buffer);
		*Block = (TMP_Buffer[FAT_Byte_Addresse + 1] << 8) + TMP_Buffer[FAT_Byte_Addresse];
		if(*Block == 0xFFFF)
			*Block = 0xFFFFFFFF;
	}
	else if(FatFlags == FAT_Flg_12)
	{
		if(Cluster == 0xFFF)
		{
			return; //文件已经到达末尾
		}
		FAT_Byte_Addresse = (((Cluster*3)>>1) & 0x1FF);
		FAT_Block_Addresse = (((Cluster*3)>>1) / BlockSize) + fat_offset;
		if(FAT_Byte_Addresse == 0x1FF)
		{
			mmcReadSector(FAT_Block_Addresse,TMP_Buffer);
			if((Cluster % 2) == 0)
			{
				*Block = TMP_Buffer[FAT_Byte_Addresse];
			}
			else
			{
				*Block = (TMP_Buffer[FAT_Byte_Addresse] >> 4);
			}
			mmcReadSector(FAT_Block_Addresse+1,TMP_Buffer);
			if((Cluster % 2) == 0)
			{
				*Block += ((TMP_Buffer[0] & 0x0F) << 8);
			}
			else
			{
				*Block += (TMP_Buffer[0] << 4);
			}
		}
		else
		{
			mmcReadSector(FAT_Block_Addresse,TMP_Buffer);
			if((Cluster % 2) == 0)
			{
				*Block = ((TMP_Buffer[FAT_Byte_Addresse + 1] & 0x0F) << 8) + TMP_Buffer[FAT_Byte_Addresse];
			}
			else
			{
				*Block = (TMP_Buffer[FAT_Byte_Addresse + 1] << 4) + (TMP_Buffer[FAT_Byte_Addresse] >> 4);
			}
		}
		if(*Block == 0xFFF)
			*Block = 0xFFFFFFFF;
	}
	else if(FatFlags == FAT_Flg_32)
	{
		if(Cluster == 0xFFFFFFFF)
		{
			return; //文件已经到达末尾
		}
		FAT_Byte_Addresse = ((Cluster<<2) & 0x1FF);
		FAT_Block_Addresse = ((Cluster<<2) / BlockSize) + fat_offset;
		mmcReadSector (FAT_Block_Addresse,TMP_Buffer);
		*Block = (TMP_Buffer[FAT_Byte_Addresse + 3] << 24) +
					(TMP_Buffer[FAT_Byte_Addresse + 2] << 16) +
					(TMP_Buffer[FAT_Byte_Addresse + 1] << 8) +
					TMP_Buffer[FAT_Byte_Addresse];
	}
	return;
}

//############################################################################
//读取文件目录区相关信息	
unsigned int fat_read_dir_ent(unsigned long dir_cluster,	//目录所在簇
							unsigned int Entry_Count,	//目录中文件序号
							unsigned long *Size,		//文件长度
							unsigned char *Dir_Attrib,	//文件属性
							unsigned char *buff)		//函数所需buffer
//############################################################################
{
	unsigned char *pointer;
	unsigned int TMP_Entry_Count = 0;
	unsigned long Block=0;			//目录所在扇区地址
	unsigned int blk;
	unsigned int a;
	unsigned char b;
	struct DirEntry *dir; //文件目录指针

	pointer = buff;

	if (dir_cluster == 0)	//根目录
	{
		Block = fat_root_dir_addr(buff);
	}
	else					//子目录
	{
		Block = (dir_cluster-2)*SecPerClus+data_offset;
	}

	for (blk = Block;;blk++)
	{
		mmcReadSector(blk,buff);	
		for (a=0;a<BlockSize; a = a + 32)
		{
		 	dir=(struct DirEntry *)&buff[a]; //装载目录内容
		 
			if (dir->DIR_Name[0] == 0) //目录已经删除
			{
				return (0xFFFF);
			}
			
			//非长文件名,并且文件没有删除
   			if ((dir->DIR_Attr != ATTR_LONG_NAME) &&
				(dir->DIR_Name[0] != DIR_ENTRY_IS_FREE)) 
			{
				//第Entery_Count个文件目录
				if (TMP_Entry_Count == Entry_Count) 
				{
					//装载文件名
					for(b=0;b<11;b++)
					{
						if (dir->DIR_Name[b] != SPACE)
						{
							if (b == 8)
							{
								*pointer++= '.';
							}
							*pointer++=dir->DIR_Name[b];
						}
					}						
					*pointer++='\0';
					*Dir_Attrib = dir->DIR_Attr;

					//文件长度
					*Size=dir->DIR_FileSize;
					
					//文件起始簇的低16位
					dir_cluster = dir->DIR_FstClusLO + (dir->DIR_FstClusHI<<16);

					//返回起始簇
					return(dir_cluster);
				}
			TMP_Entry_Count++;
			}
		}
	}
	return (0xFFFF); //Kein Eintrag mehr gefunden R點ksprung mit 0xFFFF
}


//############################################################################
//读取文件内容每次512bytes
unsigned char fat_read_file(unsigned int Cluster,	
				 			unsigned char *buff,
				 			unsigned long BlockCount,
							unsigned char *blockserial)
//############################################################################
{
	unsigned long Block;
	static unsigned char serial=0; 
	
	if(BlockCount == 0)
	{
		fat_load(Cluster,&Block,buff);
		mmcReadSector((Cluster-2)*SecPerClus+data_offset+serial,buff);
		serial++;
		blocknow = Cluster;
		*blockserial = SecPerClus-serial;
		if(serial == SecPerClus)
			serial = 0;
	}
	else
	{
		fat_load(blocknow,&Block,buff);
		mmcReadSector((blocknow-2)*SecPerClus+data_offset+serial,buff);
		serial++;
		*blockserial = SecPerClus-serial;
		if(serial == SecPerClus)
			serial = 0;
	}
	if(serial == 0)
		blocknow = Block;
	if(blocknow == 0xFFFFFFFF)
		return 1;
	else
		return 0;

}

unsigned char strscmp(unsigned char *src,unsigned char *dist)
{
	while(*src)
	{
		if((*src) != (*dist))
		{
			if((*src) > (*dist))
				return 1;
			else
				return 2;
		}
		src++;
		dist++;
	}
	return 0;
}

//####################################################################################
//Sucht ein File im Directory
unsigned char fat_search_file (unsigned char *File_Name,		//要查找的文件名
							unsigned long *Cluster, 	//要查找的文件所在簇
							unsigned long *Size, 		//查到的文件大小
							unsigned char *Dir_Attrib,//查到的文件属性
							unsigned char *buff) 	//查到的文件名称
//####################################################################################
{
	unsigned int Dir_Cluster_Store = *Cluster;
	unsigned char a;
	for (a = 0;a < 100;a++)
	{
		*Cluster = fat_read_dir_ent(Dir_Cluster_Store,a,Size,Dir_Attrib,buff);
		if (*Cluster == 0xffff)
		{
			return(0); //File not Found
		}
		if(strscmp(File_Name,buff) == 0)
		{
			return(1); //File Found
		}
	}
	return(2); //Error
}

⌨️ 快捷键说明

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