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

📄 test.c

📁 msp430f149读写CF卡操作
💻 C
📖 第 1 页 / 共 4 页
字号:
  _NOP();     //<1uS指令周期
}

/*********************************************************************************************************
** 函数名称: ATA_HaveCard
** 功能描述: 判断CF卡是否连接到,CF卡的CD1、CD2引脚与GND直接相接,可以通过该引脚判断CF卡是否存在
**			 (对于IDE硬盘也有也多共地的引脚,也可以像CF卡那样检测但是这点ATA规范中并没有说明)。
**			 如果硬件上没有相关的检测,则应一直返回TRUE。
** 输   入: 无
** 输   出: TRUE,如果有设备存在,不管设备是主或是从,或可以返回TRUE(1);
**			 FALSE,如果设备不存在,即返回FALSE(0)
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
uint8 SYS_HaveCard(void)
{

#define	DEVICE_IS_ATTACHED 	0		/*硬件设备没有检测CF CARD是否存在*/


	if(DEVICE_IS_ATTACHED)			/*如果DEVICE_IS_ATTACHED为0却有设备存在,为1即没有*/
		return FALSE;			/*DEVICE_IS_ATTACHED不为0,没有设备存在,返回FALSE*/
	else
		return TRUE;			/*DEVICE_IS_ATTACHED为0,有设备存在,返回TRUE*/
}


/*********************************************************************************************************
** 函数名称: SYS_PortIn
** 功能描述: 从ATA设备指定的寄存器中读出一个字的数据,有些寄存器只有一个字节数有效。
** 输   入: reg 寄存器名称
** 输   出: 读出的数据
** 全局变量: 无
** 调用模块: OS_ENTER_CRITICAL(),关中断
**			 OS_EXIT_CRITICAL(),清中断
********************************************************************************************************/
uint16 SYS_PortIn(uint8 reg)
{
	uint16 res ;
    OS_ENTER_CRITICAL();  						/*关中断*/  
    CF_ADDR_DIR = 0XFF;
    CF_DATA_DIR = 0;
    CF_ADDR_OUT &= ~(A2 + A1 + A0 + CS1 + CS0);
    CF_ADDR_OUT |= reg;
    /*读低字节*/
    CF_ADDR_OUT &= ~RD;
    res = (uint8)CF_DATA_IN;
    CF_ADDR_OUT |= RD;
    /*读高字节*/
    if(reg==ATA_REG_DATA)						/*如果读数据寄存器,读高字节*/
    {	
    	CF_ADDR_OUT &= ~RD;
    	res += ((uint16)CF_DATA_IN<<8);
    	CF_ADDR_OUT |= RD;
    }
    
    CF_ADDR_OUT |= A2 + A1 + A0 + CS1 + CS0;						/*输出控制信号置高*/  
	OS_EXIT_CRITICAL();							/*开中断*/
    return res;									/*返回数值*/
}


/*********************************************************************************************************
** 函数名称: SYS_PortOut
** 功能描述: 向ATA设备指定的寄存器中写入一个字的数据,有些寄存器只有一个字节数有效。
** 输   入: reg 寄存器名称
** 输   出: 无
** 全局变量: 无
** 调用模块: OS_ENTER_CRITICAL(),关中断
**			 OS_EXIT_CRITICAL(),清中断
********************************************************************************************************/

void SYS_PortOut(uint8 reg, uint16 data)
{	 
	OS_ENTER_CRITICAL();					/*关中断*/
	CF_DATA_DIR = 0XFF;
	CF_ADDR_OUT &= ~(A2+A1+A0+CS1+CS0);
	CF_ADDR_OUT |= reg;
	CF_DATA_OUT = 0;
	CF_DATA_OUT = (uint8)data;
	CF_ADDR_OUT &= ~WR;/*写信号为低电平,保持大于165nS*/
	CF_ADDR_OUT |= WR;/*写信号脚置高[与低>162ns]*/
					
	
	if(reg==ATA_REG_DATA)				/*如果访问的寄存器为16位的数据寄存器*/
	{	/*写高字节*/
   		CF_DATA_OUT = 0;
   		CF_DATA_OUT = (uint8)(data>>8);
   		CF_ADDR_OUT &= ~WR;
   		CF_ADDR_OUT |= WR;
   	}
   	 
    CF_ADDR_OUT |= A2+A1+A0+CS1+CS0;
    CF_DATA_DIR=0;  
	OS_EXIT_CRITICAL();						/*开中断*/
}



/*********************************************************************************************************
** 函数名称: SYS_IdeHardReset
** 功能描述: ATA设备硬件复位
** 输   入: 无
** 输   出: 无
** 全局变量: 无
** 调用模块: SYS_WaitInUS(),等待微秒函数。
********************************************************************************************************/
void SYS_IdeHardReset(void)
{
    CF_ADDR_DIR &= ~RST;					/*复位引脚置低    */
    SYS_WaitInUS(30); 					/*延时大于25微秒  */
  	CF_ADDR_DIR |= RST;					/*复位引脚置高    */
   	
   	SYS_WaitInUS(5000);  				/*延时大于2毫秒,设备通常在480ms内完成硬件初始化和自诊断*/
										
}
/*********************************************************************************************************
** 函数名称: ATA_GetStatus					所在文件:IDE.C
** 功能描述: 读取ATA状态寄程器
** 输   入: Status,存放状态值的变量指针
** 输   出: 无
** 全局变量: THIS_DEVICE,当前选中的设备
**			 ATA,设备信息数据结构
** 调用模块: GetAStatus(),读辅助状态寄存器
**			 GetStatus(),读状态寄存器
**			 GetERR(),读错误寄存器
********************************************************************************************************/
void ATA_GetStatus(uint8 *Status)
{	
	if(SYS_HaveCard())				 
	{	
		GetAStatus();				/*读助状态寄存器不作处理,以保证读状态寄存器返回有效的值*/
		*Status = (uint8)GetStatus();			/*读取ATA设备状态*/

		if((*Status)&ATA_STAT_REG_BSY)		/*设备状态寄存器BSY位为1,其它位无效*/
		{
			*Status = ATA_STAT_REG_BSY;	/*BSY位为1其它位无效,屏蔽其它位*/
			ATA[THIS_DEVICE].ERRCODE = CARD_IS_TRUE;			/*清错误码率代码*/
		}
		else						/*设备不忙*/
		{
			if((*Status) & ATA_STAT_REG_ERR)			/*设备是否出错*/
			{  													/*设备出错*/
				ATA[THIS_DEVICE].ERRCODE 
					= (uint8)GetERR();			/*读取出错代码,保存出错代码,以便查询*/
				if(ATA[THIS_DEVICE].ERRCODE & ATA_EER_REG_IDNF)		/*如果是寻址出错,即记录出错的扇区号*/
				{	
					ATA[THIS_DEVICE].ERRSECTOR  
						= (uint8)GetSector();		/*读出首次错误的扇区号LBA7~0*/
					ATA[THIS_DEVICE].ERRSECTOR 
					   |= ((uint8)GetCylinderLow())*0x100;	/*读出首次错误的扇区号LBA15~8*/
					ATA[THIS_DEVICE].ERRSECTOR 
					   |= ((uint8)GetCylinderHigh())*0x10000;/*读出首次错误的扇区号LBA23~16*/
					ATA[THIS_DEVICE].ERRSECTOR 
					   |= ((uint8)GetDeviceHead()&0x0f)*0x1000000;	/*读出首次错误的扇区号LBA27~4*/
				}
					
			}
			else
				if(*Status==0)					/*如果状态全为0,该设备是无效的*/
				{
					ATA[THIS_DEVICE].ERRCODE = CARD_IS_FALSE;	/*设备无效*/
					*Status = CARD_IS_FALSE;					/*返回函数结果*/
				}
				else
				{					
					ATA[THIS_DEVICE].ERRCODE = CARD_IS_TRUE;	/*清错误码率代码*/	
				}
		}
		
	}
	else
	{	
		*Status = CARD_IS_FALSE;								/*设备不可用*/
		ATA[THIS_DEVICE].ERRCODE = CARD_IS_FALSE;				/*设备不可用*/
		ATA[THIS_DEVICE].ATAIsOK = FALSE;						/*设备不可用*/
	}
}
/*********************************************************************************************************
** 函数名称: ATA_WaitOnBusyNDrdy					所在文件:IDE.C
** 功能描述:  设备忙等待直到设备不忙并设备准备好.
** 输   入: 无
** 输   出: 设备出错返回0
** 全局变量: ATA,数据结构体
** 调用模块: ATA_GetStatus(),读取状态函数
********************************************************************************************************/
uint8 ATA_WaitOnBusyNDrdy(void)
{	
   	uint8	ATAStatus;
   	uint32 	timeout;
		
	for(timeout=0;timeout<TIMEOUTSET;timeout++)	/*超时返回,即多次读取,在读取一定的次数还没得到需要的状态就认为超时*/
	{
		ATA_GetStatus(&ATAStatus);								/*获取设备状态*/
	
		if( ATAStatus==CARD_IS_FALSE)							/*该设备有错误或无效*/
			return FALSE;										/*返回失败*/
		
		if(ATAStatus&ATA_STAT_REG_ERR)							/*如果设备出错*/
			return FALSE;
		
		if(ATA_STAT_REG_DRDY==(ATAStatus&ATA_STAT_BSY_DRDY))	/*如果设备准备好返回*/
  			return TRUE;
    }
	
	ATA[THIS_DEVICE].ERRCODE = CARD_TIMEOUT;					/*标志超时出错*/ 
	ATA[THIS_DEVICE].ERRSECTOR = -1;							/*清错误扇区号*/ 
	return FALSE;
}


