📄 ide.c
字号:
#include"IDE.h"
#define nop() __asm__ __volatile__ ("nop" ::)
void IDE_Delay(uint16 n)
{
while(n--);
}
uint8 IDE_WaitBSY()//等待空闲
{
uint8 timeout = 0;
uint8 temp;
do
{
temp = IDE_ReadREG(IDE_Status_Command);
timeout++;
// if(timeout>100)return 1;
}while(temp&(1<<BSY));
return 0;
}
uint8 IDE_WaitDRQ()//等待驱动器准备好传输数据
{
uint8 timeout = 0;
uint8 temp;
do
{
temp = IDE_ReadREG(IDE_Status_Command);
timeout++;
// if(timeout>100)return 1;
}while(!(temp&(1<<DRQ)));
return 0;
}
void IDE_RegConvert(uint8 reg)//设置读寄存器是的相应管脚
{
IDE_CS0_L();
IDE_CS1_H();
switch(reg)
{
case IDE_Data : IDE_DA2_L();IDE_DA1_L();IDE_DA0_L();break;
case IDE_Err_Features : IDE_DA2_L();IDE_DA1_L();IDE_DA0_H();break;
case IDE_SecCount : IDE_DA2_L();IDE_DA1_H();IDE_DA0_L();break;
case IDE_SecNumber : IDE_DA2_L();IDE_DA1_H();IDE_DA0_H();break;
case IDE_CylinderL : IDE_DA2_H();IDE_DA1_L();IDE_DA0_L();break;
case IDE_CylinderH : IDE_DA2_H();IDE_DA1_L();IDE_DA0_H();break;
case IDE_Device_Head : IDE_DA2_H();IDE_DA1_H();IDE_DA0_L();break;
case IDE_Status_Command : IDE_DA2_H();IDE_DA1_H();IDE_DA0_H();break;
default : IDE_CS0_H();break;
}
}
uint8 IDE_Init()//硬盘初始化
{
uint8 temp,retry = 0;
MCUCR &= ~(1<<SRE);//不采用总线方
IDE_RST_DDR |= 1<<IDE_RST_PIN;
IDE_RST_PORT |= 1<<IDE_RST_PIN;
IDE_CS0_DDR |= 1<<IDE_CS0_PIN;
IDE_CS0_PORT |= 1<<IDE_CS0_PIN;
IDE_CS1_DDR |= 1<<IDE_CS1_PIN;
IDE_CS1_PORT |= 1<<IDE_CS1_PIN;
IDE_DA0_DDR |= 1<<IDE_DA0_PIN;
IDE_DA0_PORT |= 1<<IDE_DA0_PIN;
IDE_DA1_DDR |= 1<<IDE_DA1_PIN;
IDE_DA1_PORT |= 1<<IDE_DA1_PIN;
IDE_DA2_DDR |= 1<<IDE_DA2_PIN;
IDE_DA2_PORT |= 1<<IDE_DA2_PIN;
IDE_WR_DDR |= 1<<IDE_WR_PIN;
IDE_WR_PORT |= 1<<IDE_WR_PIN;
IDE_RD_DDR |= 1<<IDE_RD_PIN;
IDE_RD_PORT |= 1<<IDE_RD_PIN;
IDE_RD_H();
IDE_WR_H();
IDE_RST_L();
IDE_Delay(0xffff);
IDE_RST_H();
for(retry = 0;retry < 20;retry++)IDE_Delay(0xffff);
do
{
IDE_WriteREG(IDE_Device_Head,0xa0);
temp = IDE_ReadREG(IDE_Status_Command);
if(retry++ >200)
{
MCUCR |= (1<<SRE);//重新使能总线
IDE_CS0_H();
return 1;
}
}while((!(temp&(1<<DRDY))) || temp&(1<<BSY));
IDE_WriteREG(IDE_Device_Head,0x40);
IDE_WriteREG(IDE_SecCount,60);
IDE_WriteREG(IDE_Status_Command,CMD_INITIALIZE_DRIVE_PARAMETERS);//0x91
IDE_WaitBSY();
IDE_WriteREG(IDE_Status_Command,CMD_RECALIBRATE);//0x10
IDE_WaitBSY();
IDE_CS0_H();
MCUCR |= (1<<SRE);//重新使能总线
return 0;
}
uint8 IDE_ReadREG(uint8 addr)//读寄存器
{
uint8 temp;
IDE_RegConvert(addr);
IDE_DATA_L_DDR = 0x00;
IDE_DATA_L_PORT = 0xff;
IDE_RD_L();
nop();
nop();
temp = IDE_DATA_L_PIN;
IDE_RD_H();
return temp;
}
void IDE_WriteREG(uint8 addr, uint8 val)//写寄存器
{
IDE_RegConvert(addr);
IDE_DATA_L_DDR = 0xff;
IDE_DATA_L_PORT = val;
IDE_WR_L();
nop();
nop();
IDE_WR_H();
}
uint8 IDE_ReadOneSector(uint32 LBA,uint8 *buffer)//读一个扇区
{
uint16 i;
MCUCR &= ~(1<<SRE);//关闭总线
IDE_WriteREG(6,0xe0 + (LBA>>24));//LBA方式,送LBA地址
IDE_WriteREG(5,LBA>>16);
IDE_WriteREG(4,LBA>>8);
IDE_WriteREG(3,LBA);
IDE_WriteREG(2,1); //读1个扇区
IDE_WriteREG(IDE_Status_Command,CMD_READ_SECTORS);//0x20//读命令
IDE_WaitDRQ();//等待数据准备好
IDE_RegConvert(IDE_Data);//设置相应地址
IDE_DATA_L_DDR = 0x00; //端口设为输入状态
IDE_DATA_L_PORT = 0xff;
IDE_DATA_H_DDR = 0x00;
IDE_DATA_H_PORT = 0xff;
for(i=0;i<512;)
{
IDE_RD_L();//1次读操作
nop();
nop();
buffer[i++] = IDE_DATA_L_PIN;
buffer[i++] = IDE_DATA_H_PIN;
IDE_RD_H();
}
MCUCR |= (1<<SRE); //重新使能总线
IDE_CS0_H(); //驱动器无效状态
return 0;
}
uint8 IDE_WriteOneSector(uint32 LBA,uint8 *buffer)//写一个扇区
{
uint16 i;
MCUCR &= ~(1<<SRE);//关闭总线
IDE_WriteREG(6,0xe0 + (LBA>>24));//LBA方式,送LBA地址
IDE_WriteREG(5,LBA>>16);
IDE_WriteREG(4,LBA>>8);
IDE_WriteREG(3,LBA);
IDE_WriteREG(2,1); //一次操作1个扇区
IDE_WriteREG(IDE_Status_Command,CMD_WRITE_SECTORS);//0x30//写命令
IDE_WaitDRQ();//等待驱动器准备好接受数据
IDE_RegConvert(IDE_Data);//设置相应地址
IDE_DATA_L_DDR = 0xff; //端口设为输出状态
IDE_DATA_H_DDR = 0xff;
for(i=0;i<512;)
{
IDE_DATA_L_PORT = buffer[i++];//写数据
IDE_DATA_H_PORT = buffer[i++];
IDE_WR_L();
nop();
nop();
IDE_WR_H();
}
MCUCR |= (1<<SRE);//重新使能总线
IDE_CS0_H(); //使驱动器处于无效状态
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -