?? 硬盤ide接口驅動程序.txt
字號:
/*********************************************************
硬盤ide接口驅動程序
CPU:AT89C51 CLOCK:24M
并行接口:82c55
**********************************************************/
#include <reg51.h>
#include <intrins.h>
#include "ide_interface.h"
sbit led = P3^5;
/* IDE初始化, 返回0,初始化失敗.返回1,成功! */
uchar IDE_Init()
{
uchar status;
uint i=0;
IDE_Write(IDE_HEAD, 0xE0);
do {
status = IDE_Read(IDE_STATUS);
}
while(!(status & 0x40)|(status & 0x80));/* 等待RDY為"1" BSY為"0" */
IDE_Write(IDE_HEAD, 0x20);
IDE_Write(IDE_SECCNT, 64);
IDE_Write(IDE_COMMAND, IDE_CMD_INIT);
IDE_Busy();
//printf("Time out,device error!\n");
IDE_Write(IDE_COMMAND, IDE_CMD_RECAL);
IDE_Busy();
//printf("Time out,device error!\n");
return 1; //初始化成功!
}
/* 從硬盤讀取一個扇區,放入到形參指定的內存中 */
void ReadSector(uint *addr, unsigned long LBA)
{
IDE_Busy();/* 等待硬盤空閑 */
WriteLBA(LBA);
IDE_Write(IDE_COMMAND,IDE_CMD_READ);
IDE_Ready();
ReadData(addr);
}
/* 向硬盤寫一個扇區,返回零表示成功,否則失敗。*/
uchar WriteSector(uint *addr, unsigned long LBA)
{
uchar i;
IDE_Busy();
WriteLBA(LBA);
IDE_Write(IDE_COMMAND,IDE_CMD_WRITE);
IDE_Ready();
WriteData(addr);
i = IDE_Busy();
if((i & 0x01)==0x01) {
i = GetError;
return i; /* 有錯誤發生,返回錯誤狀態值 */
}
return 0;
}
/* 取得錯誤號*/
uchar GetError()
{
uchar res;
res = IDE_Read(IDE_ERR); /* 取出低位字節 */
return res;
}
/* 讀取硬盤的標識。*/
void GetDriverId(uint *Buffer)
{
IDE_Busy();
IDE_Write(IDE_COMMAND,IDE_CMD_ID);
IDE_Ready();
ReadData(Buffer);
}
/* 激活硬盤(轉動)。*/
void SpinUP()
{
IDE_Write(IDE_COMMAND,IDE_CMD_SPINUP);
IDE_Busy();
}
/* 讓硬盤休眠(停轉)。*/
void SpinDown()
{
IDE_Busy();
IDE_Write(IDE_COMMAND,IDE_CMD_SPINDOWN);
IDE_Busy();
}
/* 從硬盤讀取512個字節。*/
void ReadData(uint xdata *Buffer)
{
uint i;
for(i = 0; i < 256; i ++)
{
*(Buffer ++) = IDE_Read(IDE_DATA);
}
}
/* 向硬盤寫入512個字節。 */
void WriteData(uint xdata *Buffer)
{
uint i;
for(i = 0; i < 256; i ++)
{
IDE_Write(IDE_DATA, *(Buffer++));
}
}
/* 向設備寄存器寫入邏輯塊地址*/
void WriteLBA(unsigned long LBA)
{
uint tmp_data = 0;
tmp_data |= ((LBA&0xFF000000) >> 24);
tmp_data &= 0x0F;
tmp_data |= 0xE0;
IDE_Write(IDE_HEAD, tmp_data);
tmp_data = 0;
tmp_data |= ((LBA&0xFF0000) >> 16);
IDE_Write(IDE_MSB, tmp_data);
tmp_data = 0;
tmp_data |= ((LBA&0xFF00) >> 8);
IDE_Write(IDE_LSB, tmp_data);
tmp_data = 0;
tmp_data |= (LBA&0xFF);
IDE_Write(IDE_SECTOR, tmp_data);
IDE_Write(IDE_SECCNT, 1);
}
/* 等待IDE設備空閑,返回設備的狀態. */
uchar IDE_Busy()
{
uchar res;
do
{
res = IDE_Read(IDE_STATUS);
}while(res & 0x80);
return res;
}
/* 等待設備空閑直到可以傳送數據,返回設備的狀態 */
uchar IDE_Ready()
{
uchar res;
do
{
res = IDE_Read(IDE_STATUS);
}while((res & 0x80)|(!(res & 0x08))); /* 等待DRQ=1,BSY=0 */
return res;
}
/* 通過8255讀取硬盤數據(一個16位的字)。 */
uint IDE_Read(uchar reg)
{
uint temp; uchar res;
CFG_8255 = RD_IDE_8255; /* 8255為輸入模式,讀硬盤。*/
IDE_8255_CTL= reg;
reg |= IDE_RD;
IDE_8255_CTL= reg;
_nop_;
temp = IDE_8255_MSB;
temp = (temp<<8) & 0xFF00;
res = IDE_8255_LSB;
temp = temp|res;
IDE_8255_CTL = 0x00; /* 清除控制寄存器。*/
return temp;
}
/* 通過8255向硬盤寫入一個字。 */
void IDE_Write(uchar reg,uint wr_data)
{
uchar tmp_data;
CFG_8255 = WR_IDE_8255; /* 8255為輸出模式,寫硬盤。*/
tmp_data = wr_data;
IDE_8255_LSB = tmp_data;/* 首先寫LSB。 */
tmp_data = (wr_data>>8);
IDE_8255_MSB = tmp_data;/* 繼續寫MSB。 */
IDE_8255_CTL = reg;
reg |= IDE_WR;
IDE_8255_CTL = reg;
_nop_;
IDE_8255_CTL = 0x00;/* 清除控制寄存器。 */
CFG_8255 = RD_IDE_8255; /* 8255為輸入模式,讀硬盤。*/
}
/* 硬盤復位操作,當初始化結束后需要復位。 */
void IDE_Reset()
{
CFG_8255 = WR_IDE_8255;/* 8255為輸出模式,寫硬盤。 */
IDE_8255_CTL = IDE_RST;
delay(10);
IDE_8255_CTL = 0x00;/* 清除控制寄存器。 */
}
/* 延時函數,延時ms級別 */
void delay(uint length) {
uint i;
do {
for (i=0;i<500;i++) {
}
length--;
}
while(length>0);
}
//測試程序部分
void main () {
uint i=1; unsigned long CurrentSector;
IDE_Reset();
if(IDE_Init()==1) {
for(i=0;i<3;i++){
led=0;
delay(50);
led=1;
delay(50);
}
}
GetDriverId(0x6000);
CurrentSector=0x00AA0000;
i=0;
do {
ReadSector(0x7000,CurrentSector);
CurrentSector++;
i++;
}
while(i<1953); /* 讀1MB的連續文件 */
SpinDown(); /* 硬盤停轉 */
for ( ; ; ) {
}
}
/*********************************************************
硬盤ide接口驅動程序
CPU:AT89C51 CLOCK:24M
并行接口:82c55
**********************************************************/
#include <absacc.h>
/***************type define****************/
#define uchar unsigned char
#define uint unsigned int
/******************************************/
/*以下是關于8255的一些定義:*/
#defineIDE_8255_LSB XBYTE[0x8000]/* 低8位 */
#defineIDE_8255_MSB XBYTE[0x8001]/* 高8位 */
#defineIDE_8255_CTL XBYTE[0x8002]
#defineCFG_8255 XBYTE[0x8003] /* 控制口 */
#defineRD_IDE_8255 0x92/*10010010b,8255輸入 */
#defineWR_IDE_8255 0x80/*10000000b,8255輸出 */
/*8255和IDE接口連接*/
#defineIDE_A0 0x01/* 8255和IDE接口直接相連 */
#defineIDE_A1 0x02/* 8255和IDE接口直接相連 */
#defineIDE_A2 0x04/* 8255和IDE接口直接相連 */
#defineIDE_CS0 0x08/* 8255和IDE接口通過74LS04反相后相連 */
#defineIDE_CS1 0x10/* 8255和IDE接口通過74LS04反相后相連 */
#defineIDE_WR 0x20/* 8255和IDE接口通過74LS04反相后相連 */
#defineIDE_RD 0x40/* 8255和IDE接口通過74LS04反相后相連 */
#defineIDE_RST 0x80/* 8255和IDE接口通過74LS04反相后相連 */
#defineIDE_DATAIDE_CS0
#defineIDE_ERRIDE_CS0 + IDE_A0
#defineIDE_SECCNTIDE_CS0 + IDE_A1
#defineIDE_SECTORIDE_CS0 + IDE_A1 + IDE_A0
#defineIDE_LSBIDE_CS0 + IDE_A2
#defineIDE_MSBIDE_CS0 + IDE_A2 + IDE_A0
#defineIDE_HEADIDE_CS0 + IDE_A2 + IDE_A1
#defineIDE_COMMANDIDE_CS0 + IDE_A2 + IDE_A1 + IDE_A0
#defineIDE_STATUSIDE_CS0 + IDE_A2 + IDE_A1 + IDE_A0
#defineIDE_CONTROLIDE_CS1 + IDE_A2 + IDE_A1
#defineIDE_ASTATUSIDE_CS1 + IDE_A2 + IDE_A1 + IDE_A0
/*IDE命令:*/
#defineIDE_CMD_RECAL 0x10
#defineIDE_CMD_READ 0x20
#defineIDE_CMD_WRITE 0x30
#defineIDE_CMD_INIT 0x91
#defineIDE_CMD_ID 0xEC
#defineIDE_CMD_SPINDOWN 0xE0
#defineIDE_CMD_SPINUP 0xE1
/*******************************函數定義*******************************/
uchar IDE_Init();
void ReadSector(uint *addr,unsigned long LBA);
uchar WriteSector(uint *addr, unsigned long LBA);
uchar GetError();
void GetDriverId(uint *Buffer);
void SpinUP();
void SpinDown();
void ReadData(uint xdata *Buffer);
void WriteData(uint xdata *Buffer);
void WriteLBA(unsigned long LBA);
uchar IDE_Busy();
uchar IDE_Ready();
uint IDE_Read(uchar reg);
void IDE_Write(uchar reg,uint wr_data);
void IDE_Reset();
void delay(uint length);
/**************************函數定義結束**********************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -