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

📄 sd.c

📁 SdCard_V2.1TinyFatFs.rar是单片机实现SD卡功能的FAT文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
    for(RetryCount1 = 0; RetryCount1 < 15; RetryCount1++)
    {
        ReadyForData = false;
        for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
        {
            *((UINT32 *)(&SdCmdBuf[1])) = RCA;
            Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
            if(Status != STATUS_SUCCESS)
                continue;  
            if(SdRespBuf[3] & 0x01) // READY_FOR_DATA in Card Status
            {
                ReadyForData = true;
                break;
            }
        }        
        if(!ReadyForData){
			CmdTimer=3;
			while(CmdTimer);
            continue;
		}
		
		SDMI_BUFBASE=(DMA_FIFOB0>>8);
      
if(SdHcFlag) {			  //Derek 2007.07.02
		*((UINT32 *)(&SdCmdBuf[1])) = SectorStart;
} else
        *((UINT32 *)(&SdCmdBuf[1])) = 
            SectorStart << BYTES_PER_SECTOR_SHIFT;

//***********************
    	if (SectorCount > 1) // Muti-Read.
        {    
			SDMI_CTL|=bmSD_AUTO_CLK_EN;    	
      		Status = SdSendCmd(READ_MUL_BLOCK, SdCmdBuf);
     		if(Status != STATUS_SUCCESS)
            	continue;
        }
     	else
        {
			SDMI_CTL &= ~bmSD_AUTO_CLK_EN; //2007.01.18
   			Status = SdSendCmd(READ_BLOCK, SdCmdBuf);

    		if(Status != STATUS_SUCCESS)
        		continue;
			else
			 memcpy(buff, (BYTE xdata *)DMA_FIFOB0, 512);
       	}
//*******************************   
      if(SDMI_ST&bmSD_CRC16_ERR)
        {
            SDMI_ST &=~bmSD_CRC16_ERR;
            continue;
        }
        else
            return STATUS_SUCCESS;
    }
    return STATUS_FLASH_ERROR;

}

/*
//----------------------------------------------------------------------------
//  Description:
//    Read one of the other sectors,except the first sector, 
//	  when execute multi-read command.
//----------------------------------------------------------------------------
#pragma OPTIMIZE(4)
STATUS SdReadNextSectorData(void)
{
  STATUS Status;
  bit Stop;

  Stop = SectorCount == 1;//
	if (!SdCardExist())
   		return STATUS_FLASH_ERROR;//如果卡拔出,直接返回!!
 
//	SDMI_BUFBASE = (FIFO_ADDRESS_IN>>8);

	SDMI_CMD=SD_CMD_RX_DATA_ONLY;  	
	SDMI_CTL|=bmSD_AUTO_CLK_EN;    	
	if ((Status = SdWaitCmd()) != STATUS_SUCCESS)
		return Status;		 

	if(SDMI_ST&bmSD_CRC16_ERR) // CRC7 Error
	{
		SDMI_ST&=~bmSD_CRC16_ERR; // Clear INT
		return STATUS_DATA_ERROR;
	}

	if (Stop) 
		return SdStopCmd();//所有block的数据已传输完毕,停止命令

	return STATUS_SUCCESS;
}	*/

/*

STATUS SdReadNextSector(void)
{
    BYTE	RetryCount;
	STATUS Status;
	Status = SdReadNextSectorData();
    if(Status != STATUS_SUCCESS)
	{
		for(RetryCount = 0 ; RetryCount < 15; RetryCount ++)
		{
			Status = SdStopCmd();
			if(Status != STATUS_SUCCESS)
				continue;
			Status = SdReadOneSector();
				break;
		}	
	}
    SectorStart ++;
    return Status;
}	*/


//--------------------------------------------------------------------
// Write single sector of data to SD/MMC,
// or write the first sector when execute multi-write command.
//--------------------------------------------------------------------
STATUS SdWriteOneSector(BYTE*buff, DWORD sector)
{
    STATUS Status;
    BYTE CrcSts;
    int RetryCount1 , RetryCount2;
    bool ReadyForData;
	BYTE MMCerror1;//09.12

	 DWORD       SectorStart,SectorCount;
	 SectorStart= sector;
	 SectorCount =1;
	if(SdCardExist()==0)
		return STATUS_NO_MEDIA;	//Derek 2007.03.14
    if(SDMI_ST & bmSD_WR_PROTECT)
        return STATUS_WRITE_PROTECT;
  
    SdWaitCard();  //保证上次操作完成!

    for(RetryCount1 = 0; RetryCount1 < 10; RetryCount1++)
    {
        ReadyForData = false;
        for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
        {
            *((UINT32 *)(&SdCmdBuf[1])) = RCA;
            Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
            if(Status != STATUS_SUCCESS)
                {
				//MMCerror1++;
                continue;}  
            if(SdRespBuf[3] & 0x01) // READY_FOR_DATA in Card Status
            {
                ReadyForData = true;
                break;
            }
        }        
        if(!ReadyForData)
            {
			CmdTimer=2;
			while(CmdTimer);
            continue;}

	 memcpy((BYTE xdata *)DMA_FIFOB0,buff, 512);	
	   SDMI_BUFBASE=(DMA_FIFOB0>>8);
if(SdHcFlag) {	   //Derek 2007.07.02  对于HC SD,以sector为单位。
		*((UINT32 *)(&SdCmdBuf[1])) = SectorStart;
} else			   //对于standard,以字节为单位。
        *((UINT32 *)(&SdCmdBuf[1])) = 
            SectorStart << BYTES_PER_SECTOR_SHIFT;	 //
//***********************
    if (SectorCount > 1) // Muti-Write.
        {   
        Status = SdSendCmd(WRITE_MUL_BLOCK, SdCmdBuf);
        if(Status != STATUS_SUCCESS)
            continue;
        }
     else
        {

        Status = SdSendCmd(WRITE_BLOCK, SdCmdBuf);
        if(Status != STATUS_SUCCESS)
            continue;

       }
//*******************************   
        
		CrcSts = (SDMI_ST&0x38) >> 3;
		if(CrcSts != GOOD_CRC16_STS) {
			MMCerror1 ++;  
			continue;
			}
        else
            return STATUS_SUCCESS;
    }
    
    
    return STATUS_FLASH_ERROR;
}  
 /*
STATUS SdWriteSector()
{
    STATUS Status = SdWriteOneSector();

    SectorStart ++;
    return Status;
}

//----------------------------------------------------------------------------
//  Description:
//    Write one sector of data from the SD device 
//----------------------------------------------------------------------------
STATUS SdWriteNextSector()
{
	STATUS Status;
	BYTE CrcSts;
	bit Stop;


	Stop = SectorCount == 1;
  	if(SdCardExist()==0)
		return STATUS_NO_MEDIA;	//Derek 2007.03.14
	SdWaitCard();
	CmdTimer = SD_CMD_TIMEOUT;
	if (CmdTimer == 0) 
	{
		return STATUS_FLASH_ERROR;
	}

//	SDMI_BUFBASE=(FIFO_ADDRESS_OUT>>8); 

	SDMI_CMD=SD_CMD_TX_DATA_ONLY; 	 
	if ((Status = SdWaitCmd()) != STATUS_SUCCESS)
		return Status;				 
	CrcSts = (SDMI_ST&0x38) >> 3;
	if (CrcSts != GOOD_CRC16_STS)
	{
		return STATUS_DATA_ERROR;
	}

	if (Stop)
		return SdStopCmd();

	return STATUS_SUCCESS;
}  */
#if 0
//--------------用于SD1.10,2.0卡function 切换----------------------
//主要是为了切换到high speed mode。
STATUS SDCMD6Test()
{
	STATUS Status;
	int i=0;
 
	SDMI_BUFBASE=0xF2; //FIFOB1
	SDMI_LENH = 0;
	SDMI_LENL = 64;
    *((UINT32 *)(&SdCmdBuf[1])) = 0x00FFFFF1; //check switchable function(mode0)
 	Status = SdSendCmd(CMD6, SdCmdBuf);		  //CMD6-adtc command type
	SDMI_LENH = 0X02;
	SDMI_LENL = 0;
	if(Status != STATUS_SUCCESS)
		return Status;

	SDMI_LENH = 0;
	SDMI_LENL = 64;
    *((UINT32 *)(&SdCmdBuf[1])) = 0x80FFFFF1; //switch card function(mode1)
 	Status = SdSendCmd(CMD6, SdCmdBuf);
	SDMI_LENH = 0X02;
	SDMI_LENL = 0;
	if(Status != STATUS_SUCCESS)
		return Status;
	return Status;
}
#endif
//--------------------------------------------------------------------
// Initialization sequence of SD/MMC
//--------------------------------------------------------------------
STATUS SdReadFlashInfo(void)
{
    STATUS Status;
    int RetryCount;
    
    for(RetryCount = 0; RetryCount < 5; RetryCount++)
    {
        Status = SdReset();
        if(Status != STATUS_SUCCESS)
            continue;
////////////////SD 2.00 card detect.
   		Status = SdSendIFCon();	   //SD2.0 only,
		if(Status == STATUS_SUCCESS)
			SdVer2Flag = 2;			//SD 2.00 card
		else
			SdVer2Flag = 0;			//non-Ver2.00 card.
/////////////////////
        Status = SdDetect();
        if(Status != STATUS_SUCCESS)
            continue;

        Status = SdGoIdentifyState();
        if(Status != STATUS_SUCCESS)
            continue;

        Status = SdGoStandbyState();
        if(Status != STATUS_SUCCESS)
            continue;

        Status = SdReadCSD();
        if(Status != STATUS_SUCCESS)
            continue;

        Status = SdGoTransferState();
        if(Status != STATUS_SUCCESS)
            continue;

//		if(CardType == CARD_SD) {	  //对于SD卡,要读取SCR寄存器。
//			SdReadSCR();
//
//			if(SdHcFlag|SdVer2Flag) {		//For SD 1.10,2.0(include high capacity).
//				Status = SDCMD6Test();	//derek 2007.06.29
//				if(Status != STATUS_SUCCESS)
//					SDMI_CTL   &= ~bmSD_CLK_40;	 //根据卡的最大传输速率设定接口频率。
//							 				//特别是对1.0的卡,要降低频率
//			} else
//				SDMI_CTL   &= ~bmSD_CLK_40;
//		}	
		return STATUS_SUCCESS;
    }
    return STATUS_FLASH_ERROR;
}

