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

📄 fat.c

📁 用串口来显示和操作的基于ucos的以sd卡为存储介质的mp3源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define IN_FAT
#include "User.h"
#include "UNICODE.H"

#define MAX_DIR_NU_List 32
#define MAX_CACHE_SIZE 544

ShortFileDirTab *pF;
extern INT8U MP3Handle;

struct QueueDL
{
	ShortFileDirTab SFDT[MAX_DIR_NU_List];
	INT8U front,frontE,rear,len,lenE,MaxSize;
	INT8U  ListNu;
}QuDirList;

struct QueueDC
{
	INT8U Buf[MAX_CACHE_SIZE];
	INT16U front,rear,len;
	INT16U MaxSize;
}Disk_Cache;

extern Disk_Info * GetDiskInfo(INT8U DriveID);

void IintQueueDL(struct QueueDL *Q)
{
	INT8U i;
	
	Q->front 	= 0;
	Q->frontE 	= 0;
	Q->rear 	= 0;
	Q->len 		= 0;
	Q->lenE		= 0;
	Q->ListNu	= 0;
	Q->MaxSize 	= MAX_DIR_NU_List - 2;
	for(i=0; i<MAX_DIR_NU_List; i++)
	{
		Q->SFDT[i].FDP.Len		= 0;
		Q->SFDT[i].FDP.OfClu	= 0;
		Q->SFDT[i].FDP.OfSec	= 0;
		Q->SFDT[i].FDP.OfByte	= 0;
	}
}

void EnQueueDL(struct QueueDL *Q, ShortFileDirTab *x)
{//向队列插入元素
	
	INT8U i;
	
	if((Q->rear  == Q->frontE) && Q->lenE != 0)
	{//队列满时将产生覆盖
		Q->frontE = (Q->frontE + 1) % Q->MaxSize; //使队首元素指向下一个位置
	}
	for(i=0; i<11; i++)
	{
		Q->SFDT[Q->rear].SName[i] = x->SName[i];
	}
	Q->SFDT[Q->rear].Attr 		= x->Attr;
	Q->SFDT[Q->rear].FstClu 	= x->FstClu; 
	Q->SFDT[Q->rear].FileSize 	= x->FileSize;
	Q->SFDT[Q->rear].FDP.OfClu 	= x->FstClu;
	Q->rear = (Q->rear + 1) % Q->MaxSize;//求出新队尾
	if(Q->len < Q->MaxSize)
		Q->len += 1;//队列长度加1
	if(Q->lenE < Q->MaxSize)
		Q->lenE += 1;
}

ShortFileDirTab * PeekQueueDL(struct QueueDL *Q)
{//取出队首元素

	ShortFileDirTab *pSFDT;
	
	pSFDT = &Q->SFDT[Q->front];
	Q->front = (Q->front + 1) % Q->MaxSize;//求出新队首位置
	if(Q->len >0)
		Q->len -= 1;//队列长度-1
	return(pSFDT);
}

ShortFileDirTab * GetElemQDL(struct QueueDL *Q,INT8U pos)
{//读取POS位置的元素
	
	if((pos < 1) || (pos > Q->lenE))
	{
		return(NULL);
	}
	return(&Q->SFDT[(Q->frontE + pos - 1) % Q->MaxSize]);
}

INT8U GetSizeQDL(struct QueueDL *Q)
{
	if(Q != NULL)
		return(Q->len);
	else
		return 0;
}

void InitQueueDC(struct QueueDC *Q)
{
	Q->front 	= 0;
	Q->rear 	= 0;
	Q->len 		= 0;
	Q->MaxSize 	= 544;
}

INT16U GetSizeDC(struct QueueDC *Q)
{
	if(Q != NULL)
		return(Q->len);
	else
		return 0;
}

void EnQueueDC(struct QueueDC *Q,INT8U x)
{//不考虑队列满的情况,实际使用中不出现这种情况
	
	Q->Buf[Q->rear] = x;//新值赋给队尾
	Q->rear = (Q->rear + 1) % Q->MaxSize;//求出队尾的下一个位置
	if(Q->len < Q->MaxSize)
		Q->len += 1;//队列长度+1
}

