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

📄 file_system.c

📁 基于AT89C51单片机的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************************
  本程序仅供广大电子爱好者制作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 + -