/******************************************************************** 硬盤控制源程序 ** 創(chuàng)建日期: 2004/3/5 ** 版本 : VER 1.0 最近修改日期 : 2004/3/6 ** 作者:邵春偉 最近修改時間 : 23:48 ** 編譯環(huán)境 : KEIL C51 V7.07 支持器件 : AT89C51 ** COPYRIGHT (C) 2004 */*******************************************************************/
///////////////////預(yù)處理/////////////////////////////////////#include <reg51.h>#include <absacc.h>#define uchar unsigned char#define uint unsigned int#define KEYPORT P1#define LCDCOM XBYTE[0x0008]//LCD命令寄存器#define LCDDATA XBYTE[0x0009]//LCD數(shù)據(jù)寄存器#define CDPA XBYTE[0x0004]//8255 PORT A, harddisk D0-D7#define CDPB XBYTE[0x0005]//8255 PORT B, harddisk D8-D15#define CDPC XBYTE[0x0006]//8255 PORT C,harddisk address#define CDCOM XBYTE[0x0007]//8255 命令寄存器#define FILE0 0x00//硬盤數(shù)據(jù)寄存器 #define FILE1 0x01//錯誤/特征寄存器#define FILE2 0x02//扇區(qū)數(shù)寄存器#define FILE3 0x03//扇區(qū)號寄存器#define FILE4 0x04//柱面號寄存器L#define FILE5 0x05//柱面號寄存器H#define FILE6 0x06//驅(qū)動器/磁頭寄存器#define FILE7 0x07//狀態(tài)/命令寄存器static uchar code LCD1[16]= "TOPLOW DESIGN ";static uchar code LCD2[16]= "Copyright(C)2004";static uchar code ERROR[16]="ERROR ";static uchar code PASS[16]= "PASS ";uchar buffer0,buffer1;uchar buffer[16];uchar STATUS;///////////////////位設(shè)置///////////////////////////sbit BFLAG=ACC^7;sbit BSY=ACC^7;sbit DRDY=ACC^6;sbit DRQ=ACC^3;sbit ERR=ACC^0;sbit RESET=P3^5;sbit READ=P3^0;sbit WRITE=P3^1;sbit ILT=ACC^0;sbit INTRQ=P3^3;/************************************************************* D7 D6 D5 D4 D3 D2 D1 D0 *BSY DRDY DWF DSC DRQ CORR IDX ERR *BSY:驅(qū)動器忙; *DRDY:驅(qū)動器準(zhǔn)備好; *DWF:驅(qū)動器寫失敗; *DSC:尋道結(jié)束; *DRQ:請求服務(wù),驅(qū)動器希望通過數(shù)據(jù)寄存器與CPU交換一字節(jié)數(shù)據(jù);*CORR:當(dāng)可以糾正的讀錯誤發(fā)生時,該位置1,數(shù)據(jù)傳輸將繼續(xù)進(jìn)行 *IDX:收到綜引信號; *ERR:命令執(zhí)行出錯。 **************************************************************//********************************************************函數(shù)名稱:void delay(uint time) **函數(shù)用途:延遲函數(shù) *********************************************************/ void delay(uint time){ uint i,j; for(i=0;i<time;i++) for(j=0;j<255;j++);}/********************************************************函數(shù)名稱:void putch(unsigned char ch) **函數(shù)用途:串口發(fā)送程序 *********************************************************/void putch(unsigned char ch){ SBUF=ch; TI=0; while(!TI);}/********************************************************函數(shù)名稱:unsigned char getch(void) **函數(shù)用途:串口接收程序 *********************************************************/unsigned char getch(void){ uchar temp; while(!RI); temp=SBUF; RI=0; return(temp);}/********************************************************函數(shù)名稱:void wait(void) **函數(shù)用途:LCD忙等待 *********************************************************/ void wait(void){ do { ACC=LCDCOM; } while(BFLAG==1);}/********************************************************函數(shù)名稱:void IniLcd(void) **函數(shù)用途:LCD初始化函數(shù) *********************************************************/ void IniLcd(void){ LCDCOM=0x38; wait(); LCDCOM=0x08; wait(); LCDCOM=0x01; wait(); LCDCOM=0x06; wait(); LCDCOM=0x0c; wait();}/************************************************************************函數(shù)名稱:void LcdDis(uchar FL,uchar Lcd1[16],uchar SL,uchar Lcd2[16]) **函數(shù)用途:液晶顯示函數(shù) *************************************************************************/ void LcdDis(uchar FL,uchar Lcd1[16],uchar SL,uchar Lcd2[16]){ uchar k; LCDCOM=FL|0x80; wait(); for(k=0;k<16;k++) { LCDDATA=Lcd1[k]; wait(); } LCDCOM=SL|0xc0; wait(); for(k=0;k<16;k++) { LCDDATA=Lcd2[k]; wait(); }}/********************************************************函數(shù)名稱:void ReadReg(uchar ADD) **函數(shù)用途:讀硬盤非數(shù)據(jù)寄存器內(nèi)容,并將結(jié)果返回 *********************************************************/void ReadReg(uchar ADD){ CDCOM=0x92; CDPC=ADD; READ=0; ACC=CDPA; STATUS=ACC; READ=1;}/********************************************************函數(shù)名稱:void WriteReg(uchar ADD,uchar DATA) **函數(shù)用途:寫硬盤非數(shù)據(jù)寄存器內(nèi)容 *********************************************************/void WriteReg(uchar ADD,uchar DATA){ CDCOM=0x80; CDPC=ADD; WRITE=0; CDPA=DATA; WRITE=1;}/********************************************************函數(shù)名稱:void ReadData() **函數(shù)用途:讀硬盤數(shù)據(jù)寄存器內(nèi)容 *********************************************************/void ReadData(){ CDCOM=0x92; CDPC=FILE0; READ=0; buffer0=CDPA; buffer1=CDPB; READ=1;}/********************************************************函數(shù)名稱:void WriteData(uchar Data0,uchar Data1) **函數(shù)用途:寫硬盤數(shù)據(jù)寄存器內(nèi)容 *********************************************************/void WriteData(uchar Data0,uchar Data1){ CDCOM=0x80; CDPC=FILE0; WRITE=0; CDPA=Data0; CDPB=Data1; WRITE=1;}/**********************************************************函數(shù)名稱:WriteCHS(uint cylinder,uchar head,uchar sector)**函數(shù)用途:寫CHS信息(地址信息) ***********************************************************/WriteCHS(uchar head,uint cylinder,uchar sector){ do{ReadReg(FILE7);}while(BSY); WriteReg(FILE6,0xe0&head); WriteReg(FILE5,cylinder>>8);//high 2-bit cylinder WriteReg(FILE4,cylinder&0x00ff);//low 8-bit cylinder WriteReg(FILE3,sector);//start sector WriteReg(FILE2,0x01);//sector counter}/**********************************************************函數(shù)名稱:WriteCommand(command) **函數(shù)用途:寫命令 ***********************************************************/WriteCommand(command){ do{ReadReg(FILE7);}while(BSY); WriteReg(FILE7,command);}/***********************************************************函數(shù)名稱:GetData() **用途:將硬盤的返回數(shù)據(jù)讀入BUFFER數(shù)組 ************************************************************/void GetData(){ uint i=512; do{ReadReg(FILE7);}while(BSY|!DRQ); if(ERR) { LcdDis(0,ERROR,0,LCD2); putch(255); } while(i){ReadData();putch(buffer0);putch(buffer1);i-=2;}}/***********************************************************函數(shù)名稱:void IniHard(void) **用途:初始化硬盤 ************************************************************/void IniHard(void){ do { WriteReg(FILE6,0xa0); ReadReg(FILE7); }while(!DRDY|BSY); WriteReg(FILE6,0x20); WriteReg(FILE2,64); WriteReg(FILE7,0x91); do{ReadReg(FILE7);}while(BSY); WriteReg(FILE7,0x10); do{ReadReg(FILE7);}while(BSY);}/***********************************************************函數(shù)名稱:void DriveID(void) **用途:讀硬盤ID ************************************************************/ void DriveID(void){ uint i=512; do { ReadReg(FILE7); }while(BSY); WriteReg(FILE7,0xec); do{ReadReg(FILE7);}while(BSY|!DRQ); while(i){ReadData();putch(buffer0);putch(buffer1);i-=2;}}/********************************************************函數(shù)名稱:主函數(shù) **函數(shù)用途: *********************************************************/void HardDiskControl(void){ uint i; SCON=0x50;//方式1,串行口接收允許位 TMOD=0x21;//定時器1用于串行通信波特率發(fā)生,定時器0用于REMOTE接收判斷0,1時間 PCON=0x80;//串行波特率加倍位 TCON=0x51;//啟動計數(shù)器0,計數(shù)器1 EA=1;//中斷允許 EX0=0;//外部中斷0不允許 TH1=0xD0; TL1=0xD0; TI=1; RESET=0; delay(50); RESET=1; delay(255); IniHard(); //DriveID(); WriteCHS(0,0,0); WriteCommand(0x20); GetData(); IniLcd(); LcdDis(0,LCD1,0,LCD2); for(i=0;i<512;i++) { putch(i); delay(255); } while(1);}void main(void){ HardDiskControl();}