⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide.c

📁 ide的低层驱动程序。一个工程(cpld+dsp)的一部分。
💻 C
字号:
#include ".\h_file\system.h"

#define IdeDalayValue   100000

extern void Delay(unsigned int Value);	//位于GeneralFunc.c

extern void IdeStandby(void);
extern void IdeIdle(void);

extern unsigned short buffers[256];
uchar aa;

/************************************************************************/
/*																		*/
/************************************************************************/
void IdeStandby(void)
{
	*pCommand = 0xe0;
}

void IdeIdle(void)
{
	*pCommand = 0x95;
}


unsigned char IdeWriteSector_LBA(  unsigned int  SectorNum)		//要写入数据的扇区号
{
	unsigned int i=0;
	unsigned int sum1=0,sum2=0;
	unsigned char errorstatus=0;
	unsigned char result=0;
	unsigned char ERRbit=0;
	unsigned char SectorNum0=0,SectorNum1=0,SectorNum2=0,SectorNum3=0;

	SectorNum0  = (unsigned char)(SectorNum & 0x000000ff);		  //扇区号的0字节
	SectorNum1  = (unsigned char)((SectorNum >> 8) & 0x000000ff); //扇区号的1字节
	SectorNum2  = (unsigned char)((SectorNum >> 16) & 0x000000ff); //扇区号的1字节
	SectorNum3  = (unsigned char)((SectorNum >> 24) & 0x000000ff); //扇区号的1字节
	
		
IDEREADLAB1:
	do
	{
		result = *pStatus;
	}while( result != 0x50 );
	
	if(result == 0x50)		//DRDY = 1:驱动器准备好; DSC = 1:寻道结束;
		{
		*pPreComp 		= 0x00;		//特性寄存器写入0
		*pSectorCount 	= 0x01;		//扇区数=1
		*pSectorNumber 	= SectorNum0;	//扇区号=传输值
		*pCylinderLow 	= SectorNum1;	//柱面号低字节
		*pCylinderHigh 	= SectorNum2;	//柱面号高字节
		*pDriveHead 	= 0xe0+SectorNum3;	//采用LBA模式,主驱动器,磁头为1
		*pCommand 		= 0x31;//write	//31H是写扇区命令

IDEREADLAB2:
		do
		{
			result = *pStatus;
		}while( ( result & 0x08 ) != 0x08 );
		
		if(result == 0x58)
			{
			for(i=0;i<256;i++)
				{
				*pDataPort = buffers[i];//write
				}
			result = *pStatus;
			ERRbit = result & 0x01;
			if(ERRbit == 0)//ok
				{return(0);
				}
			else
				{errorstatus = *pErrorReg;
				return(errorstatus);
				}
			}
		else//timeout process
			{Delay(IdeDalayValue);
			sum2++;
			if(sum2<1000)
				{goto IDEREADLAB2;
				}
			else
				{errorstatus = *pErrorReg;
				return(errorstatus);
				}
			}
		}
	else//timeout process
		{Delay(IdeDalayValue);
		sum1++;
		if(sum1<10)
			{goto IDEREADLAB1;
			}
		else
			{errorstatus = *pErrorReg;
			return(errorstatus);
			}
		}	
}


unsigned char IdeReadSector_LBA(  unsigned int  SectorNum)		//要读出数据的扇区号
							  
{
	unsigned int i=0,j=0;
	unsigned int sum1=0,sum2=0;
	unsigned char errorstatus=0;
	unsigned short result=0;
	unsigned char ERRbit=0;
	unsigned char SectorNum0=0,SectorNum1=0,SectorNum2=0,SectorNum3=0;

	SectorNum0  = (unsigned char)(SectorNum & 0x000000ff);		  //扇区号的0字节
	SectorNum1  = (unsigned char)((SectorNum >> 8) & 0x000000ff); //扇区号的1字节
	SectorNum2  = (unsigned char)((SectorNum >> 16) & 0x000000ff); //扇区号的1字节
	SectorNum3  = (unsigned char)((SectorNum >> 24) & 0x000000ff); //扇区号的1字节
		
IDEREADLAB1:
	
	do
	{
		result = *pStatus;	//读硬盘状态
		if ( result == 0x01 )
		  {
		  	ERRbit = *pErrorReg;
		  }
		aa = result & 0x80;
	}while(  result != 0x50 );
	
	if(result == 0x50)	//DRDY = 1:驱动器准备好; DSC = 1:寻道结束;(50H)
		{
		*pPreComp 		= 0x00;	//特性寄存器写入0
		*pSectorCount 	= 0x01;	//扇区数=1
		*pSectorNumber 	= SectorNum0;	//扇区号=传输值
		*pCylinderLow 	= SectorNum1;	//柱面号低字节
		*pCylinderHigh 	= SectorNum2;	//柱面号高字节
		*pDriveHead 	= 0xe0+SectorNum3;	//采用CHS模式,主驱动器,磁头为1
		*pCommand 		= 0x20;//read	//21H是读扇区命令

IDEREADLAB2:
		do
		{
			result = *pStatus;	//读硬盘状态
			if ( result == 0x01 )
		  	  {
		  		ERRbit = *pErrorReg;
		      }
		}while( ( result & 0x08 ) != 0x08 );
		
		if(( result & 0x08 ) == 0x08)	//DRDY = 1:驱动器准备好; DSC = 1:寻道结束;DRQ = 1:请求服务;(58H)
			{
			for(i=0;i<256;i++)
				{
				buffers[i] = *pDataPort;//read
				}
			result = *pStatus;	//读硬盘状态
			aa = result & 0x08;
			
			ERRbit = result & 0x01;	//查询是否有错误
			if(ERRbit == 0)//ok
				{return(0);		//没有错误则返回0
				}
			else
				{errorstatus = *pErrorReg;	//有错,则返回错误类型
				return(errorstatus);
				}
			}
		else//timeout process	//送出读扇区命令后,若硬盘没有准备好则执行
			{Delay(IdeDalayValue);	//调延时程序
			sum2++;			//sum2+1,用于表示查询次数
			if(sum2<1000)	
				{goto IDEREADLAB2;	//若小于指定次数则继续查询
				}
			else						//超时
				{errorstatus = *pErrorReg;	//若等于指定次数,则说明有错,读错误寄存器
				return(errorstatus);	//返回错误类型
				}
			}
		}
	else//timeout process	//初始读硬盘时,硬盘没准备好
		{Delay(IdeDalayValue);	//调用延时程序
		sum1++;				//次数加1
		if(sum1<10)	
			{goto IDEREADLAB1;	//少于指定次数,则继续查询
			}
		else						//超时
			{errorstatus = *pErrorReg;	//等于指定次数,则出错
			return(errorstatus);		//返回错误状态
			}
		}	
}










⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -