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

📄 fat.c

📁 基于STC51通过GPS自主定位导航FAT文件系统程序
💻 C
字号:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fat文件系统函数&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//*文件名称:fat.c

//*文件作用:fat文件系统函数

//*文件作者:翟  鹏

//*创建日期:2005年5月
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&



#include <include.h>



static ulong xdata DiskStart=0;//逻辑盘的起始绝对扇区号LBA
static uchar xdata SecPerClus;//逻辑盘的每簇扇区数
static uchar xdata RsvdSecCnt;//逻辑盘的保留扇区数
static uint  xdata FATSz16;//FAT16逻辑盘的FAT表占用的扇区数
static ulong data position=0;//文件偏移量


uchar fat_init(void)
{
	uchar data temp;

	//初始化SD卡
	if(SD_Init())return 1;	
	//读取逻辑引导扇区标志 判断是不是逻辑引导扇区
	SD_Set_SectorAddr(0);
	if(SD_Read_SectorByte(0,&temp))return 2;
	//如果不是逻辑引导扇区 提取逻辑引导扇区号
	if(temp!=0xEB && temp!=0xE9)
	{
		if(SD_Read_SectorByte(0x1C6,&temp))return 2;
		DiskStart=temp;
		if(SD_Read_SectorByte(0x1C7,&temp))return 2;
		DiskStart|=(uint)temp<<8;
		if(SD_Read_SectorByte(0x1C8,&temp))return 2;
		DiskStart|=(ulong)temp<<16;
		if(SD_Read_SectorByte(0x1C9,&temp))return 2;
		DiskStart|=(ulong)temp<<24;
	}
	//是逻辑引导扇区 逻辑引导扇区号=0
	else
	{
		DiskStart=0;
	}

	//提取逻辑盘参数
	SD_Set_SectorAddr(DiskStart);
	if(SD_Read_SectorByte(0x0D,&temp))return 3;SecPerClus=temp;//每簇扇区数
	if(SD_Read_SectorByte(0x0E,&temp))return 3;RsvdSecCnt=temp;//逻辑盘的保留扇区数
	if(SD_Read_SectorByte(0x16,&temp))return 3;FATSz16=(uint)temp;//FAT表占用扇区数
	if(SD_Read_SectorByte(0x17,&temp))return 3;FATSz16|=(uint)temp<<8;//FAT表占用扇区数

	return 0;
}

uint fopen(uchar *file_name, uchar *open_flag)
{
	uchar data temp;
	uint  data StartCluster=0xFFFF;//文件的首簇
	uchar data sector;
		
	if(*open_flag=='r' && *open_flag=='w')return 0xFFFF;
	
	//读取FAT16逻辑盘的根目录,寻找文件 通常根目录占用32个扇区
	for(sector=0;sector<SecPerClus;sector++)
	{
		uint CurrentDir;
		
		dog();
		
		//遍历当前扇区
		SD_Set_SectorAddr(DiskStart+RsvdSecCnt+FATSz16*2+sector);
		for(CurrentDir=0;CurrentDir<512;CurrentDir+=32)
		{	
			if(SD_Read_SectorByte(CurrentDir+0,&temp))return 0xFFFF;
			if(temp==0)break;//目录结束了 跳出循环
			if(temp!=0xE5)//文件没有被删除
			{
				if(SD_Read_SectorByte(CurrentDir+0x0B,&temp))return 0xFFFF;
				if((temp&0x08)==0)//正常已知文件
				{
					uchar data i;

					//比较文件名
					for(i=0;i<11;i++)
					{
						if(SD_Read_SectorByte(CurrentDir+i,&temp))return 0xFFFF;
						#ifdef DEBUG
						DEBUG_SEND_CHAR(temp);
						#endif
						if(temp!=file_name[i])break;
					}
					#ifdef DEBUG
					DEBUG_SEND_STR("\r\n");
					#endif
						
					//文件找到 提取文件的首簇
					if(i==11)
					{
						if(SD_Read_SectorByte(CurrentDir+0x1A,&temp))return 0xFFFF;
						StartCluster =(uint)temp;
						if(SD_Read_SectorByte(CurrentDir+0x1B,&temp))return 0xFFFF;
						StartCluster |=(uint)temp<<8;
						if(StartCluster!=0xFFFF)return StartCluster;
					}
				}
			}
		}
	}
	
	if(StartCluster!=0xFFFF)return StartCluster;
	
	return 0xFFFF;
}


void fseek(ulong offset)
{
	position=offset;	
}

uchar fread(char *buf, uint length, uint fp)
{
	uchar data temp;
	uint  data ClusterOffset=fp+(position>>9)/SecPerClus;
	
						
	//显示文件所有内容
	while(ClusterOffset<=0xFFEF && length)
	{
		//计算当前簇的开始扇区
		ulong data ClusterStartSector=DiskStart+RsvdSecCnt+FATSz16*2+32+(ulong)(ClusterOffset-2)*SecPerClus;
		//计算当前簇内的扇区偏移量
		uint data SectorOffset=(position>>9)%SecPerClus;
		//循环读取32个扇区的循环变量
		uchar data sector;
		
		dog();
		
		//判断文件为空文件
		if(ClusterOffset==0)return 1;
			
		//读取当前簇的 SecPerClus个扇区
		for(sector=SectorOffset;sector<SecPerClus;sector++)
		{			
			//当前扇区内的字节偏移量
			uint data ByteOffset=position%512;
			//当前扇区内的数据长度
			uint data count=512-ByteOffset;

			//长度不够一个扇区
			if(length<count)count=length;
				
			//读取扇区内的数据
			SD_Set_SectorAddr(ClusterStartSector+sector);
			if(SD_Read_Sector_Offset(ByteOffset,buf,count))return 2;
			//写入和读取的位置都向后移动
			buf+=count;
			position+=count;
			length-=count;
			if(length==0)return 0;
		}
		//获取链接簇
		SD_Set_SectorAddr(DiskStart+RsvdSecCnt+(ClusterOffset>>8));
		if(SD_Read_SectorByte(ClusterOffset+ClusterOffset,&temp))return 3;
		ClusterOffset=(uint)temp;
		if(SD_Read_SectorByte((ClusterOffset+ClusterOffset)+1,&temp))return 4;
		ClusterOffset|=(uint)temp<<8;
	}
	
	return 0;	
}



⌨️ 快捷键说明

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