/*********************************************************************************************************
** 函数名称: ATA_WaitOnBusyNDrq					所在文件:IDE.C
** 功能描述: 设备忙等待直到设备不忙并有数据传输请求时.
** 输   入: 无
** 输   出: 设备出错返回0
** 全局变量: ATA[THIS_DEVICE].ERRCODE,出错代码
**		     ATA[THIS_DEVICE].ERRSECTOR,出错扇区号
** 调用模块: ATA_GetStatus(),读取状态函数
********************************************************************************************************/
uint8 ATA_WaitOnBusyNDrq(void)
{
	uint8	ATAStatus;
    uint32 timeout;

	for(timeout=0;timeout<TIMEOUTSET;timeout++)	/*超时返回,即多次读取,在读取一定的次数还没得到需要的状态就认为超时*/
	{	
		ATA_GetStatus(&ATAStatus);								/*获取设备状态*/
		if(ATAStatus==CARD_IS_FALSE)							/*卡有错误*/
			return FALSE;
		
		if(ATAStatus&ATA_STAT_REG_ERR)							/*如果设备出错*/
			return FALSE;

		if(ATA_STAT_REG_DRQ==(ATAStatus&ATA_STAT_BSY_DRQ))		/*有数据传输请求*/
       		return TRUE;
 	}
	ATA[THIS_DEVICE].ERRCODE = CARD_TIMEOUT;					/*标志超时出错*/
	ATA[THIS_DEVICE].ERRSECTOR = -1;							/*清错误扇区号*/
	return FALSE;
}


/*********************************************************************************************************
** 函数名称: ATA_WaitOnBusy					所在文件:IDE.C
** 功能描述: 设备忙等待
** 输   入: 无
** 输   出: 出错返回0
** 全局变量: ATA[THIS_DEVICE].ERRCODE,出错代码
**		     ATA[THIS_DEVICE].ERRSECTOR,出错扇区号
** 调用模块: ATA_GetStatus(),读取状态函数
********************************************************************************************************/
uint8 ATA_WaitOnBusy(void)
{
	uint8	ATAStatus;
    	uint32 	timeout;

	for(timeout=0;timeout<TIMEOUTSET;timeout++)	/*超时返回,即多次读取,在读取一定的次数还没得到需要的状态就认为超时*/
	{
		ATA_GetStatus(&ATAStatus);							/*读取状态寄存器*/
		if(ATAStatus==CARD_IS_FALSE)						/*卡有错误*/
			return FALSE;							/*返回设备发生了错误*/

		if((ATAStatus & ATA_STAT_BSY_DRQ)==0)					/*设备不忙,*/
  			return TRUE;									/*正常返回*/
	}
	
	ATA[THIS_DEVICE].ERRCODE = CARD_TIMEOUT;				/*标志超时出错*/
	ATA[THIS_DEVICE].ERRSECTOR = -1;						/*清错误扇区号*/
	return FALSE;
}



/*********************************************************************************************************
** 函数名称: ATA_SelectDevice					所在文件:IDE.C
** 功能描述: 选择主从设备
** 输   入: Device,0为主设备,1为从设备
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA_DevReg
** 调用模块: SetDeviceHead(),写设备寄存器
**			 ATA_WaitOnBusy(),等待设备不忙
********************************************************************************************************/
uint8 ATA_SelectDevice(uint8 Device)
{
	ATA_WaitOnBusy();									/*等待设备不忙*/
	if(Device>0)										/*选择的为从设备*/
		ATA_DevReg = ATA_DevReg_DEV1 + 					/*选择设备0*/
    			 	 ATA_DevReg_b5 +
    			 	 ATA_DevReg_LBA+					/*工作在LAB模式*/
    			 	 ATA_DevReg_b7;	
	else												/*选择的为主设备*/
		ATA_DevReg = ATA_DevReg_DEV0 + 					/*选择设备0*/
    			 	 ATA_DevReg_b5 +
    			 	 ATA_DevReg_LBA +					/*工作在LAB模式*/
    			 	 ATA_DevReg_b7;			
    			 	 
    SetDeviceHead(ATA_DevReg);							/*写设备磁头寄存器*/
   
    return ATA_WaitOnBusy();							/*等待设备不忙,返回状态*/

}



/*********************************************************************************************************
** 函数名称: ATA_CommandSet
** 功能描述: 指令设置相关的寄存器。
** 输   入: Feature,特征寄存器
**			 SecCnt,扇区计数寄存器
**			 SecNum,扇区号寄存器
**			 CylLow,柱面低寄存器
**			 CylHigh,柱面高寄存器
**			 C_D_H,设备磁头寄存器
**			 Command,指令寄存器 
** 输   出: 无
** 全局变量: 无
** 调用模块: SetFeature(),写Feature,特征寄存器
**			 SetSECCNT(),写SecCnt,扇区计数寄存器
**			 SetSector(),写扇区号寄存器
**			 SetCylinderLow(),写柱面低寄存器
**			 SetCylinderHigh(),写柱面高寄存器
**    		 SetDeviceHead(),写设备磁头寄存器
**			 SetCommand(),写指令寄存器
********************************************************************************************************/
void ATA_CommandSet(uint8 Feature,
					uint8 SecCnt,
					uint8 SecNum,
					uint8 CylLow,
					uint8 CylHigh,
					uint8 C_D_H,
					uint8 Command 
					)
{
	SetFeature(Feature);			/*Feature,特征寄存器*/
   	SetSECCNT(SecCnt);				/*SecCnt,扇区计数寄存器*/
	SetSector(SecNum);				/*SecNum,扇区号寄存器*/
	SetCylinderLow(CylLow);			/*CylLow,柱面低寄存器*/

⌨️ 快捷键说明

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