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

📄 fat.c

📁 用串口来显示和操作的基于ucos的以sd卡为存储介质的mp3源码
💻 C
📖 第 1 页 / 共 2 页
字号:
							  ((INT32U)Data_Buf[j + OFSDIR_FstCluH] << 16)     |
							  ((INT32U)Data_Buf[j + OFSDIR_FstCluL +1 ] << 8)  | 
							  ((INT32U)Data_Buf[j + OFSDIR_FstCluL]);
				SFDT.FileSize = ((INT32U)Data_Buf[j + OFSDIR_FileSize + 3] << 24) | 
							 	((INT32U)Data_Buf[j + OFSDIR_FileSize + 2] << 16) | 
								((INT32U)Data_Buf[j + OFSDIR_FileSize + 1] << 8)  | 
								((INT32U)Data_Buf[j + OFSDIR_FileSize]);
				if((SFDT.SName[0] == '.') && (SFDT.SName[1] == '.'))
				{//是dotdot目录(指向上级目录)
				
					for(k=2; k<11; k++)
					{
						QuDirList.SFDT[MAX_DIR_NU_List -1].SName[k] = SFDT.SName[k];
					}
					QuDirList.SFDT[MAX_DIR_NU_List -1].Attr = SFDT.Attr;
					QuDirList.SFDT[MAX_DIR_NU_List -1].FstClu = SFDT.FstClu;
					QuDirList.SFDT[MAX_DIR_NU_List -1].FileSize = SFDT.FileSize;
				}
				else if(SFDT.SName[0] == '.')
				{//是dot目录(指向该目录本身)
				
					for(k=2; k<11; k++)
					{
						QuDirList.SFDT[MAX_DIR_NU_List -2].SName[k] = SFDT.SName[k];
					}
					QuDirList.SFDT[MAX_DIR_NU_List -2].Attr = SFDT.Attr;
					QuDirList.SFDT[MAX_DIR_NU_List -2].FstClu = SFDT.FstClu;
					QuDirList.SFDT[MAX_DIR_NU_List -2].FileSize = SFDT.FileSize;
				}
				else
				{//是普通子目录或文件
				
					EnQueueDL(&QuDirList, &SFDT);
					i ++;
				}
			}
		}
		else if(SFDT.SName[0] == 0x00)
		{//此目录为空,并且后续的磁盘空间都为空
				
			pSFDT->FDP.OfClu = pSFDT->FstClu;
			pSFDT->FDP.Len = 0;
			pSFDT->FDP.OfByte = 0;
			PrintDir();
			return 0;
		}
		j += 32;
		if(j > (pDI->BytsPerSec - 32))
		{
			j = 0;
			pSFDT->FDP.OfSec += 1;
			if(flag == 0)
			{
				if(pSFDT->FDP.OfSec >= pDI->SecPerClus)
				{//读下一个簇
					pSFDT->FDP.OfSec = 0;
					pSFDT->FDP.OfClu = GetNextClu(pSFDT->FDP.OfClu, DiskID);
					NextCluOfFAT = pSFDT->FDP.OfClu;
					if(pDI->FilSysType == FAT16)
					{
						if((NextCluOfFAT >= 0x0002) && (NextCluOfFAT <= 0xFFEF))
						{
							FirstSectorOfCluster = ((NextCluOfFAT - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
						}
						else
						{//所有簇已读完
							
							pSFDT->FDP.OfClu = pSFDT->FstClu;
							pSFDT->FDP.Len = 0;
							pSFDT->FDP.OfSec = 0;
							pSFDT->FDP.OfByte = 0;
							return 0;
						}
					}
					else if(pDI->FilSysType == FAT32)
					{
						if((NextCluOfFAT >= 0x00000002) && (NextCluOfFAT <= 0xFFFFFFEF))
						{
							FirstSectorOfCluster = ((NextCluOfFAT - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
						}
						else
						{//所有簇已读完
							
							pSFDT->FDP.OfClu = pSFDT->FstClu;
							pSFDT->FDP.Len = 0;
							pSFDT->FDP.OfSec = 0;
							pSFDT->FDP.OfByte = 0;
							return 0;
						}
					}
				}
			}
			else if(flag == 1)
			{
				if(pSFDT->FDP.OfSec >= pDI->RootDirSectors)
				{//所有簇已读完
						
					pSFDT->FDP.OfClu = pSFDT->FstClu;
					pSFDT->FDP.Len = 0;
					pSFDT->FDP.OfSec = 0;
					pSFDT->FDP.OfByte = 0;
					return 0;
				}
			}
			DP.SectorIndex = FirstSectorOfCluster + pSFDT->FDP.OfSec;
			(* pDI->DiskDrive)(ReadSec, &DP);//读下一个扇区
		}
		pSFDT->FDP.OfByte = j;
		pSFDT->FDP.Len += 32; 
		temp = QuDirList.MaxSize - GetSizeQDL(&QuDirList);
		if(temp == 0)
		{
			PrintDir();
			i = 0;
		}
	}
}

INT8U ChangeDir(INT8U DirListIndex, INT8U DriveID)
{
	Disk_Info *pDI;
	ShortFileDirTab *pSFDT;
	
	pDI = GetDiskInfo(DriveID);
	switch(DirListIndex)
	{
		case '\\':
			if(pDI->FilSysType == FAT16)
			{
				QuDirList.SFDT[MAX_DIR_NU_List - 1].Attr = 0xF0;
				QuDirList.SFDT[MAX_DIR_NU_List - 1].FstClu = 0;
				QuDirList.SFDT[MAX_DIR_NU_List - 1].FileSize = 0;
				GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 1],DriveID); 
			}
			else if(pDI->FilSysType == FAT32)
			{
				QuDirList.SFDT[MAX_DIR_NU_List - 1].Attr = 0xF0;
				QuDirList.SFDT[MAX_DIR_NU_List - 1].FstClu = pDI->RootClus;
				QuDirList.SFDT[MAX_DIR_NU_List - 1].FileSize = 0;
				GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 1],DriveID);
			}
			break;
		case '*':
			GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 1], DriveID);
			break;
		case '.':
			GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 2], DriveID);
			break;
		default:
			pSFDT = GetElemQDL(&QuDirList, DirListIndex);
			GetFDI(pSFDT, DriveID);
	}
	return 0;
}

