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

📄 ide.c

📁 基于at89c51snd1c的硬盘MP3播放器
💻 C
字号:
/************************************************************************************
  本程序仅供广大电子爱好者制作MP3学习和参考使用,不得用于其它用途,否则后果自负

   IDE.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 "AT89C51SND1C.h"
#include "file_system.h"
#include "IDE.H"
#include "hardware.h"

#include "lcd.h"

unsigned char  DISK_CAPACITY[8];
unsigned char driver_number=0;             //磁盘驱动器

//////////////////////////////////////   IDE 状态寄存器  ////////////////////////////////////
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毫秒,时间不准的
{
 unsigned int i;
 for(;x>0;x--)
  for(i=0;i<500;i++);
}
//////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////   IDE 复位  ///////////////////////////////////////////////
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 状态寄存器  /////////////////////////////////
void read_IDE_status(void)
{
 IDE_status=read_IDE_8(IDE_Status);  //结果保存在状态寄存器中
}
///////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////    读 IDE 错误寄存器 ///////////////////////////////////
void read_IDE_error(void)
{
 IDE_error_register=read_IDE_8(IDE_Error_Register);   //结果保存在错误寄存器中
}
///////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////     等待IDE    ///////////////////////////////////////////
unsigned char wait_IDE_busy(void)
{
 while(!IDE_IORDY);
 do
  {
   read_IDE_status();
   if(IDE_ERR)
   {
    read_IDE_error();
    LCD_go_home();
    prints("硬盘错误! ");
    printf(IDE_error_register);
   }
  }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 软复位    /////////////////////////////////////
/*(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];  //扇区缓冲

unsigned int byte_offset;        //字节偏移
unsigned char disk_error=0;     //磁盘错误


DPT xdata dpt[4];   //磁盘分区表
DBR xdata dbr[4];   //DOS引导记录


unsigned long int xdata FAT_start_sector[4];   //FAT开始扇区
unsigned long int xdata DATA_start_sector[4];  //数据开始扇区

unsigned char mp3_file_exist=0;

unsigned char xdata FAT_buffer[512];         //文件分配表FAT缓冲

//////////////////////////////////////  写扇区计数寄存器   ///////////////////////////////////////////
void write_IDE_sector_count(unsigned char count)
{
 write_IDE_8(IDE_Sector_Count,count);
}
/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////  读取一个FAT扇区,512字节保存在FAT_buffer[]中  ///////////////////////
void read_IDE_FAT_sector(unsigned long int LBA)
{
 unsigned int i;
 if(LBA>=(dpt[driver_number].start_sector+dpt[driver_number].total_sectors))return;
 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;
}
///////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////  读取一个数据扇区,512字节保存在buffer[]中 //////////////////
void read_IDE_sector(unsigned long int LBA)
{
 unsigned int i;
 if(LBA>=(dpt[driver_number].start_sector+dpt[driver_number].total_sectors))return;
 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;  //当前文件夹中播放曲号

/////////////////////////////////////   获取磁盘信息  /////////////////////////////////////////
void get_IDE_information(void)
{
 unsigned int i;
 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];       //文件系统类型
  ((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];  //分区开始扇区
  ((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];  //分区总扇区
 }
 
 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];     //每扇区字节数
 ((unsigned char *)&(dbr[0].bytes_per_sectors))[0]=buffer[0x0C];
 ((unsigned char *)&(dbr[0].bytes_per_sectors))[1]=buffer[0x0B];  //每扇区字节数
 dbr[0].sectors_per_cluster=buffer[0x0D];                        //每簇扇区数
 ((unsigned char *)&(dbr[0].reserve_sectors))[1]=buffer[0x0E];
 ((unsigned char *)&(dbr[0].reserve_sectors))[0]=buffer[0x0F];   //保留扇区数
 dbr[0].num_of_FAT=buffer[0x10];                                  //FAT副本数
 ((unsigned char *)&(dbr[0].FAT16_ROOT_num))[1]=buffer[0x11];
 ((unsigned char *)&(dbr[0].FAT16_ROOT_num))[0]=buffer[0x12];     //FAT16文件系统的根目录数
 ((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];
 DISK_CAPACITY[0]=buffer[0x23];
 DISK_CAPACITY[1]=buffer[0x22];
 DISK_CAPACITY[2]=buffer[0x21];
 DISK_CAPACITY[3]=buffer[0x20];
 ((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;
 play_count=1;
 item_count=1;
 get_nst_item();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*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(unsigned long int LBA)
{
 unsigned int i;
 write_IDE_LBA(LBA);
 write_IDE_sector_count(1);
 write_IDE_command(IDE_Write_Sectors);
 IDE_Address=IDE_Data;
 set_IDE_address();
 for(i=0;i<512;i++)
  {
   while(!IDE_IORDY);
   IDE_DIOW=0;
   IDE_DATA_L=buffer[i];
   i++;
   IDE_DATA_H=buffer[i];
   IDE_DIOW=1;
  }
 wait_IDE_busy();
 IDE_Address=IDE_Bus_Not_Use;
 set_IDE_address();
}
*/

/////////////////////////////////////////////    IDE 初始化  /////////////////////////////////////////
void IDE_initial(void)
{
 unsigned char i;
 reset_IDE();
 for(i=2;i<200;i++)dir_name[i]=0x2020;
 do
  {
   write_IDE_8(IDE_Drive_Head,0xE0);
   read_IDE_status();
  }while(IDE_BSY);
 wait_IDE_busy();
 write_IDE_8(IDE_Device_Control,0xFA);//没有中断模式
 dir_name[0]='C'+0xA380;
 ((unsigned char *)dir_name)[2]=':';
 ((unsigned char *)dir_name)[3]='\\';
 folder_length=4;
 dir_length=folder_length;
 not_root_dir=0;
 get_IDE_information();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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