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

📄 fat.c

📁 加速度采集器。基于ATMega16L.AVRSTUIDIO4
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "fat.h"
#include <string.h>

extern unsigned char sdBuffer[512];

//===========Data========================
//-----------SYSTEM-------------
unsigned char partitionType;//1=fat16,2=fat32
//unsigned long patitionBegin;
unsigned long fatBeginSector;
unsigned long dirBeginCluster;
unsigned long clusterBeginSector;
unsigned short dirEntries;
unsigned long sectorsPerFAT;
unsigned char sectorsPerCluster;


//-------------File-------------
unsigned long fileCurrentCluster;
unsigned long fileDirSector;
unsigned short fileDirIndex;
unsigned char fileCurrentSectorInCluster;
unsigned long fileSize = 0;



//=========Functions======================
unsigned char fatInit()
{
	unsigned char  tempChar;
	unsigned short *pShort;
	unsigned long partitionFirstSector;
	unsigned short numReservedSectors;
	//1. Init SD CARD
	if(sdInitCard())
		return FATERR_NOCARD;
	
	//2. Read MBR (master boot record)
	//2.1 Read the first sector of SD card
	if(sdReadData(0))
		return FATERR_NOCARD;
	//2.2 check MBR/BPB validity
	if(sdBuffer[510]!=0x55 || sdBuffer[511]!=0xAA)
		return FATERR_UNFORMATTED;
	//2.3 whether the first sector is MBR or BPB(boot sector)
	if(strncmp(sdBuffer+0x36,"FAT16",5)==0)	//BPB && FAT16
	{
		partitionType = 1;
		partitionFirstSector = 0;
	}
	else if (strncmp(sdBuffer+0x52,"FAT32",5)==0)
	{
		partitionType = 2;
		partitionFirstSector = 0;
	}
	else	//MBR
	{
		tempChar = sdBuffer[(0x1BE)+(0x04)];
		switch(tempChar)
		{
			case 0x0B:
			case 0x0C:	//FAT32
				partitionType = 2;
				break;
			case 0x04:
			case 0x06:
			case 0x0E:
				partitionType = 1;
				break;
			default:
				return FATERR_UNFORMATTED;
		}
		partitionFirstSector = *((unsigned long*)(sdBuffer+((0x1BE)+(0x08))));
	}
	
	//3. Read BPB (volume ID / Boot Record)
	if(sdReadData(partitionFirstSector<<9))
		return FATERR_NOCARD;
	if(sdBuffer[510]!=0x55 || sdBuffer[511]!=0xAA)	//Check signature
		return FATERR_UNFORMATTED;
	if(sdBuffer[0x10]!=2)							//Check number of FAT==2
		return FATERR_UNFORMATTED;
	pShort = (unsigned short*)(sdBuffer+0x0B);
	if((*pShort)!=(unsigned short)512)								//Check Bytes Per Sector ==512
		return FATERR_UNFORMATTED;
	
	sectorsPerCluster = sdBuffer[0x0D];
	numReservedSectors = *((unsigned short*)(sdBuffer+0x0E));
	if(partitionType == 1)//FAT16
		sectorsPerFAT = *((unsigned short*)(sdBuffer+0x16));
	else
		sectorsPerFAT = *((unsigned long*)(sdBuffer+0x24));
	fatBeginSector = partitionFirstSector+numReservedSectors;
	if (partitionType==2)//FAT32
		dirBeginCluster = *((unsigned long*)(sdBuffer+0x2C));
	else
	{
		dirBeginCluster = 0;
		dirEntries = *((unsigned short*)(sdBuffer+0x11));
	}
	if(partitionType==1)
		clusterBeginSector = partitionFirstSector+numReservedSectors+sectorsPerFAT*2+(dirEntries>>4)-sectorsPerCluster*2;
	else
		clusterBeginSector = partitionFirstSector+numReservedSectors+sectorsPerFAT*2-sectorsPerCluster*2;

	return FATERR_NOERR;
}