INT8U ReadFile(ShortFileDirTab *pSFDT, INT16U Len, INT8U DiskID)
{
	INT8U Data_Buf[512];
	INT16U i;
	INT32U  NextCluOfFAT;			//文件簇链中下一个簇号
	INT32U  FirstSectorOfCluster;   //该簇号第一个扇区号
	Disk_Info *pDI;
	Disk_RW_Parameter DP;
	
	if(Len > 512)
	{
		return PARAMETER_ERR;
	}
	pDI = GetDiskInfo(DiskID);
	DP.Buf = Data_Buf;
	if((pSFDT->FDP.Len + Len) <= pSFDT->FileSize)
	{
		DP.Len = Len;
	}
	else
	{
		DP.Len = pSFDT->FileSize - pSFDT->FDP.Len;
	}
	FirstSectorOfCluster = ((pSFDT->FDP.OfClu - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
	DP.SectorIndex = (FirstSectorOfCluster + pSFDT->FDP.OfSec) * 512 + pSFDT->FDP.OfByte;
	(* pDI->DiskDrive)(ReadBlock, &DP);
	pSFDT->FDP.Len = (pSFDT->FDP.Len + DP.Len) % pSFDT->FileSize;
	pSFDT->FDP.OfByte += Len;
	pSFDT->FDP.OfSec += pSFDT->FDP.OfByte / 512;
	pSFDT->FDP.OfByte %= 512;
	for(i=0; i<DP.Len; i++)
	{
		EnQueueDC(&Disk_Cache, Data_Buf[i]);
	}
	if(pSFDT->FDP.OfSec >= pDI->SecPerClus)
	{//取下一个簇号
		pSFDT->FDP.OfSec = 0;
		pSFDT->FDP.OfClu = GetNextClu(pSFDT->FDP.OfClu, DiskID);
		NextCluOfFAT = pSFDT->FDP.OfClu;
		if(pDI->FilSysType == FAT16)
		{
			if((NextCluOfFAT < 0x0002) || (NextCluOfFAT > 0xFFEF))
			{//所有簇已读完
							
				pSFDT->FDP.OfClu = pSFDT->FstClu;
				pSFDT->FDP.Len = pSFDT->FileSize;
				pSFDT->FDP.OfSec = 0;
				pSFDT->FDP.OfByte = 0;
				return FILE_EOF;
			}
		}
		else if(pDI->FilSysType == FAT32)
		{
			if((NextCluOfFAT < 0x00000002) || (NextCluOfFAT > 0xFFFFFFEF))
			{//所有簇已读完
							
				pSFDT->FDP.OfClu = pSFDT->FstClu;
				pSFDT->FDP.Len = pSFDT->FileSize;
				pSFDT->FDP.OfSec = 0;
				pSFDT->FDP.OfByte = 0;
				return FILE_EOF;
			}
		}
	}
	return 0;
}

INT32U GetFileSize(void)
{
	return pF->FileSize;
}

INT8U ReadFileByte(void)
{
	void FileOperation(INT8U List_NU);
	
	INT8U data;
	INT16U len;
	
	data = PeekQueueDC(&Disk_Cache);
	len = GetSizeDC(&Disk_Cache);
	if(len < 480)
		FileOperation('r');
	return data;
}

void FileOperation(INT8U List_NU)
{
	INT8U temp,j;
	//INT16U flen;
	
	switch(List_NU)
	{
		case '\\':
		case '*':
		case '.':
			ChangeDir(List_NU, 'A');
			break;
		case 'c':
			CloseFile(&pF);
			break;
		case 'r':
			if(pF != NULL)
			{
				if(pF->FDP.Len < pF->FileSize)
					temp = ReadFile(pF, 32, 'A');
				else
					CloseFile(&pF);
					
				/*flen = GetSizeDC(&Disk_Cache);
				if((temp = FILE_EOF) && (flen == 0))
				{
					UartPrint((void *)("\nfile end"));
				}
				else
				for(i=0; i<flen; i++)
				{
					temp = PeekQueueDC(&Disk_Cache);
					UartPutchar(temp);
				}*/
			}
			break;
		default:
			if(List_NU > 0 && List_NU <= QuDirList.MaxSize)
			{
				CloseFile(&pF);
				pF = OpenFile(List_NU);
				if((pF->Attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == 0x00)
				{//读取文件中数据
	
					InitQueueDC(&Disk_Cache);
					if(pF != NULL)
					{
						temp = ReadFile(pF, 512, 'A');
						if(temp != FILE_EOF)
						{
							if(pF->SName[8] == 'M' && pF->SName[9] == 'P' && pF->SName[10] == '3')
							{
								MP3Handle = MP3CMD_Play;
								UartPrint((void *)("\nPlaying "));
								for(j=0; j<11; j++)
								{
									if(j == 8)
									{
										if(pF->SName[j] != ' ')
										UartPutchar('.');
									}
									if(pF->SName[j] != ' ')
										UartPutchar(pF->SName[j]);
								}
							}
						}
						/*flen = GetSizeDC(&Disk_Cache);
						if((temp = FILE_EOF) && (flen == 0))
						{
							UartPrint((void *)("\nfile end"));
						}
						else
						for(i=0; i<flen; i++)
						{
							temp = PeekQueueDC(&Disk_Cache);
							UartPutchar(temp);
						}*/
					}
				}
				else if((pF->Attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == ATTR_DIRECTORY)
				{//改变当前目录
			
					ChangeDir(List_NU, 'A');
				}
			}
	}
}

⌨️ 快捷键说明

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