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

📄 fat.c

📁 avr+TFT+SD卡实现数码相框功能
💻 C
字号:
//*****************************************************************************
//
// File Name	: 'fat.c'
// Title		: FAT32 File System
// Author		: Andy Zhu - Copyright (C) 2008.7
// Created		: 2008.07.20
// Revised		: 2008.07.20
// Version		: 0.1
// Target MCU	: Atmel AVR mega128
//
//*****************************************************************************
#include <avr/io.h>
#include <util/delay.h>
#include "sd.h"
#include "fat.h"
//-----------------------------------------------------------------------------
/******************************************************************************
* 名    称: Look_for_DBR(void)
* 功    能: 根据MBR信息得到启动扇区(DBR)的扇区号
* 参    数: 无
* 返 回 值: 启动扇区(DBR)的扇区号
* 备    注: 
*******************************************************************************/
unsigned long int Look_for_DBR(void)
{
	unsigned char buffer[512];
	unsigned long int DBR_block = 0;
	SD_ReadSingleBlock(0,buffer);	//read MBR
	if ((buffer[510] == 0x55) && (buffer[511] == 0xAA))	//判断是否是有效的扇区
	{
		/*********read the offset of DBR sector*********/
		DBR_block = buffer[0x1c9];
		DBR_block <<= 8;
		DBR_block |= buffer[0x1c8];
		DBR_block <<= 8;
		DBR_block |= buffer[0x1c7];
		DBR_block <<= 8;
		DBR_block |= buffer[0x1c6];
	}
	else
	{
		DBR_block = 0;
	}
	return DBR_block;
}
/******************************************************************************
* 名    称: Get_FAT_BPB_Infor(void)
* 功    能: 读取启动扇区上的相关信息
* 参    数: 无
* 返 回 值: 启动扇区(DBR)的扇区号
* 备    注: 
*******************************************************************************/
void Get_FAT_BPB_Infor(void)
{
	unsigned char buf[512];
	FirstSecNum = Look_for_DBR();		//look for logic block 0
	SD_ReadSingleBlock(FirstSecNum,buf);	//DBR(DOS BOOT RECORD)
	//-----------每扇区字节数,offset 0x0B,一般512字节---
	FAT32_BPB_infor.BPB_BytesPerSec = buf[0x0b+1];
	FAT32_BPB_infor.BPB_BytesPerSec <<= 8;
	FAT32_BPB_infor.BPB_BytesPerSec |= buf[0x0b];
	//-----------每簇扇区数,offset 0x0D--------------------
	FAT32_BPB_infor.BPB_SecPerClus = buf[0x0d];
	//-----------保留扇区数,offset 0x0E----------------
	FAT32_BPB_infor.BPB_ResSec = buf[0x0F];
	FAT32_BPB_infor.BPB_ResSec <<= 8;
	FAT32_BPB_infor.BPB_ResSec |= buf[0x0E];
	//-----------该分区上FAT的副本数,offset 0x10-------------------
	FAT32_BPB_infor.BPB_NumOfFAT = buf[0x10];
	//-----每FAT扇区数(只被FAT32使用)该分区每个FAT所占的扇区数。offset 0x24-----------
	FAT32_BPB_infor.BPB_SecPerFAT = buf[0x24+3];
	FAT32_BPB_infor.BPB_SecPerFAT <<= 8;
	FAT32_BPB_infor.BPB_SecPerFAT |= buf[0x24+2];
	FAT32_BPB_infor.BPB_SecPerFAT <<= 8;
	FAT32_BPB_infor.BPB_SecPerFAT |= buf[0x24+1];
	FAT32_BPB_infor.BPB_SecPerFAT <<= 8;
	FAT32_BPB_infor.BPB_SecPerFAT |= buf[0x24];
}
//----------------------------------------------------------------------------
/*****************************************************************************
* 名    称: GetFileInfor(unsigned char *DIR_BUF,DIR_SHORT_STR *pDIR)
* 功    能: 得到短文件名的相关信息
* 参    数: unsigned char *DIR_BUF--->指向短文件32个字节信息首地址的指针
			DIR_SHORT_STR *pDIR   --->指向目标短文件信息结构的指针
* 返 回 值: 无
* 备    注: 
*******************************************************************************/
void GetFileInfor(unsigned char *DIR_BUF,DIR_SHORT_STR *pDIR)
{
	unsigned char i;
	/*
	//----------文件名----offset:0x00---------
	for (i=0; i<8; i++)
	{
		pDIR->DIR_Name[i] = *DIR_BUF++;
	}
	//----------扩展名----offset:0x08------
	for (i=0; i<3; i++)
	{
		pDIR->DIR_ExtName[i] = *DIR_BUF++;
	}
	*/
	//-------------文件全名-------------------
	for (i=0; i<11; i++)
	{
		pDIR->DIR_FullName[i] = *DIR_BUF++;
	}
	//----------文件属性---offset:0x0B-----
	pDIR->DIR_Attr = *DIR_BUF++;
	//----------系统保留----offset:0x0c----
	pDIR->DIR_NTRes = *DIR_BUF++;
	//-----------创建时间的10毫秒位-----offset:0x0d--------
	pDIR->DIR_CrtTimeTenth = *DIR_BUF;
	//-----------文件创建时间-----offset:0x0e--------
	DIR_BUF += 2;
	pDIR->DIR_CrtTime = *DIR_BUF;
	pDIR->DIR_CrtTime <<= 8;
	DIR_BUF--;
	pDIR->DIR_CrtTime |= *DIR_BUF;
	//----------文件创建日期-----offset:0x10--------
	DIR_BUF += 3;
	pDIR->DIR_CrtDate = *DIR_BUF;
	pDIR->DIR_CrtDate <<= 8;
	DIR_BUF--;
	pDIR->DIR_CrtDate |= *DIR_BUF;
	//----------文件最后访问日期----offset:0x12---------
	DIR_BUF += 3;
	pDIR->DIR_LstAccDate = *DIR_BUF;
	pDIR->DIR_LstAccDate <<= 8;
	DIR_BUF--;
	pDIR->DIR_LstAccDate |= *DIR_BUF;
	//-----------文件的最近修改时间----offset:0x16-------
	DIR_BUF += 5;
	pDIR->DIR_WrtTime = *DIR_BUF;
	pDIR->DIR_WrtTime <<= 8;
	DIR_BUF--;
	pDIR->DIR_WrtTime |= *DIR_BUF;
	//-----------文件的最近修改日期-----offset:0x18------
	DIR_BUF += 3;
	pDIR->DIR_WrtDate = *DIR_BUF;
	pDIR->DIR_WrtDate <<= 8;
	DIR_BUF--;
	pDIR->DIR_WrtDate |= *DIR_BUF;
	//-----------文件的长度-------offset:0x1C----
	DIR_BUF += 7;
	pDIR->DIR_FileSize = *DIR_BUF--;
	pDIR->DIR_FileSize <<= 8;
	pDIR->DIR_FileSize |= *DIR_BUF--;
	pDIR->DIR_FileSize <<= 8;
	pDIR->DIR_FileSize |= *DIR_BUF--;
	pDIR->DIR_FileSize <<= 8;
	pDIR->DIR_FileSize |= *DIR_BUF;
	//-----------文件起始簇号---offset:0x14 & offset:0x1A--------
	DIR_BUF -= 7;
	pDIR->DIR_FstClus = *DIR_BUF--;
	pDIR->DIR_FstClus <<= 8;
	pDIR->DIR_FstClus |= *DIR_BUF;
	pDIR->DIR_FstClus <<= 8;
	DIR_BUF += 7;
	pDIR->DIR_FstClus |= *DIR_BUF--;
	pDIR->DIR_FstClus <<= 8;
	pDIR->DIR_FstClus |= *DIR_BUF;
}
//--------------------------------------------------
/*****************************************************************************
* 名    称: Calculate_FirstRootDirSecNum
* 功    能: 得到根目录的扇区号
* 参    数: 
* 返 回 值: 根目录扇区号
* 备    注: 
*******************************************************************************/
unsigned long int Calculate_FirstRootDirSecNum(void)
{
	unsigned long int temp;
	temp = FirstSecNum + FAT32_BPB_infor.BPB_ResSec + \
	FAT32_BPB_infor.BPB_NumOfFAT*FAT32_BPB_infor.BPB_SecPerFAT;
	return temp;
}
//--------------------------------------------------
/*****************************************************************************
* 名    称: FAT_Get_File_FirCluNum
* 功    能: 得到指定文件的首簇号
* 参    数: unsigned char *pFileDir--->文件的路径,例如"\\PICTURE\\PIC1.BIN"
			DIR_SHORT_STR *pDIR   --->指向目标短文件信息结构的指针
* 返 回 值: 目标文件的首簇号
* 备    注: 
*******************************************************************************/
unsigned long int FAT_Get_File_FirCluNum( char *pFileDir)
{
	volatile unsigned char j,k;
	volatile unsigned int s,i;
	volatile char *p = pFileDir;
	volatile unsigned char depth = 0;
	volatile unsigned char Cluster_changed;
	unsigned char BUF[512];
	char Name_buf[11];
	volatile unsigned long int TagFileSec;
	FirstRootDirSecNum = Calculate_FirstRootDirSecNum();	//首先指定到根目录下
	TagFileSec = FirstRootDirSecNum;
	while (*p)
	{
		if(*p == '\\')
		{
			depth++;
		}
		p++;
	}
	p = pFileDir;	//---"\\PICTURE\\PIC1.BIN"
	for (j=0; j<depth; j++)
	{
		p++;
		for (i=0; i<11; i++)	//---得到整个文件的11字节名称
		{
			if ((*p == '.')&&(i==8)) 
			{
				p++;
				i--;
				continue;	//去除文件的点号
			}
			if ((*p == '.')&&(i<8))
			{
				Name_buf[i] = 0X20;
			}
			else if (*p == '\\')
				Name_buf[i] = 0X20;
			else if (*p == '\0')
				Name_buf[i] = 0X20;
			else
				Name_buf[i] = *p++;
		}
		Cluster_changed = 0;
		for (k=0; k<FAT32_BPB_infor.BPB_SecPerClus; k++)//在一簇里查找
		{
			SD_ReadSingleBlock(TagFileSec++,BUF);	//读取一个扇区
			//---读取一个文件的相关信息------
			for (i=0,s=(i<<5); i<16; i++,s=(i<<5))	//16x32=512
			{
				if (BUF[s] == 0x00)	//文件目录结束
					return 0;			//没有找到文件则返回0
				if ((BUF[s] == 0xe5)||(BUF[s] == 0x05))
					continue;	//文件已经被删除,继续读取下一个文件目录信息
				if ((BUF[s+0x0b] == 0x08)||(BUF[s+0x0b] == 0x0f))
					continue;	//卷名或长文件名
				if ((depth == 1)&&(BUF[s+8] == 0x20))
					continue;	//查找的文件在根目录下,则为目录文件(没有扩展名)的直接放弃
				//else if ((depth > 1)&&(BUF[s+8] != 0x20))
				//	continue;	//查找的文件不在根目录下,则根目录下的文件(有扩展名)则放弃
				GetFileInfor(&BUF[s],&FAT32_DIR_infor);	//读取文件的相关信息
				if (FileNameMatch(Name_buf,(char*)FAT32_DIR_infor.DIR_FullName))	//名字匹配
				{
					if (j == depth-1)	//已经是最后层目录
						return (FAT32_DIR_infor.DIR_FstClus);
					else
					{
						TagFileSec = (FAT32_DIR_infor.DIR_FstClus - 2)*FAT32_BPB_infor.BPB_SecPerClus+FirstRootDirSecNum;
						Cluster_changed = 1;
						break;
					}
				}
			}
			if (Cluster_changed)
				break;
		}

	}
	//--------------------------------------
	
	return 0;
}
//--------------------------------------------------
unsigned char FileNameMatch(char *TagName,char *FileName)
{
	unsigned char m;
	for (m=0; m<11; m++)
	{
		if (*(TagName+m)!=*(FileName+m))
			return 0;	//名字不匹配,返回0
	}
	return 1;	//名字匹配,返回1
}

//--------------------------------------------------


⌨️ 快捷键说明

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