fat.c

来自「加速度采集器。基于ATMega16L.AVRSTUIDIO4」· C语言 代码 · 共 564 行 · 第 1/2 页

C
564
字号
}

unsigned char fileClose(unsigned short sdBufferLength)
{
	unsigned char ucTemp;
	unsigned short usTemp;
	unsigned long currentSector;

	//1. if sdBufferLength==0 && fileCurrentSectorInCluster, Write an zero record cluster
	if(!sdBufferLength && !fileCurrentSectorInCluster)
	{
		for(usTemp=0;usTemp<512;usTemp++)
			sdBuffer[usTemp] = 0;
		sdBufferLength = 512;
	}
	fileSize += sdBufferLength;

	//2. write Buffer
	currentSector = clusterBeginSector;
	currentSector += fileCurrentCluster*sectorsPerCluster;
	currentSector += fileCurrentSectorInCluster;
	if(sdWriteData(currentSector<<9))
		return FATERR_NOCARD;
	//3. write EOF
	ucTemp = fileWriteEOF();
	return ucTemp;
}

//========================================================================================================================
//===========================================Internal Operation===========================================================
//========================================================================================================================

unsigned char fatNextEmptyCluster()	//move fileCurrentCluster to next empty cluster
{
	unsigned long clusterSearchSector;	//offset
	unsigned short clusterSearchIndex;
	unsigned char clusterFound = 0;

	//Step over current cluster, because this cluster hasnot been marked as used!
	fileCurrentCluster++;
	if(partitionType ==1) 			//FAT16
	{
		clusterSearchSector = fileCurrentCluster>>8;
		clusterSearchIndex = fileCurrentCluster&0xFF;
	}
	else							//FAT32
	{
		clusterSearchSector = fileCurrentCluster>>7;
		clusterSearchIndex = fileCurrentCluster&0x7F;
	}
		
	while(clusterSearchSector<sectorsPerFAT && !clusterFound)
	{
		if(sdReadData((fatBeginSector+clusterSearchSector)<<9))	//Read in the current cluster in FAT
			return FATERR_NOCARD;
		if(partitionType==1)
		{						//FAT16: everty FAT record in 2 bytes
			for(;clusterSearchIndex<256;clusterSearchIndex++)
				if ( !*(unsigned short*)(sdBuffer+(clusterSearchIndex<<1)) )	// An empty found
				{
					fileCurrentCluster = clusterSearchSector*256+clusterSearchIndex;
					clusterFound = 1;
					break;
				}
		}
		else if(partitionType==2)						//FAT32: everty FAT record in 4 bytes
		{
			for(;clusterSearchIndex<128;clusterSearchIndex++)
				if( !*(unsigned long*)(sdBuffer+(clusterSearchIndex<<2))	)// An empty found
				{
					fileCurrentCluster = clusterSearchSector*128+clusterSearchIndex;
					clusterFound = 1;
					break;
				}
		}
		clusterSearchSector++;
		clusterSearchIndex=0;							//When Changed to next sector, search from begining
	}//while
	if(!clusterFound)
		return FATERR_DISKFULL;
	return FATERR_NOERR;
}

unsigned char fatWriteFAT(unsigned long previousCluster, unsigned long currentCluster)
{
	unsigned short usTemp;
	unsigned long currentSector;

	if(partitionType==1)	//FAT16: 2 bytes, 256/sector
	{
		currentSector = fatBeginSector+(previousCluster>>8);		//Read FAT
		if(sdReadData(currentSector<<9))
			return FATERR_NOCARD;
		usTemp = previousCluster&0xFF;
		*(unsigned short*)(sdBuffer+(usTemp<<1)) = currentCluster;	//Fill FAT
		if(sdWriteData(currentSector<<9))								//Write FAT 1
			return FATERR_NOCARD;
		if(sdWriteData((currentSector+sectorsPerFAT)<<9))				//Write FAT 2
			return FATERR_NOCARD;
	}
	if(partitionType==2)	//FAT32: 2 bytes, 128/sector
	{
		currentSector = fatBeginSector+(previousCluster>>7);		//Read FAT
		if(sdReadData(currentSector<<9))
			return FATERR_NOCARD;
		usTemp = previousCluster&0x7F;
		*(unsigned long*)(sdBuffer+(usTemp<<2)) = currentCluster;	//Fill FAT
		if(sdWriteData(currentSector<<9))								//Write FAT 1
			return FATERR_NOCARD;
		if(sdWriteData((currentSector+sectorsPerFAT)<<9))				//Write FAT 2
			return FATERR_NOCARD;
	}
	return FATERR_NOERR;
}

unsigned char fatDirReset()			//reset fileDirSector & fileDirIndex;
{
	if(partitionType==1)
		fileDirSector = fatBeginSector+sectorsPerFAT*2;
	else
		fileDirSector = clusterBeginSector+dirBeginCluster*sectorsPerCluster;
	
	fileDirIndex = 0;

	if(sdReadData(fileDirSector<<9))
		return FATERR_NOCARD;
	return 0;
}

