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

📄 fat16.c

📁 适合RAM有限的嵌入式系统使用的fat16文件系统。目前只支持在根目录下读写文件
💻 C
字号:
/*---------------------------------------------------------
使用sd卡
只支持一个簇大小的文件,目前是这样,我只用到这么大的文件也就没有增强他的功能了
fat16
作者Bear Zhou
2008.1-2008.6课余时间完成
huntstart@163.com
----------------------------------------------------------*/
#include "lpc214x.h"
#include "..\lcd\PCF8833.h"
#include "fat16.h"
#include "..\sd\sddriver.h"
#include "..\key\key.h"
#include "..\COM\uart.h"


INT8U  Read_r[512];
//INT8U  Name[12]={"xxxxxxxx.xxx"};
INT16U Root_s=0;//root list start sector
INT8U  Fat1_s=0;//@0x0e	 reserved sector
INT16U Fat_s=0;//@0x16	sectors per fat
INT8U  Cluster=0;//@0x0d sectors per cluster
INT16U File_s=0;//~@0x1a file start cluster
INT32U File_l=0;//~@0x1c number of byte of the file
INT16U File_n=0;//next cluster
INT16U f=0;
INT8U command[512];
INT8U s=3,cmd=0,z=0;
INT16U File_ns=0;//next sectors

INT8U Init_Fat()
{
	Fat1_s=0;
	Fat_s=0;
	Cluster=0;
	Root_s=0;
	if(SD_ReadBlock(0,Read_r)!=OK) return (ERROR);
	Fat1_s=Read_r[0x0e];
	Fat_s=Read_r[0x16]+((Read_r[0x17])<<8);
	Cluster=Read_r[0x0d];
	Root_s=Fat1_s+2*Fat_s;
	return (OK);
}

INT8U Compare(INT8U *Name,INT8U *Fname)	//find out where the file is.
{
	INT8U i,j,z=0xff;
	if(Name[0]!='*')
		for(j=0;j<16;j++)
		{	
			for(i=0;i<8;i++)
			if(Name[i]!=Fname[i+j*32]) 
				{z=0;break;}
			for(i=8;i<11;i++)
			if(Name[i+1]!=Fname[i+j*32]) 
				{z=0;break;}
			if(z==0xff) {z=j;break;}
			z=0xff;
		}
	else
		for(j=0;j<16;j++)//寻找被删除或者空目录项
		{	
			if((Fname[j*32]==0xe5)&&((Fname[j*32+1]!=0xb0)&&(Fname[j*32+1]!=0xc2)))
				{z=j;break;}
			if(Fname[j*32]==0)
				{z=j;break;}
			//z=0xff;
		}
	if(z!=0xff)
		return (z);
	return (ERROR);
}

/*---------------------------------
如果是写目录确定没有同名文存在的前提!
----------------------------------*/
INT8U Get_Root_File(INT8U *Name)
{
	INT8U j,i=0,sector=0;
//	INT16U time,date;
	File_s=0;
	File_l=0;	
	do
	{				
		if(SD_ReadBlock(Root_s+i,Read_r)!=OK) return (ERROR);
		j=Compare(Name,Read_r);
		if(j!=ERROR) break;//找到文件,获得行号跳出
		sector++;	
	}while(sector<32);
	if(j==ERROR) return (ERROR);
	File_s=Read_r[0x1a+j*32]+((Read_r[0x1b+j*32])<<8); //读出文件起始簇
	File_l=Read_r[0x1c+j*32]+((Read_r[0x1d+j*32])<<8)+((Read_r[0x1e+j*32])<<16)+((Read_r[0x1f+j*32])<<24);//获得文件长度
	File_n=File_s;//获得下一簇的值
	File_ns=520+(File_n-2)*32;	 
	return (OK);
}
/*----------------------------------
如果Fcluster==0说明有同名文件,且文件已打开
------------------------------------*/	
INT8U Set_New_File(INT8U *Name,int size,int Fcluster,INT8U hour,INT8U minute,INT8U sec,INT16U year,INT8U month,INT8U day)
{
	INT8U j,i=0,sector=0;
	INT16U time,date;
	if(Fcluster!=0)
	{
		File_s=Fcluster;
		File_n=Fcluster;
		do
		{				
			if(SD_ReadBlock(Root_s+sector,Read_r)!=OK) return (ERROR);
			j=Compare("********.***",Read_r);
			if(j!=ERROR) break;
			sector++;	
		}while(sector<32);
		if(j==ERROR) return (ERROR);
			
		//创建目录项,fat16,0x0c~0x15未定义
		time = hour*2048+minute*32+sec/2;
		date = (year-1980)*512+month*32+day;
		for(i=0;i<8;i++)
		Read_r[i+j*32]=Name[i];
		for(;i<11;i++)
		Read_r[i+j*32]=Name[i+1];
		Read_r[0x0b+j*32]=0;
		Read_r[0x16+j*32]=(INT8U)time;
		Read_r[0x17+j*32]=(INT8U)(time>>8);
		Read_r[0x18+j*32]=(INT8U)date;
		Read_r[0x19+j*32]=(INT8U)(date>>8);
		Read_r[0x1a+j*32]=(INT8U)Fcluster;
		Read_r[0x1d+j*32]=(INT8U)(Fcluster>>8);
		Read_r[0x1c+j*32]=(unsigned char)size;
		Read_r[0x1d+j*32]=(unsigned char)(size>>8);
		Read_r[0x1e+j*32]=(unsigned char)(size>>16);
		Read_r[0x1f+j*32]=(unsigned char)(size>>24);
		if(SD_WriteBlock(Root_s+sector, Read_r)!=OK)	return (ERROR);	
	}
	else
	{

		j=Compare(Name,Read_r);

		if(j==ERROR) return (ERROR);
			
		//修改目录项,fat16,0x0c~0x15未定义
		time = hour*2048+minute*32+sec/2;
		date = (year-1980)*512+month*32+day;

		Read_r[0x16+j*32]=(INT8U)time;
		Read_r[0x17+j*32]=(INT8U)(time>>8);
		Read_r[0x18+j*32]=(INT8U)date;
		Read_r[0x19+j*32]=(INT8U)(date>>8);

		Read_r[0x1c+j*32]=(unsigned char)size;
		Read_r[0x1d+j*32]=(unsigned char)(size>>8);
		Read_r[0x1e+j*32]=(unsigned char)(size>>16);
		Read_r[0x1f+j*32]=(unsigned char)(size>>24);
		if(SD_WriteBlock(Root_s+sector, Read_r)!=OK)	return (ERROR);	
	}
	return (OK);
}
void Get_File()
{
	//INT8U i,j,s=3,cmd=0,z=0;
	//unsigned char x=0,y=0;
//	int f=0,command[48]={0};
	//Init_key();
	PutString(1,60,"OK",0xF800,0xFFE0);
	PutHex(1,32, (INT8U)(Root_s>>8),0xffff,0x0000);
	PutHex(30,32, (INT8U)(Root_s),0xffff,0x0000);
	PutHex(60,32, (INT8U)(File_n>>8),0xffff,0x0000);
	PutHex(90,32, (INT8U)(File_n),0xffff,0x0000);
	SD_ReadBlock((File_n-2)*32+520,Read_r);
	S1D15G00ClearLcd();
}

void S_C()
{
	INT8U i,j;	
	s=Scan();
	if(s==3)
	{
		cmd=0;
		//if(f>512) f=0;
		for(;f<511;f++)
		{
			if((Read_r[f]=='A')&&(Read_r[f+1]=='T'))
				cmd=1;	
			if(cmd==1)
			{
				for(;;z++)
				{
					command[z]=Read_r[f];
					if((command[z]==0x0a)||(z>=510)||(f>=512)) {cmd=0;command[z+1]='\0';z=0;break;}
					f++;
				}
				break;				
			}			
		}
	}		
	if(s==6)
	{
		cmd=3 ;
		for(;f>0;f--)
		{
			if((Read_r[f-1]=='A')&&(Read_r[f]=='T'))
				cmd--;	
			if(cmd==1)
			{
				f--;
				for(;;z++)
				{
					command[z]=Read_r[f];
					if((command[z]==0x0a)||(z>=46)||(f>=512)) {cmd=0;command[z+1]='\0';z=0;break;}
					f++;				
				}
				break;
			}			
		}		
	}
	if(s!=0)
	{	
		for(j=0;j<1;j++)
			for(i=0;i<16;i++)
				PutChar(i*8,j*16,' ',0x0000,0xffff);
		for(j=0;j<1;j++)
			for(i=0;i<16;i++)
			{
				if((command[j*16+i]>=0x21)&&(command[j*16+i]<=0x7E))
				{
					PutChar(i*8,j*16,command[j*16+i],0x0000,0xffff);
				}
				if(command[j*16+i]==0x0a) {break;}	
			}
	}
	if(s==4)
		SendByte0(0x1a)	;	 

	 if(s==8)
	 {
	 	UART0_SendData(command);	
	 }
}
void writeJPEG(unsigned char sector,unsigned char* Rbuf,long No)
{
	long i=0;
	for(i=4;i<No-2;i++)
	 	Read_r[i-4]=Rbuf[i];
	if(No!=518)
	for(i=No-7;i<512;i++)
		Read_r[i]=0;
	SD_WriteBlock(520+(File_n-2)*32+sector, Read_r);
}
/*---------------------------------------------------------------
修改fat表传出簇号,传入0,则返回新文件所在簇号,出入>2的值,则
将对应簇置0,成功返回1,失败,返回0。
----------------------------------------------------------------*/
long Findcluster(long Dcluster)
{
	//int sect=0;
	INT8U cluster=0;
	INT8U cluster_p_s=0;

	if(Dcluster==0)
	{
		for(cluster=0;cluster<=242;cluster++)
		{ 
			if(SD_ReadBlock(Fat1_s+cluster,Read_r)!=OK) return (0);
			for(cluster_p_s=0;cluster_p_s<256;cluster_p_s++)
			{
				if((Read_r[cluster_p_s*2]==0)&&(Read_r[cluster_p_s*2+1]==0))
				{	
					Read_r[cluster_p_s*2]=0xff;
					Read_r[cluster_p_s*2+1]=0xff;
					SD_WriteBlock(Fat1_s+cluster, Read_r);
					SD_WriteBlock(Fat1_s+cluster+243, Read_r);
					return (((long)(cluster)<<8)+(long)(cluster_p_s));
				}					
			}
		}
	 				 	
	}
	else
	{
		cluster = (INT8U)(Dcluster>>8);
		cluster_p_s	=(INT8U)(Dcluster);
		if(SD_ReadBlock(Fat1_s+cluster,Read_r)!=OK) return (0);
		Read_r[cluster_p_s*2]=0;
		Read_r[cluster_p_s*2+1]=0;
		SD_WriteBlock(Fat1_s+cluster, Read_r);
		SD_WriteBlock(Fat1_s+cluster+243, Read_r);	
		return 1;		
	}
	return 0;
}
void NameB(INT8U* Name , INT16U i)
{
	 Name[0]=i/10000+48;
	 Name[1]=(i%10000)/1000+48;
	 Name[2]=(i%1000)/100+48;
	 Name[3]=(i%100)/10+48;
	 Name[4]=(i%10)/1+48;
	 Name[5]='Z';
	 Name[6]='Q';
	 Name[7]='W';
}
INT16U GetJPEG(unsigned char* Name,unsigned char* filedata )
{
	INT16U i=0,j=0,iend;
	if(Get_Root_File(Name)==ERROR) return ERROR; 
	
	iend=File_l/512;
	
	//Uart_Printf("\niend=",iend);
	for(i=0;i<=iend;i++)
	{
		if(SD_ReadBlock(File_ns+i,Read_r)!=OK) return 0; 
		//Uart_Printf("\nFile_ns+i=",File_ns+i);
		//Uart_Printf("\ni=",i);
		for(j=0;j<512;j++)	
		{
			

			filedata[i*512+j]=Read_r[j];
			//SendByte0(filedata[(i*512)+j]);
			//for(delay=0;delay<5000;delay++);
		}
	}
	//Uart_Printf("file_l=",File_l);
	return File_l;	
}

⌨️ 快捷键说明

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