📄 ide.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 + -