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

📄 fat16.c

📁 C51读写SD卡,SD卡使用SPI模式进行读写
💻 C
字号:

/* 取文件系统信息 */
/* 操作正确返回:0 */
uchar GetFATInfo(uchar *data)
{
	uchar s,*p,i;
	uint w;
/* 读硬盘信息 主要取:FAT类型(450)、首扇区地址即DBR地址(454,455,456,457)
  总扇区数,根据这个可以算出硬盘大小(458,459,460,461) */
	s=sd_read_block(0,data);								/* MBR */
	if(s!=0)return(s);
	p=data;
	p+=450;
	if(*p!=6)
	{														/* 判断文件系统(FAT16-6,FAT32-B) */
		return(1);
	}
	p+=4;													/* 取DBR地址 */
	DBRSectors=*p++;
	DBRSectors+=((ulong)*p++)<<8;
	DBRSectors+=((ulong)*p++)<<16;
	DBRSectors+=((ulong)*p++)<<24;
	TotalSectors=*p++;										/* 取总扇区数 */
	TotalSectors+=((ulong)*p++)<<8;
	TotalSectors+=((ulong)*p++)<<16;
	TotalSectors+=((ulong)*p)<<24;

/* 读硬盘信息 主要取:每扇区字节数(11,12)一般为512所以不管、每簇扇区数(13)、
   DBR到FAT1的扇区数(14,15)、每个FAT占的扇区数(22,23) */
	s=sd_read_block(DBRSectors,data);						/* DBR */
	if(s!=0)return(s);
	p=data;
	p+=13;
	SecPerClus=*p++;										/* 每簇扇区数 */
	w=*p++;
	w+=(uint)*p<<8;
	FATSectors=DBRSectors+w;								/* FAT1地址 */
	p+=7;
	w=*p++;
	w+=(uint)*p<<8;
	FDTSectors=FATSectors+w*2;								/* FDT地址 */
	DATASectors=FDTSectors+32;								/* DATA地址 */
	return(0);
}

#if SeekFile_EN
/* 查找文件 */
/* 找到文件返回0,找不到文件返回0x55,操作错误返回其它数据(不定) */
uchar List(uchar *data)
{
	uchar s,i,k,suffix[3],*p,over;
	while(1)
	{
		over=0;
		for(k=0;k<Item[list]/(SecPerClus*16);k++)
		{
			s=sd_read_block(FATSectors+Clus[list-1]/256,data);		/* 取下一簇 */
			if(s!=0)return(s);
			p=data;
			p=p+(Clus[list-1]%256)*2;
			Clus[list-1]=*p++;
			Clus[list-1]+=((uint)*p)<<8;
			if(Clus[list-1]>0xfff7)Item[list]=0,over=1;
		}
		if(over)break;
		for(i=(Item[list]%(SecPerClus*16))/16;i<SecPerClus;i++)
		{
			s=sd_read_block(DATASectors+((ulong)Clus[list-1]-2)*SecPerClus+i,data);
			if(s!=0)return(s);
			for(k=Item[list]%16;k<16;k++)
			{
				over=0;
				Item[list]++;
				p=data;
				p+=k*32;
				if(*p!=0xe5 && *p!='.')
				{
					for(s=0;s<3;s++)suffix[s]=*(p+8+s);
					if(suffix[0]=='M' && suffix[1]=='P' && suffix[2]=='3')
					{										/* MP3文件 */
						StartClus=*(p+26);
						StartClus+=(uint)*(p+27)<<8;
						for(s=0;s<list;s++)Item[s]--;
						return(0);
					}
					else if(*(p+11)==0x10)
					{										/* 子目录* */
						if(list<3)							/* 最高3层 */
						{
							list++;
							Clus[list-1]=*(p+26);
							Clus[list-1]+=(uint)*(p+27)<<8;
							FileLength=*(p+28);
							FileLength+=(ulong)*(p+29)<<8;
							FileLength+=(ulong)*(p+30)<<16;
							FileLength+=(ulong)*(p+31)<<24;
							s=List(data);
							if(s==0)return(0);
							list--;
							over=1;
						}
					}
				}
				if(over)break;
			}
			if(over)break;
		}
	}
	return(0x55);
}
uchar SeekFile(uchar *data)
{
	uchar s,i,k,suffix[3],*p,over;
	while(Item[0]<512)
	{														/* 根目录下有512项 */
		i=Item[0]/16;
		s=sd_read_block(FDTSectors+i,data);
		if(s!=0)return(s);
		for(i=Item[0]%16;i<16;i++)
		{
			over=0;
			Item[0]++;
			p=data;
			p+=i*32;
			if(*p!=0xe5)
			{
				for(s=0;s<3;s++)suffix[s]=*(p+8+s);
				if(suffix[0]=='M' && suffix[1]=='P' && suffix[2]=='3')
				{											/* MP3文件 */
					StartClus=*(p+26);
					StartClus+=(uint)*(p+27)<<8;
					FileLength=*(p+28);
					FileLength+=(ulong)*(p+29)<<8;
					FileLength+=(ulong)*(p+30)<<16;
					FileLength+=(ulong)*(p+31)<<24;
					return(0);
				}
				else if(*(p+11)==0x10)
				{											/* 子目录1 */
					if(*p!='A'||*(p+1)!='D'||*(p+2)!='V'||*(p+3)!='E'||*(p+4)!='R'||*(p+5)!='T')
					{
						list=1;
						Clus[list-1]=*(p+26);
						Clus[list-1]+=(uint)*(p+27)<<8;
						s=List(data);
						if(s==0)return(0);
						list=0;
						over=1;
					}
				}
			}
			if(over)break;
		}
	}
	return(0x55);
}
#endif
	
#if SeekAdvert_EN
/*----------------------------------------------------------*/
/* 查找文件Advert */
/* 找到文件返回0,否则返回0x55,操作出错返回其它数字 */
uchar SeekAdvert(uchar *data,uchar *sub,uchar *adv)
{
	uchar s,i,k,suffix[3],*p;
	uint term=0,c;
	while(term<512)
	{														/* 根目录下有512项 */
		i=term/16;
		s=sd_read_block(FDTSectors+i,data);
		if(s!=0)return(s);
		for(i=term%16;i<16;i++)
		{
			term++;
			p=data;
			p+=i*32;
			if(*(p+11)==0x10)
			{												/* 子目录1 */
				if(*p=='A'&&*(p+1)=='D'&&*(p+2)=='V'&&*(p+3)=='E'&&*(p+4)=='R'&&*(p+5)=='T'&& *(p+6)==*sub && *(p+7)==*(sub+1))
				{
					c=*(p+26);
					c+=(uint)*(p+27)<<8;
					term=0;
					while(1)
					{
						for(i=0;i<SecPerClus;i++)
						{
							s=sd_read_block(DATASectors+((ulong)c-2)*SecPerClus+i,data);
							if(s!=0)return(s);
							for(k=term%16;k<16;k++)
							{
								term++;
								p=data;
								p+=k*32;
								if(*p!=0xe5)
								{
									for(s=0;s<3;s++)suffix[s]=*(p+8+s);
									if(suffix[0]=='M' && suffix[1]=='P' && suffix[2]=='3')
									{
										if(*p==*adv && *(p+1)==*(adv+1) && *(p+2)==*(adv+2))
										{
											StartClus=*(p+26);
											StartClus+=(uint)*(p+27)<<8;
											FileLength=*(p+28);
											FileLength+=(ulong)*(p+29)<<8;
											FileLength+=(ulong)*(p+30)<<16;
											FileLength+=(ulong)*(p+31)<<24;
											return(0);
										}
									}
								}
							}
						}
						s=sd_read_block(FATSectors+c/256,data);		/* 取下一簇 */
						if(s!=0)return(s);
						p=data;
						p=p+(c%256)*2;
						c=*p++;
						c+=((uint)*p)<<8;
						if(c>0xfff7)return(0x55);
					}
				}
			}
		}
	}
	return(0x55);
}
#endif

⌨️ 快捷键说明

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