51单片机控制硬盘资料及电路

发布时间:2011-6-22 11:46    发布者:circuit_share
关键词: 51单片机 , 硬盘


#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;

}
本文地址:https://www.eechina.com/thread-69273-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

相关视频

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表