#ifdef DEBUG_FLASH_ERASE
//----------------------------------------------------------------------------
STATUS SdEraseDevice(void)
{
  STATUS Status;

// ERASE_WR__BLK_START.
 *((UINT32 *)(&CmdBuf[1])) = 0;
 SdIssueCmd(32, SD_CMD_SHORT_RSP);
 if ((Status = SdReadRsp(SdRespBuf, RSP_LEN)) != STATUS_SUCCESS)
    return Status;    
// ERASE_WR__BLK_END.
 *((UINT32 *)(&CmdBuf[1])) = SdAvailableBlocks << BYTES_PER_SECTOR_SHIFT;
 SdIssueCmd(33, SD_CMD_SHORT_RSP);
 if ((Status = SdReadRsp(SdRespBuf, RSP_LEN)) != STATUS_SUCCESS)
    return Status;    
// ERASE.
 *((UINT32 *)(&CmdBuf[1])) = 0;
 SdIssueCmd(38, SD_CMD_SHORT_RSP);
 if ((Status = SdReadRsp(SdRespBuf, RSP_LEN)) != STATUS_SUCCESS)
    return Status;    
  
  return STATUS_SUCCESS;
}
#endif

//----------------------------------------------------------------------------
// Description:
//   Handle the media change event
//----------------------------------------------------------------------------
void SdMediaChange(void)
{
  if (SdCardExist())
  {
    BYTE i = MAX_FLASH_RETRY_TIMES;

	SdLoClk();
	SdHcFlag = 0;	 //每次读取SD卡信息前,将标志清零。
	SdVer2Flag = 0;
    do 
    {
      SdMediaStatus = SdReadFlashInfo();
      i--;
    }while (i && (SdMediaStatus != STATUS_SUCCESS));
    if (SdMediaStatus == STATUS_SUCCESS)
      SdMediaStatus = STATUS_MEDIA_CHANGE;
//////////////////////////////////////////////
//{	
//
//	SectorStart = 0;		   //检测T5C SDMI接口性能.
//	SectorCount = 1;
//	FIFO_ADDRESS_OUT = DMA_FIFOA0;
//	memset((BYTE xdata*)FIFO_ADDRESS_OUT,0,512);
//	SdMediaStatus = SdWriteSector();//
//
//	SectorStart = 0;
//	SelectInFifo();
//	SdMediaStatus = SdReadSector();//
//}
////////////////////////////////////////////
  }
  else
  {
    SdStopClk();	
    SdPowerOff();
    SdAvailableBlocks = 0;
    SdMediaStatus = STATUS_NO_MEDIA;
  }
}
#if 0
//----------------------------------------------------------------------------
// Description:
//   use to change STATUS when device "Start"
//----------------------------------------------------------------------------
void SdStart()
{
    if(SdCardExist())
        SdMediaStatus = STATUS_SUCCESS;
}


//----------------------------------------------------------------------------
// Description:
//   use to change STATUS when device "eject"
//----------------------------------------------------------------------------
void SdEject(void)
{
    SdMediaStatus = STATUS_NO_MEDIA;
}

//----------------------------------------------------------------------------
// Description:
//   Query the current device information
//----------------------------------------------------------------------------
STATUS SdQueryDevice(void)
{
  STATUS OrgStatus = SdMediaStatus;

  if (SdMediaStatus == STATUS_NO_MEDIA)
      return SdMediaStatus;

  if (SdMediaStatus == STATUS_MEDIA_CHANGE)
      SdMediaStatus = STATUS_SUCCESS;

  DeviceInfo.TotalBlocks = SdAvailableBlocks;
  DeviceInfo.BlockSize = BYTES_PER_SECTOR;

  if (CardType == CARD_SD)
      DeviceInfo.WriteProtect = SdWriteProtect();
  else
      DeviceInfo.WriteProtect = false;

  return OrgStatus;
}

//----------------------------------------------------------------------------
// Description:
//   Make the SD device into suspend mode
//----------------------------------------------------------------------------
void SdSuspend()
{
  SdStopClk();	
  SdPowerOff();
}

//----------------------------------------------------------------------------
// Description:
//   Make the CF device resume
//----------------------------------------------------------------------------
void SdResume()
{
  if (SdCardExist())
  {
    SdPowerOn();
	SdLoClk();			//Derek 2006.09.14 时钟设为低速
    SdReadFlashInfo();	//重新识别读取SD信息
  }
}
#endif
//----------------------------------------------------------------------------
// Description:
//   Initiate the SD device
//----------------------------------------------------------------------------
void SdInit(void)
{
  if (SdCardExist())
  {
    SdMediaChange();
  }
}

⌨️ 快捷键说明

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