?? 硬盤mp3源碼.txt
字號:
/************************************************************************************
本程序僅供廣大電子愛好者制作MP3學(xué)習(xí)和參考使用,不得用于其它用途,否則后果自負(fù)
AT89C51SND1C 解碼芯片做的硬盤MP3,軟件還在完善中,現(xiàn)在只支持一塊硬盤,一個分區(qū),
只支持根目錄歌曲播放,不支持文件夾。只支持FAT32文件系統(tǒng),部分MP3文件不能解碼。
*************************************************************************************/
/* MAIN.C File
The MP3 main file
Created by Computer-lov date: 2005.3.19
Copyright (c) 2005 Computer-lov
version 1.0
*/
#include "AT89C51SND1C.H"
#include "ide.h"
#include "hardware.h"
#include "file_system.h"
#include "Initial.h"
#include "keyboard.h"
#include "MP3.H"
//////////////////////////////////////////// 主函數(shù) ///////////////////////////////
void main(void)
{
system_initial(); //初始化
status=START;
driver_number=0; //選擇第一個分區(qū)
key=0;
function=FUN_SEL; //歌曲選擇狀態(tài)
while(1)
{
switch (status)
{
case START: //開機
{
vol=10;
bas=10;
med=10;
tre=10;
set_vol(vol);
set_vor(vol);
set_bas(bas);
set_med(med);
set_tre(tre); //音量等初始化
while(!key);
if(key==KEY_OK)
{
status=PLAY;
key=0;
break;
}
}
case STOP:{ //停止
while(!key);
if(key==KEY_OK)
{
status=PLAY;
key=0;
break;
}
}
case PLAY:{play();break;} //播放
case USB: {break;} //USB下載
key=0;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
/* IDE.C File
Created by Computer-lov Date: 2005.3.19
Copyright (c) 2005 Computer-lov
version 1.0
*/
#include "AT89C51SND1C.h"
#include "file_system.h"
#include "IDE.H"
#include "hardware.h"
unsigned char DISK_CAPACITY[8];
//unsigned char IDE_Buffer_H,IDE_Buffer_L;
unsigned char driver_number=0; //磁盤驅(qū)動器
////////////////////////////////////// IDE 狀態(tài)寄存器 ////////////////////////////////////
unsigned char bdata IDE_status;
sbit IDE_BSY = IDE_status^7;
sbit IDE_DRDY = IDE_status^6;
sbit IDE_DWF = IDE_status^5;
sbit IDE_DSC = IDE_status^4;
sbit IDE_DRQ = IDE_status^3;
sbit IDE_CORR = IDE_status^2;
sbit IDE_IDX = IDE_status^1;
sbit IDE_ERR = IDE_status^0;
//////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// IDE 錯誤寄存器 ////////////////////////////////////
unsigned char bdata IDE_error_register;
sbit IDE_BBK = IDE_error_register^7;
sbit IDE_UNC = IDE_error_register^6;
sbit IDE_MC = IDE_error_register^5;
sbit IDE_IDNF = IDE_error_register^4;
sbit IDE_MCR = IDE_error_register^3;
sbit IDE_ABRT = IDE_error_register^2;
sbit IDE_TKONF= IDE_error_register^1;
sbit IDE_AMNF = IDE_error_register^0;
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
void delayXms(unsigned int x) //延時x毫秒,時間不準(zhǔn)的
{
unsigned int i;
for(;x>0;x--)
for(i=0;i<500;i++);
}
//////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// IDE 復(fù)位 ///////////////////////////////////////////////
void reset_IDE(void)
{
IDE_Address=IDE_Reset;
IDE_ALE=1;
IDE_ALE=0;
delayXms(200);
IDE_Address=IDE_Bus_Not_Use;
IDE_ALE=1;
IDE_ALE=0;
delayXms(200);
while(!IDE_IORDY);
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// 讀IDE 16位,未用 ////////////////////////////////////////
/*void read_IDE_16(unsigned char address)
{
while(!IDE_IORDY);
IDE_Address=address;
set_IDE_address();
IDE_DATA_H=0xFF;
IDE_DATA_L=0xFF;
IDE_DIOR=0;
IDE_Buffer_H=IDE_DATA_H;
IDE_Buffer_L=IDE_DATA_L;
IDE_DIOR=1;
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
}*/
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// 寫IDE 16位,未用 ////////////////////////////////////////
/*void write_IDE_16(unsigned char address)
{
while(!IDE_IORDY);
IDE_Address=address;
set_IDE_address();
IDE_DIOW=0;
IDE_DATA_H=IDE_Buffer_H;
IDE_DATA_L=IDE_Buffer_L;
IDE_DIOW=1;
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
}*/
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////// 讀IDE 低8位 /////////////////////////////////
unsigned char read_IDE_8(unsigned char address)
{
unsigned char temp;
while(!IDE_IORDY);
IDE_Address=address;
set_IDE_address();
IDE_DATA_H=0xFF;
IDE_DATA_L=0xFF;
IDE_DIOR=0;
temp=IDE_DATA_L;
IDE_DIOR=1;
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
return temp;
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////// 寫IDE 低8位 /////////////////////////////////
void write_IDE_8(unsigned char address,unsigned char w_data)
{
while(!IDE_IORDY);
IDE_Address=address;
set_IDE_address();
IDE_DIOW=0;
IDE_DATA_L=w_data;
IDE_DIOW=1;
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
}
///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////// 從IDE讀一個字 //////////////////////////////////
/*void read_IDE_word(void)
{
read_IDE_16(IDE_Data);
}*/
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// 往IDE寫一個字 ///////////////////////////////////
/*void write_IDE_word(void)
{
write_IDE_16(IDE_Data);
}*/
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// 讀 IDE 狀態(tài)寄存器 /////////////////////////////////
void read_IDE_status(void)
{
IDE_status=read_IDE_8(IDE_Status); //結(jié)果保存在狀態(tài)寄存器中
}
///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// 讀 IDE 錯誤寄存器 ///////////////////////////////////
void read_IDE_error(void)
{
IDE_error_register=read_IDE_8(IDE_Error_Register); //結(jié)果保存在錯誤寄存器中
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// 等待IDE ///////////////////////////////////////////
unsigned char wait_IDE_busy(void)
{
while(!IDE_IORDY);
do
{
read_IDE_status();
if(IDE_ERR)
{
read_IDE_error();
}
}while(IDE_BSY);
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// 寫 IDE 命令 /////////////////////////////////////
void write_IDE_command(unsigned char command)
{
write_IDE_8(IDE_Command,command);
wait_IDE_busy();
}
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// IDE 軟復(fù)位 /////////////////////////////////////
/*(void soft_reset_IDE(void)
{
write_IDE_8(IDE_Device_Control,0xFD);
wait_IDE_busy();
}
*/
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// 寫IDE 邏輯塊地址LBA //////////////////////////////
void write_IDE_LBA(unsigned long int _LBA)
{
unsigned char LBA0;
LBA0=((unsigned char *)&_LBA)[0];
LBA0&=0x0F;
LBA0|=0xE0;//磁盤0工作在LBA模式下
write_IDE_8(IDE_LBA_Bits_24_27,LBA0);
write_IDE_8(IDE_LBA_Bits_16_23,((unsigned char *)&_LBA)[1]);
write_IDE_8(IDE_LBA_Bits_8_15,((unsigned char *)&_LBA)[2]);
write_IDE_8(IDE_LBA_Bits_0_7,((unsigned char *)&_LBA)[3]);
}
///////////////////////////////////////////////////////////////////////////////////////////////
unsigned char xdata buffer[512]; //扇區(qū)緩沖
unsigned int byte_offset; //字節(jié)偏移
unsigned char disk_error=0; //磁盤錯誤
DPT xdata dpt[4]; //磁盤分區(qū)表
DBR xdata dbr[4]; //DOS引導(dǎo)記錄
unsigned long int xdata FAT_start_sector[4]; //FAT開始扇區(qū)
unsigned long int xdata DATA_start_sector[4]; //數(shù)據(jù)開始扇區(qū)
unsigned char mp3_file_exist=0;
unsigned char xdata FAT_buffer[512]; //文件分配表FAT緩沖
////////////////////////////////////// 寫扇區(qū)計數(shù)寄存器 ///////////////////////////////////////////
void write_IDE_sector_count(unsigned char count)
{
write_IDE_8(IDE_Sector_Count,count);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// 讀取一個FAT扇區(qū),512字節(jié)保存在FAT_buffer[]中 ///////////////////////
void read_IDE_FAT_sector(unsigned long int LBA)
{
unsigned int i;
write_IDE_LBA(LBA);
write_IDE_sector_count(1);
write_IDE_command(IDE_Read_Sectors);
IDE_Address=IDE_Data;
set_IDE_address();
IDE_DATA_H=0xFF;
IDE_DATA_L=0xFF;
for(i=0;i<512;i++)
{
while(!IDE_IORDY);
IDE_DIOR=0;
FAT_buffer[i]=IDE_DATA_L;
i++;
FAT_buffer[i]=IDE_DATA_H;
IDE_DIOR=1;
}
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
IDE_DATA_L=0xFF;
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// 讀取一個數(shù)據(jù)扇區(qū),512字節(jié)保存在buffer[]中 //////////////////
void read_IDE_sector(unsigned long int LBA)
{
unsigned int i;
write_IDE_LBA(LBA);
write_IDE_sector_count(1);
write_IDE_command(IDE_Read_Sectors);
IDE_Address=IDE_Data;
set_IDE_address();
IDE_DATA_H=0xFF;
IDE_DATA_L=0xFF;
for(i=0;i<512;i++)
{
while(!IDE_IORDY);
IDE_DIOR=0;
buffer[i]=IDE_DATA_L;
i++;
buffer[i]=IDE_DATA_H;
IDE_DIOR=1;
}
IDE_Address=IDE_Bus_Not_Use;
set_IDE_address();
IDE_DATA_L=0xFF;
}
///////////////////////////////////////////////////////////////////////////////////////////////
unsigned int play_count; //當(dāng)前文件夾中播放曲號
///////////////////////////////////// 獲取磁盤信息 /////////////////////////////////////////
void get_IDE_information(void)
{
unsigned int i;
unsigned int j;
unsigned int k;
unsigned long int LBA=0;
mp3_file_exist=0;
LBA=0;
read_IDE_sector(LBA);
for(i=0;i<4;i++)
{
dpt[i].file_system_type=buffer[0x1C2+i*16]; //文件系統(tǒng)類型
((unsigned char *)&(dpt[i].start_sector))[3]=buffer[0x1C6+i*16];
((unsigned char *)&(dpt[i].start_sector))[2]=buffer[0x1C7+i*16];
((unsigned char *)&(dpt[i].start_sector))[1]=buffer[0x1C8+i*16];
((unsigned char *)&(dpt[i].start_sector))[0]=buffer[0x1C9+i*16]; //分區(qū)開始扇區(qū)
((unsigned char *)&(dpt[i].total_sectors))[3]=buffer[0x1CA+i*16];
((unsigned char *)&(dpt[i].total_sectors))[2]=buffer[0x1CB+i*16];
((unsigned char *)&(dpt[i].total_sectors))[1]=buffer[0x1CC+i*16];
((unsigned char *)&(dpt[i].total_sectors))[0]=buffer[0x1CD+i*16]; //分區(qū)總扇區(qū)
}
if((buffer[510]!=0x55)||(buffer[511]!=0xAA))disk_error=1;
LBA=dpt[0].start_sector; //C盤
read_IDE_sector(LBA);
DISK_CAPACITY[7]=buffer[0x0B];
DISK_CAPACITY[6]=buffer[0x0C]; //分區(qū)容量
((unsigned char *)&(dbr[0].bytes_per_sectors))[0]=buffer[0x0C];
((unsigned char *)&(dbr[0].bytes_per_sectors))[1]=buffer[0x0B]; //每扇區(qū)字節(jié)數(shù)
dbr[0].sectors_per_cluster=buffer[0x0D]; //每簇扇區(qū)數(shù)
((unsigned char *)&(dbr[0].reserve_sectors))[1]=buffer[0x0E];
((unsigned char *)&(dbr[0].reserve_sectors))[0]=buffer[0x0F]; //保留扇區(qū)數(shù)
dbr[0].num_of_FAT=buffer[0x10]; //FAT副本數(shù)
((unsigned char *)&(dbr[0].FAT16_ROOT_num))[1]=buffer[0x11];
((unsigned char *)&(dbr[0].FAT16_ROOT_num))[0]=buffer[0x12]; //FAT16文件系統(tǒng)的根目錄數(shù)
((unsigned char *)&(dbr[0].small_sectors))[1]=buffer[0x13];
((unsigned char *)&(dbr[0].small_sectors))[0]=buffer[0x14];
((unsigned char *)&(dbr[0].sectors_per_FAT16))[1]=buffer[0x16];
((unsigned char *)&(dbr[0].sectors_per_FAT16))[0]=buffer[0x17];
((unsigned char *)&(dbr[0].hidden_sectors))[3]=buffer[0x1C];
((unsigned char *)&(dbr[0].hidden_sectors))[2]=buffer[0x1D];
((unsigned char *)&(dbr[0].hidden_sectors))[1]=buffer[0x1E];
((unsigned char *)&(dbr[0].hidden_sectors))[0]=buffer[0x1F];
((unsigned char *)&(dbr[0].large_sectors))[3]=buffer[0x20];
((unsigned char *)&(dbr[0].large_sectors))[2]=buffer[0x21];
((unsigned char *)&(dbr[0].large_sectors))[1]=buffer[0x22];
((unsigned char *)&(dbr[0].large_sectors))[0]=buffer[0x23];
((unsigned char *)&(dbr[0].sectors_per_FAT32))[3]=buffer[0x24];
((unsigned char *)&(dbr[0].sectors_per_FAT32))[2]=buffer[0x25];
((unsigned char *)&(dbr[0].sectors_per_FAT32))[1]=buffer[0x26];
((unsigned char *)&(dbr[0].sectors_per_FAT32))[0]=buffer[0x27];
((unsigned char *)&(dbr[0].root_cluster_num))[3]=buffer[0x2C];
((unsigned char *)&(dbr[0].root_cluster_num))[2]=buffer[0x2D];
((unsigned char *)&(dbr[0].root_cluster_num))[1]=buffer[0x2E];
((unsigned char *)&(dbr[0].root_cluster_num))[0]=buffer[0x2F];
if((buffer[510]!=0x55)||(buffer[511]!=0xAA))disk_error=2;
FAT_start_sector[0]=dpt[0].start_sector+dbr[0].reserve_sectors;
DATA_start_sector[0]=FAT_start_sector[0]+(dbr[0].num_of_FAT)*(dbr[0].sectors_per_FAT32);
LBA=DATA_start_sector[0];
driver_number=C_;
current_dir.first_cluster_number=dbr[0].root_cluster_num;
for(i=0;i<dbr[0].sectors_per_cluster;i++) //掃描C盤根目錄,是否有MP3文件
{
read_IDE_sector(LBA);
for(j=0;j<512/32;j++)
{
for(k=0;k<11;k++)file.name[k]=buffer[j*32+k];
file.attribute=buffer[j*32+11];
((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;
if(is_a_mp3_file())
{
mp3_file_exist=1;
play_count++;
if(play_count==3)return;
}
}
LBA++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*void read_IDE_buffer(void)
{
write_IDE_command(IDE_Read_Buffer);
}*/
/*void write_IDE_buffer(void)
{
write_IDE_command(IDE_Write_Buffer);
}*/
/*void write_IDE_sector(void)
{
write_IDE_command(IDE_Write_Sectors);
}*/
///////////////////////////////////////////// IDE 初始化 /////////////////////////////////////////
void IDE_initial(void)
{
reset_IDE();
do
{
write_IDE_8(IDE_Drive_Head,0xE0);
read_IDE_status();
}while(IDE_BSY);
wait_IDE_busy();
write_IDE_8(IDE_Device_Control,0xFA);//沒有中斷模式f
get_IDE_information();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*file_system.c file
Created by Computer-lov Date: 2005.3.19
Copyright (c) 2005 Computer-lov
version 1.0
*/
#include "file_system.h"
#include "IDE.H"
#include "hardware.h"
//#include "USB_mass_storage.h"
FILE xdata file;
//////////////////////////////////// 判斷是否為一個 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; //此文件為系統(tǒng)文件
if(file.attribute & 0x08)return 0; //此項目為系統(tǒng)標(biāo)卷
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 long int get_next_sector(void) //根據(jù)當(dāng)前簇號,獲取下一個扇區(qū)地址
{
unsigned long int LBA;
unsigned int i;
LBA=(file.next_cluster_number)/((dbr[driver_number].bytes_per_sectors)/4); //計算扇區(qū)地址
i=(file.next_cluster_number)*4-LBA*dbr[driver_number].bytes_per_sectors; //計算偏移地址
if(LAST_FAT_LBA!=LBA) //如果數(shù)據(jù)不在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]; //轉(zhuǎn)換成扇區(qū)地址
// IDE_LED=!IDE_LED; //硬盤指示燈閃爍
return LBA;
}
////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////// 獲取文件夾的下一扇區(qū)地址 ///////////////////
unsigned long int get_dir_next_sector(void)
{
unsigned long int LBA,LBA2;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -