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

📄 fat.c

📁 fat格式文件的读写操作
💻 C
字号:
/************************************************************/
/*		 SD Code for   AT91SAM7S64						*/
/*				By   pasyong								*/
/*					2006-5									*/
/*				Base IAR 4.30A						*/
/************************************************************/
#include <string.h>
#include "sd.h"
#include "fat.h"
#include "uart.h"
#include "3310.h"
extern uchar BUFFER[512];
unsigned char  LONGNAME_BUFFER_ADDR[30];
unsigned char  DIRNAME_BUFFER_ADDR[30];
 unsigned char *LongNameBuffer =		(unsigned char *) LONGNAME_BUFFER_ADDR;
unsigned char *DirNameBuffer =		(unsigned char *) DIRNAME_BUFFER_ADDR;
struct partrecord *PartInfo;
unsigned char Fat32Enabled;
unsigned long FirstDataSector;
unsigned int  BytesPerSector;
unsigned int  SectorsPerCluster;
unsigned long FirstFATSector;
unsigned long FirstDirSector;
unsigned long FileSize;
unsigned long FatInCache = 0;

//********************************************************************************************
//读一个扇区
void ReadBlock(unsigned long LBA)
//********************************************************************************************
{   unsigned long temp;
    temp=LBA<<9;
    SD_Read_Block(temp);
}
/*-----------------------------------------------------------------------
 查询数据区一个簇开始扇区号
-----------------------------------------------------------------------*/
unsigned long fatClustToSect(unsigned long clust)
{
	return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}
/*-----------------------------------------------------------------------
 查询一个簇所占扇区数
-----------------------------------------------------------------------*/
unsigned int fatClusterSize(void)
{
	// return the number of sectors in a disk cluster
	return SectorsPerCluster;
}
/*-----------------------------------------------------------------------
查询SD卡文件系统信息
-----------------------------------------------------------------------*/
unsigned char fatInit()
{       unsigned int data;unsigned char t1,t2;
        unsigned char PartType;
        unsigned long StartLBA,FATsecs,Size;
	//struct bpb710 *bpb;
	// 读MBR结构
	ReadBlock(0);
	// 读取分区表信息
	//PartInfo = ((struct partrecord *) ((struct partsector *)BUFFER)->psPart);
	// 读引导扇区
	// 引导扇区号在PartInfo.prStartLBA中
        PartType=BUFFER[450];
        Size=BUFFER[458]+(BUFFER[459]<<8)+(BUFFER[460]<<16)+(BUFFER[461]<<24);
        StartLBA=BUFFER[454]+(BUFFER[455]<<8)+(BUFFER[456]<<16)+(BUFFER[457]<<24);
        ReadBlock(StartLBA);  //FAT32时是99号扇区

        //bpb = (struct bpb710 *) ((struct bootsector710 *) BUFFER)->bsBPB;

	FirstDataSector=StartLBA;     //FirstDataSector	= PartInfo->prStartLBA;
	
        FATsecs=BUFFER[22]+(BUFFER[23]<<8);//bpb->bpbFATsecs
        if(FATsecs)//bpb->bpbFATsecs
	{
		// bpbFATsecs非0,为FAT16,FAT表所占的扇区数在bpbFATsecs里
	   FirstDataSector	+= BUFFER[14]+(BUFFER[15]<<8)+BUFFER[16]*FATsecs;
          //FirstDataSector	+= bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
	}
	else
	{
		// bpbFATsecs是0,为FAT32,FAT表所占的扇区数在bpbBigFATsecs里
	  FirstDataSector	+= BUFFER[14]+(BUFFER[15]<<8)+BUFFER[16]*(BUFFER[36]+(BUFFER[37]<<8)+(BUFFER[38]<<16)+(BUFFER[39]<<24));
          //FirstDataSector	+= bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
	}
	
	SectorsPerCluster	=BUFFER[13]; //bpb->bpbSecPerClust;
	BytesPerSector		=BUFFER[11]+(BUFFER[12]<<8); //bpb->bpbBytesPerSec;
	FirstFATSector		=BUFFER[14]+(BUFFER[15]<<8)+StartLBA; //bpb->bpbResSectors + PartInfo->prStartLBA;
//查询SD卡文件系统分区类型
	switch (PartType)//PartInfo->prPartType
	{
		case PART_TYPE_DOSFAT16:
		case PART_TYPE_FAT16:
		case PART_TYPE_FAT16LBA:
			// 第一个目录扇区号为2
			FirstDirSector	= CLUST_FIRST;
			//FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
			Fat32Enabled = 0;
			
			break;
		case PART_TYPE_FAT32LBA:
		case PART_TYPE_FAT32:
			
			FirstDirSector =BUFFER[44]+(BUFFER[45]<<8)+(BUFFER[46]<<16)+(BUFFER[47]<<24); //bpb->bpbRootClust;
			Fat32Enabled = 1;
			break;
		default:break;
			//return 1;
	}
//查询SD卡文件系统信息
	switch (PartType)
	{
		case PART_TYPE_DOSFAT16:
				LCD_write_english_string(0,0,"DOSFAT 16");
				break;
		case PART_TYPE_FAT16:
				LCD_write_english_string(0,0,"FAT16 ");
				break;
		case PART_TYPE_FAT16LBA:
				LCD_write_english_string(0,0,"FAT16 LBA");
				break;
		case PART_TYPE_FAT32LBA:
				LCD_write_english_string(0,0,"FAT32 LBA");
				break;
		case PART_TYPE_FAT32:
				LCD_write_english_string(0,0,"FAT32");
				break;
		default:
				LCD_write_english_string(0,0,"No Partition!");
				break;
	}
   //显示磁盘容量
  data=Size>>11;
    LCD_set_XY(56,0);
    t1=data/100;
	LCD_write_char(t1+48);
	data=data%100;
	t1=data/10;
	LCD_write_char(t1+48);
	t2=data%10;
	LCD_write_char(t2+48);
	LCD_write_english_string(76,0,"M");
    LCD_write_english_string(0,1,"RATE");
	
        return 0;	
}

/*-----------------------------------------------------------------------
查询一个文件的开始簇
-----------------------------------------------------------------------*/
unsigned long fatGetDirEntry(unsigned char entry)
{
        unsigned char offentry,offsetsector,n;
		unsigned long temp;
        offsetsector=entry/16;
        offentry=entry%16;
	// read dir data
        ReadBlock(fatClustToSect(FirstDirSector)+offsetsector);
		//for( w=0;w<512;w++)
		   //putchar(BUFFER[w]);
        n=offentry*32;
    temp=((unsigned long)BUFFER[26+n])+((unsigned long)BUFFER[27+n]<<8) +((unsigned long)BUFFER[20+n] << 16)+((unsigned long)BUFFER[21+n]<<24);
     //文件的起始簇地址
    if((BUFFER[0+n] == 0x00)||(BUFFER[0+n] == 0xE5))
    return 0;
    else
      return temp;
	
}



/*-----------------------------------------------------------------------
 在FAT表中查询下一个簇所在扇区号
-----------------------------------------------------------------------*/
unsigned long fatNextCluster(unsigned long cluster)
{
	unsigned long nextCluster;
	unsigned long fatMask;
	unsigned long fatOffset;
	unsigned long sector;
	unsigned int offset;
	
	if(Fat32Enabled)
	{
		// 一个表项为4bytes(32 bits)
		fatOffset = cluster << 2;
		// 设置 FAT32 bit mask
		fatMask = FAT32_MASK;
	}
	else
	{
		// 一个表项为2bytes(16 bits)
		fatOffset = cluster << 1;
		// 设置 FAT16 bit mask
		fatMask = FAT16_MASK;
	}
	
	//计算FAT扇区号
	sector = FirstFATSector + (fatOffset / BytesPerSector);
	//计算FAT扇区号中表项的偏移地址
	offset = fatOffset % BytesPerSector;

	ReadBlock(sector);

	// 读取下一个簇号
	nextCluster = (*((unsigned long*) &((char*)BUFFER)[offset])) & fatMask;

	// 是否文件的结束簇
	if (nextCluster == (CLUST_EOFE & fatMask))
		nextCluster = 0;
		
	return nextCluster;
}

⌨️ 快捷键说明

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