unsigned char fatDirNext()			//reset fileDirSector & fileDirIndex;	
{									//Return 0 for OK, 1 for Error; When reach end fileDirIndex = 0xFFFF;
	unsigned long ulTemp;
	unsigned long dirCluster;
	unsigned short dirSectorInCluster;

	fileDirIndex++;
	if(fileDirIndex>=16)			
	{	//Switch to nextSector
		fileDirIndex = 0;
		fileDirSector++;
		//Check if reach the end or go to next cluster
		if(partitionType==1)			//FAT16
		{
			ulTemp = fileDirSector-(fatBeginSector+sectorsPerFAT*2);
			if( (ulTemp<<4)+fileDirIndex>=dirEntries)
			{
				fileDirIndex = 0xFFFF;
				return 0;				//reached the end of ROOT
			}
		}
		else							//FAT32
		{
			//1. Count the number of the cluster
			ulTemp = fileDirSector-clusterBeginSector;
			dirCluster = ulTemp/sectorsPerCluster;
			dirSectorInCluster = ulTemp-dirCluster*sectorsPerCluster;
			if(dirSectorInCluster==0)	//just step into the next cluster
			{
				dirCluster--;			//return to the origin cluster
				//2. Read the next cluster of dirCluster;
				if(sdReadData((fatBeginSector+(dirCluster>>7))<<9))
					return FATERR_NOCARD;
				dirCluster = *( (unsigned long*)(sdBuffer)+(dirCluster&0x7F) );
				//3. Reach the end?
				if(dirCluster>=0x0FFFFFF7)
				{
					fileDirIndex = 0xFFFF;
					return 0;				//reached the end of ROOT
				}
				//4. Calculate & Load the Sector
				fileDirSector = clusterBeginSector+dirCluster*sectorsPerCluster;
			}//if just step into next cluster
		}//if partitionType
		if(sdReadData(fileDirSector<<9))
			return FATERR_NOCARD;
	}//if switched to next sector
	return 0;
}

unsigned char fileWriteEOF()
{
	unsigned char ucTemp;
	unsigned short usTemp;
	//3. write FAT chain end token
	ucTemp = fatWriteFAT(fileCurrentCluster,0x0FFFFFFF);
	if(ucTemp)
		return ucTemp;
	//4. write fileSize
	//4.1 Read the dir entry sector
	if(sdReadData(fileDirSector<<9))
		return FATERR_NOCARD;
	//4.2 fill file size
	usTemp = fileDirIndex<<5;
	*(unsigned long*)(sdBuffer+usTemp+0x1C) = fileSize;
	//4.3 write back
	if(sdWriteData(fileDirSector<<9))
		return FATERR_NOCARD;
	return FATERR_NOERR;
}

unsigned char fatCreateNewDirCluster()
{
	unsigned long currentSector;
	unsigned long currentIndex;
	unsigned long emptyCluster = 0x0FFFFFFF;
	unsigned long currentCluster,nextCluster;
	unsigned char ucTemp;
	unsigned short usTemp;
	//1.Find an empty cluster 
	currentSector = 0;
	ucTemp = 0;//empty cluster not found
	while(currentSector<sectorsPerFAT)
	{
		if(sdReadData((fatBeginSector+currentSector)<<9))
			return FATERR_NOCARD;
		for(currentIndex=0;currentIndex<128;currentIndex++)
			if( !*((unsigned long*)sdBuffer+currentIndex) )
			{
				emptyCluster = (currentSector<<7)+currentIndex;
				ucTemp = 1;
				break;
			}
		if(ucTemp)
			break;
		currentSector++;
	}
	if(emptyCluster>0x0FFFFFF7)
		return FATERR_DISKFULL;
	//2.Goto ROOT Cluster End
	currentCluster = dirBeginCluster;
	nextCluster = dirBeginCluster;
	while(nextCluster<=0x0FFFFFEF)
	{
		//goto next cluster
		currentCluster = nextCluster;
		// get next cluster
		currentSector = fatBeginSector+(currentCluster>>7);
		if(sdReadData( currentSector<<9 ))
			return FATERR_NOCARD;
		nextCluster = *((unsigned long*)sdBuffer+(currentCluster&0x7F));
	}
	//3.Fill in the cluster chain and the end token
	currentSector = fatBeginSector+(currentCluster>>7);		//Read FAT
	if(sdReadData(currentSector<<9))
		return FATERR_NOCARD;
	*(unsigned long*)(sdBuffer+((currentCluster&0x7F)<<2)) = emptyCluster;	//Fill FAT
	if(sdWriteData(currentSector<<9))								//Write FAT 1
		return FATERR_NOCARD;
	if(sdWriteData((currentSector+sectorsPerFAT)<<9))				//Write FAT 2
		return FATERR_NOCARD;
	
	currentSector = fatBeginSector+(emptyCluster>>7);		//Read FAT
	if(sdReadData(currentSector<<9))
		return FATERR_NOCARD;
	*(unsigned long*)(sdBuffer+((emptyCluster&0x7F)<<2)) = 0x0FFFFFFF;	//Fill FAT
	if(sdWriteData(currentSector<<9))								//Write FAT 1
		return FATERR_NOCARD;
	if(sdWriteData((currentSector+sectorsPerFAT)<<9))				//Write FAT 2
		return FATERR_NOCARD;
	
	ucTemp = fatNextEmptyCluster();				//After occupied the cluster
	if(ucTemp)									//let fileCurrentCluster
		return ucTemp;							//move to next
	
	//4.Calculate the fileDirSector and fileDirIndex
	fileDirSector = clusterBeginSector+emptyCluster*sectorsPerCluster;
	fileDirIndex = 0;	
	//5.Write the Root DIR end token to buffer
	for(usTemp=0;usTemp<512;usTemp++)
		sdBuffer[usTemp] = 0;
	//6.Clear the new DIR cluster
	for(currentSector=0;currentSector<sectorsPerCluster;currentSector++)
		if(sdWriteData((fileDirSector+currentSector)<<9))								//Write FAT 1
			return FATERR_NOCARD;
	return FATERR_NOERR;
}





⌨️ 快捷键说明

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