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

📄 fat.c

📁 C51实现的FAT16格式下的USB通信
💻 C
字号:
#include "common.h"
#include "Fat.h"
#include "SL811.H"
#include "TPBULK.H"
#include "HAL.H"
//#include "RBCCMD.H"
////////////////////////////////////////
//extern uchar	bdata	usb_flag1;
//extern uchar	bdata	usb_flag2;
extern bit		SLAVE_FOUND;		// Slave USB device found
extern bit		TIMEOUT_ERR;		// timeout error during data endpoint transfer
extern bit		DATA_STOP;		// device unplugged during data transfer
extern bit		bTimer;
extern bit		bData1;

extern SYS_INFO_BLOCK xdata DeviceInfo;
extern FILE_INFO xdata ThisFile;		//当前已经打开的文件信息
extern unsigned char xdata DBUF[2060];
unsigned char xdata next_fat[512]		_at_	0X0400;
unsigned char xdata CurFatSector[512]	_at_	0X0800;
extern 	bit		NOW_READ;
idata		uint	NowFatSecNum,NowFatEntOffset;

////////////////////////////////////////
unsigned long FirstSectorofCluster(unsigned int clusterNum)	//计算出参数给出簇号的绝对扇区号
	{
	unsigned long data temp;
	temp=clusterNum-2;
	temp=temp*DeviceInfo.BPB_SecPerClus;
	temp=temp+DeviceInfo.FirstDataSector;
	return temp;
	}

unsigned int ThisFatSecNum(unsigned int clusterNum)		//用簇号计算在FAT的绝对扇区号
	{
	return(DeviceInfo.FatStartSector+clusterNum/(DeviceInfo.BPB_BytesPerSec/2));
	}

unsigned int ThisFatEntOffset(unsigned int clusterNum)		//用簇号计算在FAT扇区的偏移量,fat16的操作方法,因为簇链的表达是由2字节组成的
	{
	return(2*(clusterNum%(DeviceInfo.BPB_BytesPerSec/2)));
	}
bit	DeleteFileFat(void)	//将已经存在的文件全部簇链清除并打开文件,但不对DBR中的文件信息作修改
	{
	idata		uint	i;
	ThisFile.NowFatSecNum=DeviceInfo.FatStartSector+ThisFile.StartCluster/(DeviceInfo.BPB_BytesPerSec/2);
	ThisFile.NowFatEntOffset=2*(ThisFile.StartCluster%(DeviceInfo.BPB_BytesPerSec/2));
	if(!RBC_Read(ThisFile.NowFatSecNum,1,CurFatSector))
		return	FALSE;
	for(i=0;i<DeviceInfo.BPB_FATSz16*(DeviceInfo.BPB_BytesPerSec/2);i++)	//最大的情况就是所有的FAT项都被检索
		{
		if((CurFatSector[ThisFile.NowFatEntOffset]==0xff)&&(CurFatSector[ThisFile.NowFatEntOffset+1]==0xff))
			{
			CurFatSector[ThisFile.NowFatEntOffset]=0;
			CurFatSector[ThisFile.NowFatEntOffset+1]=0;
			NOW_READ=1;
			if(!RBC_Write(ThisFile.NowFatSecNum,1,CurFatSector))
				return FALSE;
			NOW_READ=1;
			if(!RBC_Write(ThisFile.NowFatSecNum+DeviceInfo.BPB_FATSz16,1,CurFatSector))
				return FALSE;
			break;	//找到文件结束标记,保存现在的FAT
			}
		else	//文件还未结束
			{
			NowFatSecNum=DeviceInfo.FatStartSector+CurFatSector[ThisFile.NowFatEntOffset+1];
			NowFatEntOffset=(uint)(2*CurFatSector[ThisFile.NowFatEntOffset]);
			CurFatSector[ThisFile.NowFatEntOffset]=0;
			CurFatSector[ThisFile.NowFatEntOffset+1]=0;
			if(ThisFile.NowFatSecNum!=NowFatSecNum)
				{
			//将FAT扇区信息回写
				NOW_READ=1;
				if(!RBC_Write(ThisFile.NowFatSecNum,1,CurFatSector))
					return FALSE;
				NOW_READ=1;
				if(!RBC_Write(ThisFile.NowFatSecNum+DeviceInfo.BPB_FATSz16,1,CurFatSector))
					return FALSE;
				ThisFile.NowFatSecNum=NowFatSecNum;
				if(!RBC_Read(ThisFile.NowFatSecNum,1,CurFatSector))	//调出本扇区FAT信息
					return FALSE;		//载入新的FAT信息失败
				}
			ThisFile.NowFatEntOffset=NowFatEntOffset;
			}
		}

	//将当前文件的FAT信息刷新
	ThisFile.bFileOpen=1;
	ThisFile.LengthInByte=0;
	ThisFile.ClusterPointer=ThisFile.StartCluster;
	ThisFile.SectorPointer=(ThisFile.StartCluster-2)*DeviceInfo.BPB_SecPerClus+DeviceInfo.FirstDataSector;
	ThisFile.NowFatSecNum=DeviceInfo.FatStartSector+ThisFile.ClusterPointer/(DeviceInfo.BPB_BytesPerSec/2);
	ThisFile.NowFatEntOffset=2*(ThisFile.ClusterPointer%DeviceInfo.BPB_BytesPerSec);
	if(!RBC_Read(ThisFile.NowFatSecNum,1,CurFatSector))
		return FALSE;		//载入新的FAT信息失败
	//文件项并未改变,待文件写完成后一并写入了
	return	TRUE;
	}
