<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x

    硬盤控制電路以及源程序

    發布時間:2011-6-22 11:45    發布者:circuit_share
    關鍵詞: 控制電路 , 硬盤 , 源程序


    知識是屬于全人類的。能將自己的成果無條件與人共享是偉大和受人尊敬的,同時也是一件幸福的事。由于我想得到幸福和受人尊敬,所以我也開放我的工作成果。(其實也不算什么工作成果,匆匆忙忙用了一晚寫的,見笑了。在此感謝邵春偉同志,我在研究ata協議的時候參考了他寫的程序)

    相信很多人都想用單片機控制硬盤來實現數據的海量儲存和開發一些東西(如硬盤mp3),但網上關于此方面的資料不多,而真正給出原代碼和電路的更是鳳毛麟角,而且就算給出原程序,但不知是因為是失誤或是本身還未理解好ata協議,抑或是出于對知識產權的保護問題,程序中有著或大或少的錯誤。本程序只是一個演示,還不是很完善,只是給你開發ata程序作一個參考,但我保證絕對可以使用。當然你可以修改和擴充一下,變成一個完善的ata驅動程序。

    特征與使用

    程序中所有與單片機本身硬件有關的參數都在程序開始處作出定義,移植到其他類型單片機時只需修改一下引腳定義就行了。使用時注意根據你的硬盤修改一下相應的參數(在程序中有注解)。

    使用步驟與運行效果

    連接好電路(很簡單),在把程序燒進芯片。先接通硬盤電源,再打開任意一個串口調試程序,把波特率設置成57600bps,再運行單片機即可。效果與下:



    源程序:

    #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 D2D1 D0*
    BSYDRDYDWFDSC DRQCORRIDX 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);
    //8888888888888888888888
    /*******************************************************
    :延遲函數
    ********************************************************/
    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;
    }
    //88888888888888888888888888888888888888888
    本文地址:http://www.portaltwn.com/thread-69271-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • 我們是Microchip
    • 想要避免發生災難,就用MPLAB SiC電源仿真器!
    • 深度體驗Microchip自動輔助駕駛應用方案——2025巡展開啟報名!
    • 利用模擬開發工具生態系統進行安全電路設計
    • 貿澤電子(Mouser)專區

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