📄 单片机写ide硬盘.c
字号:
//发信人: DouChong (热爱生活), 信区: Embedded // 标 题: Re: 单片机写ide硬盘怎么实现? // 发信站: BBS 水木清华站 (Wed Apr 10 22:08:06 2002) //---------------------------------------------------------------------------- // IDE 19960417 CHG // Small and simple interface for an "standard" IDE Harddisk connected // to a 8051 cpu, in this case a DS5000, but all other 8051 compatible // cpu could be used, as long as they have some external RAM, 1KByte or so // // This code is provided as is, with NO responsibility by the author ! // ie. this is use on your own risk !!!!! // // Code is free to use, the only request i have is, that if you do some // enhancements, discoveries I would appreciate to get a copy/info on what // YOU have done ! // That way, we can all help each other with code etc etc etc. // // // //---------------------------------------------------------------------------- #include <reg5000.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> //---------------------------------------------------------------------------- // Constants... //---------------------------------------------------------------------------- #define TRUE 1 #define FALSE 0 #define CTRL 0 #define CMD 1 #define DRIVE0 0 //---------------------------------------------------------------------------- // Types //---------------------------------------------------------------------------- typedef struct { unsigned char Heads; unsigned int Tracks; unsigned int SectorsPerTrack; char Model[41]; } tdefDriveInfo; //定义了结构tdefDriveInfo //---------------------------------------------------------------------------- // I/O definitions... // The IDE harddisk is just connected DIRECTLY to these I/O ports on the 8051 // See pin numbers on IDC connecter on IDE drive in one of the attached files. // REMEMBER to make a pullup on the P0 port (ex 4.7 K to vcc from each of the // 8 P0 pins //---------------------------------------------------------------------------- #define nCS1FX P00 #define nCS3FX P01 #define DA0 P02 #define DA1 P03 #define DA2 P04 #define nDASP P05 #define LSBDATA P1 #define MSBDATA P2 #define nDIOR P06 #define nDIOW P07 #define INTRQ P32 #define IORDY P33 #define RESET P34 #define ALLINPUT 0xFF //---------------------------------------------------------------------------- // Variables... //---------------------------------------------------------------------------- unsigned int Timer10mSec=0; // General timer, tick is 10 mSec unsigned char SectorBuffer[512]; //---------------------------------------------------------------------------- // Wait for a specific time in 10 mSec // Based on a 11.0592 Mhz crystal //---------------------------------------------------------------------------- void Delay(unsigned char t) { unsigned int i; if (t==0) return; while (t--) for(i=0;i<774; i++); } //---------------------------------------------------------------------------- // Dump a buffer as a hex listing //---------------------------------------------------------------------------- void HexDump( void *Dataa, int Len ) { unsigned char *Data=Dataa; unsigned char Line[80], *CurLine, *CurData; int linelen, j; unsigned short rc; unsigned char tmp; printf( "*************** HEX-DUMP ***************\n" ); while( Len ){ linelen = Len < 16 ? Len : 16; *Line='\0'; //即Line[0] CurLine = Line; for( CurData=Data, j=0; j<linelen; j++ ) { tmp=*CurData; sprintf( CurLine, "%02BX ", tmp); CurLine+=3; CurData++; } for( j=linelen; j<17; j++ ) { *CurLine =' '; CurLine[1]=' '; CurLine[2]=' '; CurLine+=3; } for( j=0; j<linelen; j++ ) { sprintf( CurLine, "%c ", *Data > ' ' ? *Data : '_' ); Data++;CurLine+=1; } printf( Line ); printf("\n"); Len-=linelen; } rc = printf( "*************** HEXEND ***************\n" ); } //---------------------------------------------------------------------------- // Timer 0 interrupt service function // executes each 10 mSec @ 11.0592 MHz Crystal Clock //---------------------------------------------------------------------------- timer0() interrupt 1 using 1 { TH0 = 0xDC; // reload timer again TL0 = 0x00; // to 10 mSec timeout TR0 = 1; if (Timer10mSec) Timer10mSec--; } //---------------------------------------------------------------------------- // Show state of nDASP, INTRQ and IORDY signals //---------------------------------------------------------------------------- void ShowInputs(void) { printf("Signals from Drive: nDASP=%s, INTRQ=%s, IORDY=%s\n", nDASP ? "FALSE":"TRUE", INTRQ ? "TRUE":"FALSE", IORDY ? "TRUE":"FALSE"); } //---------------------------------------------------------------------------- // Select address and CS signals //---------------------------------------------------------------------------- void SetAddress(unsigned char cs, unsigned char adr) { DA0=((adr & 0x01)==0x01); DA1=((adr & 0x02)==0x02); DA2=((adr & 0x04)==0x04); if (cs==CTRL) { nCS1FX=1; nCS3FX=0; } else { nCS1FX=0; nCS3FX=1; } } //---------------------------------------------------------------------------- // Read data WORD from Drive //---------------------------------------------------------------------------- unsigned int ReadWORD(unsigned char cs, unsigned char adr) { unsigned int tmp; MSBDATA=ALLINPUT; LSBDATA=ALLINPUT; SetAddress(cs,adr); nDIOR=0; tmp=(MSBDATA<<8)+LSBDATA; nDIOR=1; nCS1FX=1; nCS3FX=1; return tmp; } //---------------------------------------------------------------------------- // Read data BYTE from Drive //---------------------------------------------------------------------------- unsigned char ReadBYTE(unsigned char cs, unsigned char adr) { unsigned char tmp; MSBDATA=ALLINPUT; LSBDATA=ALLINPUT; SetAddress(cs,adr); nDIOR=0; tmp=LSBDATA; nDIOR=1; nCS1FX=1; nCS3FX=1; return tmp; } //---------------------------------------------------------------------------- // Write data WORD to Drive //---------------------------------------------------------------------------- void WriteWORD(unsigned char cs, unsigned char adr, unsigned int dat) { SetAddress(cs,adr); // OBS MSB/LSB is swapped (see writeSector function) MSBDATA=dat; LSBDATA=(dat>>8); nDIOW=0; nDIOW=1; nCS1FX=1; nCS3FX=1; } //---------------------------------------------------------------------------- // Write data BYTE to Drive //---------------------------------------------------------------------------- void WriteBYTE(unsigned char cs, unsigned char adr, unsigned char dat) { SetAddress(cs,adr); MSBDATA=0; LSBDATA=dat; nDIOW=0; nDIOW=1; nCS1FX=1; nCS3FX=1; } //---------------------------------------------------------------------------- // Send Identify Command to Drive, and fetch resulting data //---------------------------------------------------------------------------- unsigned char IdentifyDrive(bit DriveNo, unsigned char *Buffer, tdefDriveInfo *DriveInfo) { unsigned int i; unsigned char Tmp; WriteBYTE(CMD, 6, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive WriteBYTE(CMD, 1, 0); WriteBYTE(CMD, 2, 1); WriteBYTE(CMD, 3, 1); WriteBYTE(CMD, 4, 0); WriteBYTE(CMD, 5, 0); WriteBYTE(CMD, 7, 0xEC); Timer10mSec=10000; while ((ReadBYTE(CMD,7) & 0x08)!=0x08 && Timer10mSec); // Wait for DRQ or timeout if (Timer10mSec==0) return 0xFF; // Fetch the data... MSBDATA=ALLINPUT; LSBDATA=ALLINPUT; // Select address and activate CS SetAddress(CMD, 0); // Two bytes at a time for (i=0; i<512; i+=2) { nDIOR=0; *(Buffer+i)=LSBDATA; *(Buffer+i+1)=MSBDATA; nDIOR=1; } // Disable CS nCS1FX=1; nCS3FX=1; // Extract drive info DriveInfo->Heads = (*(Buffer+7)<<8) + *(Buffer+6); DriveInfo->Tracks = (*(Buffer+3)<<8) + *(Buffer+2); DriveInfo->SectorsPerTrack = (*(Buffer+13)<<8) + *(Buffer+12); // Swap bytes, because of 16 bit transfer... for (i=0; i<40; i+=2) { Tmp=*(Buffer+54+i); *(Buffer+54+i)=*(Buffer+55+i); *(Buffer+55+i)=Tmp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -