- #include <at89x51.h>
- /**************************************************
- * HardDisk Control Demo
- * Power BY DDDLZHU
- * 编译环境 : KEIL C51 V7.07 支持器件 : AT89C51
- * COPYRIGHT (C) 2004
- ***************************************************/
- #define byte unsigned char
- #define uint unsigned int
- /*************************************************
- //线路连接定义。如电路有变直接修改就可以了
- *************************************************/
- #define DataH P1
- #define DataL P0
- #define RegAddr P2
- #define Read P3_4
- #define Write P3_3
- #define Rst P3_2
- /*************************************************
- //线路连接定义。如电路有变直接修改就可以了
- *************************************************/
- //寄存器地址定义
- #define _Status_Control 0x16
- #define _Data 0x8
- #define _Err_Features 0x9
- #define _SecCount 0xa
- #define _SecNum 0xb
- #define _CylinderL 0xc
- #define _CylinderH 0xd
- #define _DeviceAndHead 0xe
- #define _Status_Command 0xf
- //**************************************************************************************/
- /*这里为初始化硬盘的重要参数,每个硬盘的参数都不尽相同。若不正确则读不了盘中的数据。计算方法如下:
- 先看清楚你的 硬盘表面标签中的数据,里面有三个重要参数:
- 1。柱面数(Cylinder)
- 2。磁头数(Head)
- 3。磁道数(Sector)
- 其中 _MaxHead=0xA+Head
- _MaxSector=Sector
- 例如我的130M硬盘(很老吧,哈哈),磁头数为15,十六进制为0xf,所以_MaxHead=0xAF,磁道数为17,所以_MaxSector=0x11
- */
- #define _MaxHead 0xAF
- #define _MaxSector 0x11
- //************************************************************************************
- byte bdata Status=0x00;
- sbit ERR=Status^0;
- sbit IDX=Status^1;
- sbit CORR=Status^2;
- sbit DRQ=Status^3;
- sbit DSC=Status^4;
- sbit DF=Status^5;
- sbit DRDY=Status^6;
- sbit BSY=Status^7;
- //************************************************************
- * D7 D6 D5 D4 D3 D2 D1 D0 *
- BSY DRDY DWF DSC DRQ CORR IDX ERR *
- BSY:驱动器忙; *
- DRDY:驱动器准备好; *
- DWF:驱动器写失败; *
- DSC:寻道结束; *
- DRQ:请求服务,驱动器希望通过数据寄存器与CPU交换一字节数据;*
- CORR:当可以纠正的读错误发生时,该位置1,数据传输将继续进行 *
- IDX:收到综引信号; *
- ERR:命令执行出错。 *
- *************************************************************/
- byte Data_bufferH=0x0;
- byte Data_bufferL=0x0;
- //***************串口子程序
- void send_string(unsigned char *word);
- void send_char(unsigned char word);
- unsigned char get_char(void);
- /*******************************************************
- :延迟函数
- ********************************************************/
- void delay(byte ms)
- { byte i,j;
- for(i=0;i<ms;i++)
- for(j=0;j<255;j++);
- }
- /*******************************************************
- *读寄存器
- ********************************************************/
- byte ReadReg(byte Addr)
- {
- RegAddr=Addr;
- DataL=0xff;
- Read=0;
- Status=DataL;
- Read=1;
- return Status;
- }
- /*******************************************************
- *等待BSY信号
- ********************************************************/
- byte WaitBSY(void)
- {
- byte timeOut=0;
- do{
- ReadReg(_Status_Command);
- timeOut++;
- // if(timeOut>=254) return(0xff);
- }while(BSY);
- return(1);
- }
- /*****************************************************
- *写寄存器值
- ********************************************************/
- void WriteReg(byte Addr,byte Data)
- {
- RegAddr=Addr;
- Write=0;
- DataL=Data;
- Write=1;
- }
- /*******************************************************
- 读数据储存器中数据
- ********************************************************/
- void ReadData(void)
- {
- DataH=0xff;
- DataL=0xff;
- RegAddr=_Data;
- Read=0;
- Data_bufferL=DataL;
- Data_bufferH=DataH;
- Read=1;
- }
- /*******************************************************
- 写数据寄存器中数据
- ********************************************************/
- void WriteData(void)
- {
- RegAddr=_Data;
- Write=0;
- DataL=Data_bufferL;
- DataH=Data_bufferH;
- Write=1;
- }
- /**********************************************************
- 初始化硬盘 *
- ***********************************************************/
- void Init(void)
- { do{
- WriteReg(_DeviceAndHead,0xa0);
- ReadReg(_Status_Command);
- }while(!DRDY|BSY);
- WriteReg(_DeviceAndHead,_MaxHead);
- WriteReg(_SecCount,_MaxSector);
- WriteReg(_Status_Command,0x91);
- WaitBSY();
- WriteReg(_Status_Command,0x10);
- WaitBSY();
- }
- /**********************************************************
- 读硬盘参数
- ***********************************************************/
- void DriverID(void)
- {
- unsigned int i=512;
- //send_string("Starting read driver ID\n");
- WaitBSY();
- //send_string("Now can read driver ID \n");
- WriteReg(_Status_Command,0xec);
- //send_string("Waiting.. ");
- do{ReadReg(_Status_Command);}while(BSY|!DRQ);
- //send_string("Now Sending \n");
- while(i){
- ReadData();
- send_char(Data_bufferH);
- send_char(Data_bufferL);
- i-=2;
- }
- }
- /*********************************************************
- 硬盘寻址
- **********************************************************/
- WriteCHS(byte head,uint cylinder,byte sector,byte read_count)
- {
- WaitBSY();
- WriteReg(_DeviceAndHead,0xa0|head);
- WriteReg(_CylinderH,(char)(cylinder>>8));
- WriteReg(_CylinderL,(char)(cylinder&0x00ff));
- WriteReg(_SecNum,sector);
- WriteReg(_SecCount,read_count);
- }
- /**********************************************************
- *用途:将硬盘的返回数据读入BUFFER数组
- ***********************************************************/
- void SendData()
- { uint i;
- i=512*15;
- do{ReadReg(_Status_Command);}while(BSY|!DRQ);
- if(ERR){
- send_string("\x0d\x0a Error\x0d\x0a");
- }
- while(i){ReadData();send_char(Data_bufferL);send_char(Data_bufferH);i-=2;}
- }
- // 激活硬盘(转动)
- void SpinUP()
- {
- WaitBSY();
- WriteReg(_Status_Command,0xE1);
- }
- // 让硬盘休眠(停转)/
- void SpinDown()
- {
- WaitBSY();
- WriteReg(_Status_Command,0xE0);
- }
- void main(void)
- {
- //Initialize
- SCON=0x50; //串口初始化
- TMOD=0x20; //波特率为57600bps
- TCON=0x40;
- PCON=0x80;
- TH1=0xFf;
- TL1=0xFf;
- TR1=1;
- send_string("IDE Control Demo. Power By DDDLZHU\x0d\x0a");//send welcome word
- Rst=0; //IDE 复位
- delay(50);
- Rst=1;
- delay(255);
- send_string("Reset Driver OK...\x0d\x0a");
- Init(); //初始化硬盘
- send_string("Initialize Driver OK,Now Read ID\x0d\x0a");
- send_string("HardDisk ID is ....\x0d\x0a");
- DriverID(); //读硬盘id
- send_string("\n\nNow Read The First Sector On this HardDisk\x0d\x0a\x0d\x0a");
- delay(244);
- delay(244);
- delay(244);
- delay(244);
- WriteCHS(0,0,1,16); //写地址
- WaitBSY();
- WriteReg(_Status_Command,0x20); //发送读命令
- SendData();
- send_string("\x0d\x0a\x0d\x0a Read OK,Now Shut Down The HardDisk..\x0d\x0a");
- SpinDown(); //硬盘停转
- while(1);
- }
- //**************************************串口子程序
- void send_char(unsigned char word)
- {
- TI=0;
- SBUF=word;
- while(TI==0);
- TI=0;
- }
- void send_string(unsigned char *word)
- {
- TI=0;
- while(*word!=0)
- {
- SBUF=*word;
- while(TI==0);
- TI=0;
- word++;
- }
- }
- unsigned char get_char(void)
- {
- RI=0;
- REN=1;
- while(RI==0);
- return(SBUF);
- RI=0;
- REN=0;
- }