#include <reg51.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; //************************************************************ * D7D6D5D4D3D2D1D0* BSYDRDYDWFDSC DRQCORRIDXERR* 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 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; }