uint 	FindNextFreeClus(void)		//求出下一个空簇号,返回false表示操作失败否则代表找到
	{
	uint		i,clusterNum;
//先在FAT扇区内找空簇
	clusterNum=ThisFile.ClusterPointer;
	NowFatSecNum=ThisFile.NowFatSecNum;
	NowFatEntOffset=ThisFile.NowFatEntOffset;

	for(i=0;i<DeviceInfo.CountOfCluster+2;i++)
		{
		clusterNum++;	//到下一簇
		if(clusterNum>=(DeviceInfo.CountOfCluster+2))
			clusterNum=2;
		NowFatEntOffset+=2;
		if(NowFatEntOffset>=DeviceInfo.BPB_BytesPerSec)	//一个FAT扇区已经查完了
			{
			NowFatSecNum=ThisFatSecNum(clusterNum);	//重新刷新当前分配表指针信息
			NowFatEntOffset=ThisFatEntOffset(clusterNum);
			if(!RBC_Read(NowFatSecNum,1,next_fat))
				return FALSE;		//载入新的FAT信息失败
			if((next_fat[NowFatEntOffset]==0)&&(next_fat[NowFatEntOffset+1]==0))
				{
				CurFatSector[ThisFile.NowFatEntOffset]=(uchar)clusterNum;
				CurFatSector[ThisFile.NowFatEntOffset+1]=(uchar)(clusterNum>>8);
				UpdateFat();	//保存当前的FAT扇区
				if(!RBC_Read(NowFatSecNum,1,CurFatSector))	//将新的FAT表载入到当前FAT扇区保存
					return FALSE;		//载入新的FAT信息失败
				ThisFile.NowFatSecNum=NowFatSecNum;
				ThisFile.NowFatEntOffset=NowFatEntOffset;
				ThisFile.ClusterPointer=clusterNum;
				CurFatSector[ThisFile.NowFatEntOffset]=0xff;
				CurFatSector[ThisFile.NowFatEntOffset+1]=0xff;
				return clusterNum;
				}
			}
		if((CurFatSector[NowFatEntOffset]==0)&&(CurFatSector[NowFatEntOffset+1]==0))
			{
			CurFatSector[ThisFile.NowFatEntOffset]=(uchar)clusterNum;
			CurFatSector[ThisFile.NowFatEntOffset+1]=(uchar)(clusterNum>>8);
			ThisFile.NowFatSecNum=NowFatSecNum;
			ThisFile.NowFatEntOffset=NowFatEntOffset;
			ThisFile.ClusterPointer=clusterNum;
			CurFatSector[ThisFile.NowFatEntOffset]=0xff;
			CurFatSector[ThisFile.NowFatEntOffset+1]=0xff;
			return clusterNum;
			}
		}
	return FALSE;		//没有空簇了
	}
//uint 	FindFirstFreeClus(void)		//求出第一个空簇号,返回false表示操作失败否则代表找到
//	{
//	union
//		{
//		uchar	temp_byte[2];
//		uint		temp_word;
//		}clusterNum;
////先在FAT扇区内找空簇
//	clusterNum.temp_word=2;	//只能从第2簇开始查
//	if(!RBC_Read(DeviceInfo.FatStartSector,1,DBUF))	//读出第一个FAT扇区
//		return FALSE;		//载入新的FAT信息失败
//	while(clusterNum.temp_word<DeviceInfo.CountOfCluster+2)
//		{
//		if(clusterNum.temp_byte[1]==0)
//			{
//			if(!RBC_Read(clusterNum.temp_byte[0]+DeviceInfo.FatStartSector,1,DBUF))	//读出下一个FAT扇区
//				return FALSE;		//载入新的FAT信息失败
//			}
//		if((DBUF[(uint)(2*clusterNum.temp_byte[1])]==0)&&(DBUF[(uint)(2*clusterNum.temp_byte[1]+1)]==0))
//			return	clusterNum.temp_word;
//		clusterNum.temp_word++;
//		}
//	return FALSE;		//没有空簇了
//	}

bit UpdateFat(void)		//将FAT当前扇区的内容保存
{
	NOW_READ=1;
	if(!RBC_Write(ThisFile.NowFatSecNum,1,CurFatSector))
		return FALSE;
	NOW_READ=1;
	if(!RBC_Write(ThisFile.NowFatSecNum+DeviceInfo.BPB_FATSz16,1,CurFatSector))
		return FALSE;
	return TRUE;
}

⌨️ 快捷键说明

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