unsigned char fileCreateSequential(const char filenamePrefix[], unsigned char fileIndexLength, const char filenameExt[])
{
	unsigned short usTemp;
	unsigned long ulTemp,ulTemp1;
	unsigned char ucTemp;
	unsigned char *pucTemp;

	unsigned long fileIndexSearch = 0;
	unsigned long fileIndexMax = 1;
	unsigned char currentFilename[11];
	unsigned char fileIndexUsed = 0;


//	unsigned long fileDirSector;	
//	unsigned long dirSearchCluster;	
//	unsigned char fileDirIndex;
	unsigned char dirFound = 0;

	//1. Search an empty cluster
	fileCurrentCluster = 0;				//Reset current cluster
	ucTemp = fatNextEmptyCluster();
	if(ucTemp)
		return ucTemp;
	fileCurrentSectorInCluster = 0;


	//2. Search an available filename
	for(usTemp=0;usTemp<fileIndexLength;usTemp++)
		fileIndexMax *= 10;
	fileIndexMax -= 1;
		//generate fixed part of filename
	for(usTemp=0;usTemp<8-fileIndexLength;usTemp++)
		currentFilename[usTemp]=filenamePrefix[usTemp];
	for(usTemp=0;usTemp<3;usTemp++)
		currentFilename[usTemp+8]=filenameExt[usTemp];

	for(fileIndexSearch=0;fileIndexSearch<fileIndexMax;fileIndexSearch++)
	{
		fileIndexUsed = 0;
		//2.1 Generate the filename
		ulTemp = fileIndexSearch;
		for(ucTemp=0;ucTemp<fileIndexLength;ucTemp++)
		{
			ulTemp1 = ulTemp/10;
			currentFilename[7-ucTemp] = ulTemp-ulTemp1*10+48;
			ulTemp = ulTemp1;
		}
	
		//2.1 Go to the first DIR entry
		ucTemp = fatDirReset();
		if(ucTemp) return ucTemp;
		//2.2 search the DIR
		while(fileDirIndex<=17)			//fileDirIndex =0xFFFF when reach the end
		{
			//Lower to upper case
			pucTemp = sdBuffer+(fileDirIndex<<5);
			for(ucTemp=0;ucTemp<11;ucTemp++)
			{
				if(*pucTemp>='a' && *pucTemp<='z')
					*pucTemp -= 'a'-'A';
				pucTemp++;
			}
			if(!strncmp (currentFilename,sdBuffer+(fileDirIndex<<5),11))
			{
				fileIndexUsed = 1;
				break;
			}
			//Switch to next sector
			ucTemp = fatDirNext();
			if(ucTemp)
				return ucTemp;
		}//while search DIR
		if(!fileIndexUsed)
			break;	// A valid file index found!!!
	}//for (file index)
	if(fileIndexUsed)
		return FATERR_FILEINDEXFULL;


	//3. search an empty DIR entry
	ucTemp = fatDirReset();
	if(ucTemp) return ucTemp;
	//3.2 search the DIR
	dirFound = 0;
	while(fileDirIndex<=17)			//fileDirIndex =0xFFFF when reach the end
	{
		//search current entry
		if ((sdBuffer[fileDirIndex<<5]==0xe5 && (sdBuffer[(fileDirIndex<<5)+0x0B]&0x0f)!=0x0f) 
		  || sdBuffer[fileDirIndex<<5]==0x00)
		{
			dirFound = 1;
			break;
		}
		if(dirFound) break;				//empty entry found
		//Switch to next sector
		ucTemp = fatDirNext();
		if(ucTemp)
				return ucTemp;
	}//while search DIR
	if(!dirFound && partitionType==1)
		return FATERR_ROOTFULL;
	if(!dirFound && partitionType==2)
	{
		ucTemp = fatCreateNewDirCluster();
		if(ucTemp)
			return ucTemp;
	}
	
	//4. Fill in the DIR entry
	usTemp = fileDirIndex<<5;
	//4.1 fill filename
	strncpy(sdBuffer+usTemp,currentFilename,11);
	//4.2 fill attribute
	sdBuffer[usTemp+0x0B] = 0x00;
	//4.3 fill Cluster
	if(partitionType==1)	//FAT16
		*(unsigned short*)(sdBuffer+usTemp+0x1A) = fileCurrentCluster;
	else					//FAT32
	{
		*(unsigned short*)(sdBuffer+usTemp+0x14) = fileCurrentCluster>>16;
		*(unsigned short*)(sdBuffer+usTemp+0x1A) = fileCurrentCluster&0xFFFF;
	}
	//4.4 fill Time Date
	*(unsigned short*)(sdBuffer+usTemp+0x0E) = 0;
	*(unsigned short*)(sdBuffer+usTemp+0x10) = 0;
	*(unsigned short*)(sdBuffer+usTemp+0x12) = 0;
	*(unsigned short*)(sdBuffer+usTemp+0x16) = 0;
	*(unsigned short*)(sdBuffer+usTemp+0x18) = 0;
	//4.5 fill file size
	fileSize = 0;
	*(unsigned long*)(sdBuffer+usTemp+0x1C) = fileSize;
	//4.6 write back
	if(sdWriteData(fileDirSector<<9))
		return FATERR_NOCARD;
	return FATERR_NOERR;
}


unsigned char fileWriteBuffer()
{
	unsigned char ucTemp;
	unsigned long filePreviourCluster;
	unsigned long currentSector;
	//1. write buffer to current sector
	currentSector = clusterBeginSector;
	currentSector += fileCurrentCluster*sectorsPerCluster;
	currentSector += fileCurrentSectorInCluster;
	if(sdWriteData(currentSector<<9))
		return FATERR_NOCARD;
	fileSize += 512;
	//2. step to next sector
	fileCurrentSectorInCluster++;

	//3. if cluster full switch to next cluster
	if(fileCurrentSectorInCluster>=sectorsPerCluster)
	{
	//3.1 find next empty cluster
		filePreviourCluster = fileCurrentCluster;
		ucTemp = fatNextEmptyCluster();
		if(ucTemp)
		{
			if(ucTemp==FATERR_DISKFULL)
				fileWriteEOF();
			return ucTemp;
		}
	//3.2 write 2 FAT
		ucTemp = fatWriteFAT(filePreviourCluster,fileCurrentCluster);
		if(ucTemp)
			return ucTemp;
	//3.3 fileCurrentSectorInCluster=0
		fileCurrentSectorInCluster = 0;
	}
	return FATERR_NOERR;

⌨️ 快捷键说明

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