INT8U PeekQueueDC(struct QueueDC *Q)
{//取出队首元素

	INT8U temp;
	if(Q->len == 0)
	{
		return 0;
	}
	temp = Q->Buf[Q->front];
	Q->front = (Q->front + 1) % Q->MaxSize;//求出新队首位置
	if(Q->len >0)
		Q->len -= 1;//队列长度-1
	return(temp);
}

void Uincode_to_GB(INT16U * x)
{//UNICODE码转换为GB2313汉字编码

 	INT16U a,b,c;
 	if(((*x) >= 0x0020) && ((*x) <= 0x007E))
 	{
 		if((*x) >= 'a' && (*x) <= 'z')
 		(*x)-='a'-'A';
 		*x+=0xA380;
 		return;
 	}
 	if((*x)<Unicode[0][0])
 	{
 		*x=0x3F3F;
 		return;
 	}
 	if((*x)>Unicode[UNICODE_MAX-1][0])
 	{
 		*x=0x3F3F;
 		return;
 	}
 	a=0;
 	b=UNICODE_MAX-1;
 	do        //采用二分查表法,因为该表为顺序表
 	{
   		c=(a+b)/2;
   		if((*x)==Unicode[c][0])
   		{
   			*x=Unicode[c][1];
   			return;
   		}
   		if((*x)<Unicode[c][0])
   		{
   			b=(a+b)/2;
   		}
   		else 
   		{
   			a=(a+b+1)/2;
   		}
 	} while(a!=b);
 	if((*x)==Unicode[a][0])
 	{
 		*x=Unicode[a][1];
 		return;
 	}
 	*x=0x3F3F;  //如果找不到,则显示??
}

ShortFileDirTab * OpenFile(INT8U DirListIndex)
{
	ShortFileDirTab *pSFDT;
	
	pSFDT = GetElemQDL(&QuDirList, DirListIndex);
	return pSFDT;
}

INT8U CloseFile(ShortFileDirTab **ppSFDT)
{
	if(*ppSFDT == NULL)
		return 1;
	(*ppSFDT)->FDP.Len 		= 0; 
	(*ppSFDT)->FDP.OfClu 	= (*ppSFDT)->FstClu;
	(*ppSFDT)->FDP.OfSec 	= 0; 
	(*ppSFDT)->FDP.OfByte 	= 0;
	*ppSFDT = NULL;
	return 0;
}

void PrintDir(void)
{
	INT8U i,j,tempa,tempb,tempc,len;
	ShortFileDirTab *pSFDT;
	
	len = GetSizeQDL(& QuDirList);
	for(i=0; i<len; i++)
	{
		QuDirList.ListNu += 1;
		tempa = QuDirList.ListNu / 100 + 48;
		if(tempa > 48)
			UartPutchar(tempa);
		else
			UartPutchar(' ');
		tempb = QuDirList.ListNu % 100;
		tempc = tempb % 10 + 48;
		tempb = tempb / 10 + 48;
		if(tempa > 48 || tempb > 48)
			UartPutchar(tempb);
		else
			UartPutchar(' ');
		UartPutchar(tempc);
		UartPutchar('-');
		pSFDT = PeekQueueDL(&QuDirList);
		for(j=0; j<11; j++)
		{
			if(j == 8)
			{
				if(pSFDT->SName[j] != ' ')
					UartPutchar('.');
			}
			if(pSFDT->SName[j] != ' ')
				UartPutchar(pSFDT->SName[j]);
		}
		UartPutchar('\n');
	}
}

INT32U GetNextClu(INT32U Index, INT8U DiskID)
{
	INT32U  FATOffset;
	INT32U  NextClu;                //下一个簇号
	INT32U  ThisFATSceNum;			//FAT表中包含该簇号N的扇区号
	INT16U  ThisFATEntOffset;		//该簇号N位于FAT表中FAT项的偏移量
	INT8U   Data_Buf[512];
	Disk_Info *pDI;
	Disk_RW_Parameter DP;
	
	pDI = GetDiskInfo(DiskID);
	switch(pDI->FilSysType)
	{
		case FAT16:
			FATOffset = Index * 2;
			ThisFATSceNum = FATOffset / pDI->BytsPerSec + pDI->RsvdSecCnt + pDI->RelaStaSect;
			DP.SectorIndex = ThisFATSceNum;
			DP.Buf = Data_Buf;
			(* pDI->DiskDrive)(ReadSec, &DP);
			ThisFATEntOffset = FATOffset % pDI->BytsPerSec;
			NextClu = (INT32U)Data_Buf[ThisFATEntOffset] | (INT32U)(Data_Buf[ThisFATEntOffset + 1] << 8);
	        break;
	    case FAT32:
	    	FATOffset = Index * 4;
			ThisFATSceNum = FATOffset / pDI->BytsPerSec + pDI->RsvdSecCnt + pDI->RelaStaSect;
			DP.SectorIndex = ThisFATSceNum;
			DP.Buf = Data_Buf;
			(* pDI->DiskDrive)(ReadSec, &DP);
			ThisFATEntOffset = FATOffset % pDI->BytsPerSec;
			NextClu = (INT32U)Data_Buf[ThisFATEntOffset] 			 | 
					  (INT32U)(Data_Buf[ThisFATEntOffset + 1] << 8)  |
					  (INT32U)(Data_Buf[ThisFATEntOffset + 2] << 16) |
					  (INT32U)(Data_Buf[ThisFATEntOffset + 3] << 24);
	    	break;
	}
	return(NextClu);
}


INT8U GetFDI(ShortFileDirTab *pSFDT, INT8U DiskID)
{
	INT8U   i,k,temp,flag;
	INT8U   Data_Buf[512];
	INT16U  j;
	INT32U  NextCluOfFAT;			//文件簇链中下一个簇号
	INT32U  FirstSectorOfCluster; 	//该簇号第一个扇区号
	INT32U  FistRootDirSecNum;		//根目录第一个扇区号
	Disk_Info *pDI;
	Disk_RW_Parameter DP;
	ShortFileDirTab SFDT;
	
    pDI = GetDiskInfo(DiskID);
    IintQueueDL(&QuDirList);
    if((pSFDT->Attr == 0xF0) && (pSFDT->FstClu == 0))
    {//该卷为FAT16且读的是根目录
    
    	FistRootDirSecNum = pDI->RsvdSecCnt + (pDI->NumFATs * pDI->FATSz16) + pDI->RelaStaSect;
    	FirstSectorOfCluster = FistRootDirSecNum;
    	flag = 1;
    }
	else
	{
		FirstSectorOfCluster = ((pSFDT->FstClu - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
		flag = 0;
	}
	DP.Buf = Data_Buf;
	DP.SectorIndex = FirstSectorOfCluster + pSFDT->FDP.OfSec;
	(* pDI->DiskDrive)(ReadSec, &DP);
    for(i=0; ; )
	{
		j = pSFDT->FDP.OfByte;
		SFDT.SName[0] = Data_Buf[j + OFSDIR_SName];
		SFDT.SName[1] = Data_Buf[j + OFSDIR_SName + 1];
		SFDT.Attr = Data_Buf[j + OFSDIR_Attr];
		if(((SFDT.Attr & ATTR_LONG_NAME_MASK) != ATTR_LONG_NAME) && (SFDT.SName[0] != 0xE5) && (SFDT.SName[0] != 0))
		{//找到一个活动的短目录项
		
			if((SFDT.Attr & ATTR_VOLUME) == 0)
			{//找到一个文件或子目录
			
				for(k=2; k<11; k++)
				{
					SFDT.SName[k] = Data_Buf[j + OFSDIR_SName + k];
	        	}
				SFDT.FstClu = ((INT32U)Data_Buf[j + OFSDIR_FstCluH + 1] << 24) | 

⌨️ 快捷键说明

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