×
单片机 > 单片机程序设计 > 详情

51单片机控制硬盘的C语言源码程序

发布时间:2020-05-28 发布时间:
|
#include   
   
/////////////////////////////////////////////////////////////////////////////////////////////////////  
//                  单片机教程httP://www.ipbb.cn  
//     Power BY DDDLZHU  
//    编译环境 : KEIL C51 V7.07    支持器件 : AT89C51         
  
///////////////////////////////////////////////////////////////////////////////////////////////////////   
   
#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 
     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;   
}   
   [page]
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
初始化硬盘                                          //  
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
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 ");   
WaitBSY();   
//send_string("Now can read driver ID   ");   
WriteReg(_Status_Command,0xec);   
//send_string("Waiting..  ");   
do{ReadReg(_Status_Command);}while(BSY|!DRQ);   
//send_string("Now Sending   ");   
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("x0dx0a Errorx0dx0a");   
    }   
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 DDDLZHUx0dx0a");//send welcome word   
Rst=0; //IDE 复位   
delay(50);   
Rst=1;   
delay(255);   
send_string("Reset Driver OK...x0dx0a");   
Init();   //初始化硬盘   
send_string("Initialize Driver OK,Now Read IDx0dx0a");   
send_string("HardDisk ID is ....x0dx0a");   
DriverID();  //读硬盘id   
send_string(" Now Read The First Sector On this HardDiskx0dx0ax0dx0a");   
delay(244);   
delay(244);   
delay(244);   
delay(244);   
WriteCHS(0,0,1,16); //写地址   
WaitBSY();   
WriteReg(_Status_Command,0x20);   //发送读命令   
SendData();   
send_string("x0dx0ax0dx0a Read OK,Now Shut Down The HardDisk..x0dx0a");   
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;   
}  


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析