📄 file_system.c
字号:
/************************************************************************************
本程序仅供广大电子爱好者制作MP3学习和参考使用,不得用于其它用途,否则后果自负
file_system.c file
Created by Computer-lov. Date: 2005.3.19
Last edited date: 2005.5.31
version 1.1
Copyright (c) 2005 Computer-lov
All rigths reserved
*************************************************************************************/
#include "file_system.h"
#include "IDE.H"
#include "hardware.h"
#include "lcd.h"
#include "mp3.h"
#include "keyboard.h"
FILE xdata file;
unsigned int dir_length; //文件名长度
unsigned int folder_length; //文件夹名长度
//////////////////////////////////// 判断是否为一个 MP3 文件 ///////////////////////////////
unsigned char is_a_mp3_file(void)
{
if((file.name[0]==0x00)||(file.name[0]==0xE5)||(file.name[0]=='.'))return 0;
if(file.attribute==0x0F)return 0; //此项目为长文件名项目
if(file.attribute & 0x04)return 0; //此文件为系统文件
if(file.attribute & 0x08)return 0; //此项目为系统标卷
if(file.attribute & 0x10)return 0; //此项目为子目录
if((file.name[8]=='M')&&(file.name[9]=='P')&&(file.name[10]=='3'))return 1;
else return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////
unsigned long int LAST_FAT_LBA;
//最后一次读取FAT时的逻辑块地址,用来判断本次读取是否需要重新从硬盘中读取,以加快速度
unsigned int disp_count=0;
unsigned char disp_time;
////////////////////////////////////////////////////////////////////////////////////////////////
unsigned long int get_next_sector(void) //根据当前簇号,获取下一个扇区地址
{
unsigned long int LBA;
unsigned int i;
LBA=(file.next_cluster_number)/((dbr[driver_number].bytes_per_sectors)/4); //计算扇区地址
i=(file.next_cluster_number)*4-LBA*dbr[driver_number].bytes_per_sectors; //计算偏移地址
if(LAST_FAT_LBA!=LBA) //如果数据不在FAT_buffer[]中,则需要重新读取
{
LAST_FAT_LBA=LBA;
LBA=LBA+FAT_start_sector[driver_number];
read_IDE_FAT_sector(LBA);
}
((unsigned char *)&(file.next_cluster_number))[3]=FAT_buffer[i];
i++;
((unsigned char *)&(file.next_cluster_number))[2]=FAT_buffer[i];
i++;
((unsigned char *)&(file.next_cluster_number))[1]=FAT_buffer[i];
i++;
((unsigned char *)&(file.next_cluster_number))[0]=FAT_buffer[i]; //获取下一簇号
LBA=file.next_cluster_number-(dbr[driver_number].root_cluster_num); //保存簇号
LBA=LBA*(dbr[0].sectors_per_cluster)+DATA_start_sector[0]; //转换成扇区地址
// IDE_LED=!IDE_LED; //硬盘指示灯闪烁
disp_time++;
if(disp_time>3)
{
disp_time=0;
LCD_go_home();
disp_count+=2;
for(i=0;i<14;i++)write_LCD_data(((unsigned char *)dir_name)[(i+disp_count)%(dir_length+4)]);
}
return LBA;
}
////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////// 获取文件夹的下一扇区地址 ///////////////////
unsigned long int get_dir_next_sector(void)
{
unsigned long int LBA,LBA2;
unsigned int i;
LBA=current_dir.current_cluster_number-(dbr[driver_number].root_cluster_num);
LBA=LBA*(dbr[driver_number].sectors_per_cluster)+DATA_start_sector[driver_number];
LBA2=(current_dir.current_cluster_number)/((dbr[driver_number].bytes_per_sectors)/4); //计算扇区地址
i=(current_dir.current_cluster_number)*4-LBA2*dbr[driver_number].bytes_per_sectors; //计算偏移地址
LBA2=LBA2+FAT_start_sector[driver_number];
read_IDE_sector(LBA2);
((unsigned char *)&(current_dir.current_cluster_number))[3]=buffer[i];
i++;
((unsigned char *)&(current_dir.current_cluster_number))[2]=buffer[i];
i++;
((unsigned char *)&(current_dir.current_cluster_number))[1]=buffer[i];
i++;
((unsigned char *)&(current_dir.current_cluster_number))[0]=buffer[i]; //获取下一簇号
return LBA;
}
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
void get_nst_file(void) //获取第n个MP3文件
{
unsigned int i,j,k,temp_count;
unsigned long int LBA;
unsigned char xdata temp_buffer[32];
disp_count=0;
temp_count=0;
current_dir.current_cluster_number=current_dir.first_cluster_number;
do
{
LBA=get_dir_next_sector();
for(i=0;i<dbr[driver_number].sectors_per_cluster;i++)
{
read_IDE_sector(LBA);
for(j=0;j<dbr[driver_number].bytes_per_sectors/32;j++)
{
if(j==15){for(k=0;k<32;k++)temp_buffer[k]=buffer[k+512-32];} //如果已到最后一个项,则将之保存
for(k=0;k<11;k++)file.name[k]=buffer[j*32+k];
file.attribute=buffer[j*32+11];
if(is_a_mp3_file())
{
temp_count++;
if(temp_count==play_count)
{
((unsigned char *)&(file.first_cluster_number))[0]=buffer[j*32+0x15];
((unsigned char *)&(file.first_cluster_number))[1]=buffer[j*32+0x14];
((unsigned char *)&(file.first_cluster_number))[2]=buffer[j*32+0x1B];
((unsigned char *)&(file.first_cluster_number))[3]=buffer[j*32+0x1A];
((unsigned char *)&(file.length))[3]=buffer[j*32+0x1C];
((unsigned char *)&(file.length))[2]=buffer[j*32+0x1D];
((unsigned char *)&(file.length))[1]=buffer[j*32+0x1E];
((unsigned char *)&(file.length))[0]=buffer[j*32+0x1F];
file.next_cluster_number=file.first_cluster_number;
dir_length=folder_length;
if(j==0){for(k=0;k<32;k++)buffer[k+512-32]=temp_buffer[k];j=16;} //如果为第一项,则用刚刚保存的一项替换最后一项
{
j--;
if((buffer[j*32+11]==0x0F)&&(buffer[j*32]!=0xE5)) //如果找到长目录,则用长目录名替换短目录名
{
for(k=0;k<10;k++)
{
((unsigned char *)dir_name)[dir_length]=buffer[j*32+0x02+k];
k++;
dir_length++;
((unsigned char *)dir_name)[dir_length]=buffer[j*32+k];dir_length++;
}
for(k=0;k<12;k++)
{
((unsigned char *)dir_name)[dir_length]=buffer[j*32+0x0F+k];
dir_length++;
k++;
((unsigned char *)dir_name)[dir_length]=buffer[j*32+0x0D+k];
dir_length++;
}
((unsigned char *)dir_name)[dir_length]=buffer[j*32+0x1D];dir_length++;
((unsigned char *)dir_name)[dir_length]=buffer[j*32+0x1C];dir_length++;
((unsigned char *)dir_name)[dir_length]=buffer[j*32+0x1F];dir_length++;
((unsigned char *)dir_name)[dir_length]=buffer[j*32+0x1E];dir_length++;
}
for(k=folder_length/2;k<13+folder_length/2;k++){if((dir_name[k]==0x0000)||(dir_name[k]==0xFF00)||(dir_name[k]==0xFFFF))break;change_code(&(dir_name[k]));}
dir_length=folder_length+(k-folder_length/2)*2;
for(;k<100;k++)dir_name[k]=0x2020;
}
return;
}
}
}
LBA++;
}
}while((!(current_dir.current_cluster_number>=0xFFFFFFF8))&&(LBA<(dpt[driver_number].start_sector+dpt[driver_number].total_sectors))); //直到文件夹结束
play_count=1;status=STOP;
}
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
void get_pre_file(void) //打开上一个MP3文件,文件信息保存在file结构中
{
if(play_count>=2)play_count--;
else {file.next_cluster_number=file.first_cluster_number;return;} //如果已到达该文件夹最前一个文件,则播放原文件
get_nst_file();
}
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
void get_next_file(void) //打开下一个MP3文件
{
play_count++;
get_nst_file();
}
////////////////////////////////////////////////////////////////////////////////////////////////
DIR xdata current_dir;
unsigned int xdata dir_name[200];
unsigned int xdata item_name[13];
unsigned int item_count;
DIR xdata temp_dir;
unsigned char file_or_folder;
//////////////////////////////////// 判断是否为一个文件夹 ///////////////////////////////
unsigned char is_a_folder(void)
{
if((file.name[0]==0x00)||(file.name[0]==0xE5)||(file.name[0]=='.'))return 0;
if(file.attribute==0x0F)return 0; //此项目为长文件名项目
if(file.attribute & 0x04)return 0; //此文件为系统文件
if(file.attribute & 0x08)return 0; //此项目为系统标卷
if(file.attribute & 0x10)return 1; //此项目为子目录
else return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// 获取当前目录下 下一个有效文件或者文件夹 /////////////////
void get_pre_item(void)
{
if(item_count>=2)item_count--;
if(item_count==0)item_count=1;
get_nst_item();
}
//////////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -