相關(guān)元件pdf下載:max232acpe at89c51 知識(shí)是屬于全人類的。能將自己的成果無(wú)條件與人共享是偉大和受人尊敬的,同時(shí)也是一件幸福的事。由于我想得到幸福和受人尊敬,所以我也開(kāi)放我的工作成果。(其實(shí)也不算什么工作成果,匆匆忙忙用了一晚寫的,見(jiàn)笑了。在此感謝邵春偉同志,我在研究ata協(xié)議的時(shí)候參考了他寫的程序) 相信很多人都想用單片機(jī)控制硬盤來(lái)實(shí)現(xiàn)數(shù)據(jù)的海量?jī)?chǔ)存和開(kāi)發(fā)一些東西(如硬盤mp3),但網(wǎng)上關(guān)于此方面的資料不多,而真正給出原代碼和電路的更是鳳毛麟角,而且就算給出原程序,但不知是因?yàn)槭鞘д`或是本身還未理解好ata協(xié)議,抑或是出于對(duì)知識(shí)產(chǎn)權(quán)的保護(hù)問(wèn)題,程序中有著或大或少的錯(cuò)誤。本程序只是一個(gè)演示,還不是很完善,只是給你開(kāi)發(fā)ata程序作一個(gè)參考,但我保證絕對(duì)可以使用。當(dāng)然你可以修改和擴(kuò)充一下,變成一個(gè)完善的ata驅(qū)動(dòng)程序。特征與使用 程序中所有與單片機(jī)本身硬件有關(guān)的參數(shù)都在程序開(kāi)始處作出定義,移植到其他類型單片機(jī)時(shí)只需修改一下引腳定義就行了。使用時(shí)注意根據(jù)你的硬盤修改一下相應(yīng)的參數(shù)(在程序中有注解)。使用步驟與運(yùn)行效果 連接好電路(很簡(jiǎn)單),在把程序燒進(jìn)芯片。先接通硬盤電源,再打開(kāi)任意一個(gè)串口調(diào)試程序,把波特率設(shè)置成57600bps,再運(yùn)行單片機(jī)即可。效果與下:源程序:#include /*************************************************** harddisk control demo * power by dddlzhu* 編譯環(huán)境 : keil c51 v7.07 支持器件 : at89c51 * copyright (c) 2004 ***************************************************/#define byte unsigned #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 _devicehead 0xe#define _status_comm 0xf//**************************************************************************************//*這里為初始化硬盤的重要參數(shù),每個(gè)硬盤的參數(shù)都不盡相同。若不正確則讀不了盤中的數(shù)據(jù)。計(jì)算方法如下:先看清楚你的 硬盤表面標(biāo)簽中的數(shù)據(jù),里面有三個(gè)重要參數(shù):1。柱面數(shù)(cylinder)2。磁頭數(shù)(head)3。磁道數(shù)(sect)其中 _maxhead=0xa+head _maxsect=sect例如我的130m硬盤(很老吧,哈哈),磁頭數(shù)為15,十六進(jìn)制為0xf,所以_maxhead=0xaf,磁道數(shù)為17,所以_maxsect=0x11*/#define _maxhead 0xaf#define _maxsect 0x11//************************************************************************************byte bdata status=0x00;sbit err=status^0;sbit idx=status^1;sbit cr=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 cr idx err *bsy:驅(qū)動(dòng)器忙; *drdy:驅(qū)動(dòng)器準(zhǔn)備好; *dwf:驅(qū)動(dòng)器寫失??; *dsc:尋道結(jié)束; *drq:請(qǐng)求服務(wù),驅(qū)動(dòng)器希望通過(guò)數(shù)據(jù)寄存器與cpu交換一字節(jié)數(shù)據(jù);*cr:當(dāng)可以糾正的讀錯(cuò)誤發(fā)生時(shí),該位置1,數(shù)據(jù)傳輸將繼續(xù)進(jìn)行 *idx:收到綜引信號(hào); *err:命令執(zhí)行出錯(cuò)。 **************************************************************/byte data_bufferh=0x0;byte data_bufferl=0x0;//***************串口子程序void send_string(unsigned *wd);void send_(unsigned wd);unsigned get_(void);//8888888888888888888888/*******************************************************:延遲函數(shù) ********************************************************/ void delay(byte ms){ byte i,j;f(i=0;i=254) return(0xff);}while(bsy);return(1);}/******************************************************寫寄存器值********************************************************/void writereg(byte addr,byte data){regaddr=addr;write=0;datal=data;write=1;}/*******************************************************讀數(shù)據(jù)儲(chǔ)存器中數(shù)據(jù)********************************************************/void readdata(void){datah=0xff;datal=0xff;regaddr=_data;read=0;data_bufferl=datal;data_bufferh=datah;read=1;}/*******************************************************寫數(shù)據(jù)寄存器中數(shù)據(jù)********************************************************/void writedata(void){regaddr=_data;write=0;datal=data_bufferl;datah=data_bufferh;write=1;}/**********************************************************初始化硬盤 ************************************************************/void init(void){ do{ writereg(_devicehead,0xa0); readreg(_status_comm); }while(!drdy|bsy); writereg(_devicehead,_maxhead); writereg(_seccount,_maxsect); writereg(_status_comm,0x91);waitbsy(); writereg(_status_comm,0x10);waitbsy();} /**********************************************************讀硬盤參數(shù)***********************************************************/ 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_comm,0xec);//send_string("waiting.. ");do{readreg(_status_comm);}while(bsy|!drq);//send_string("now sending \n");while(i){readdata();send_(data_bufferh);send_(data_bufferl);i-=2;}}/*********************************************************硬盤尋址**********************************************************/writechs(byte head,uint cylinder,byte sect,byte read_count){waitbsy();writereg(_devicehead,0xa0|head);writereg(_cylinderh,()(cylinder>>8)); writereg(_cylinderl,()(cylinder&0x00ff));writereg(_secnum,sect); writereg(_seccount,read_count);}/***********************************************************用途:將硬盤的返回?cái)?shù)據(jù)讀入buffer數(shù)組 ************************************************************/void senddata(){ uint i;i=512*15;do{readreg(_status_comm);}while(bsy|!drq);if(err){ send_string("\x0d\x0a err\x0d\x0a"); }while(i){readdata();send_(data_bufferl);send_(data_bufferh);i-=2;}}// 激活硬盤(轉(zhuǎn)動(dòng))void spinup(){waitbsy(); writereg(_status_comm,0xe1);}// 讓硬盤休眠(停轉(zhuǎn))/void spindown(){waitbsy(); writereg(_status_comm,0xe0);}void main(void){//initialize scon=0x50; //串口初始化tmod=0x20; //波特率為57600bpstcon=0x40;pcon=0x80;th1=0xff;tl1=0xff;tr1=1;send_string("ide control demo. power by dddlzhu\x0d\x0a");//send welcome wdrst=0; //ide 復(fù)位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(); //讀硬盤idsend_string("\n\nnow read the first sect on this harddisk\x0d\x0a\x0d\x0a");delay(244);delay(244);delay(244);delay(244);writechs(0,0,1,16); //寫地址waitbsy();writereg(_status_comm,0x20); //發(fā)送讀命令senddata();send_string("\x0d\x0a\x0d\x0a read ok,now shut down the harddisk..\x0d\x0a");spindown(); //硬盤停轉(zhuǎn) while(1);}//**************************************串口子程序void send_(unsigned wd){ ti=0;sbuf=wd;while(ti==0);ti=0;}void send_string(unsigned *wd){ ti=0;while(*wd!=0) { sbuf=*wd; while(ti==0); ti=0; wd++; }}unsigned get_(void){ ri=0;ren=1;while(ri==0);return(sbuf);ri=0;ren=0;}//88888888888888888888888888888888888888888