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

📄 sd.c

📁 SdCard_V2.1TinyFatFs.rar是单片机实现SD卡功能的FAT文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
			{    		
    			*((INT32U *)(&SdCmdBuf[1])) = RCA;
				Status = SdSendCmd(SEND_STATUS, SdCmdBuf);

				if(Status == STATUS_SUCCESS)
   				{
   					if(busWidth==8)
					{	
						SDMI_CTL|=bmSD_BUS_8BIT_EN;
						SDMI_CTL&=~bmSD_BUS_4BIT_EN;
					}
					else if((busWidth==4))
					{	
						SDMI_CTL&=~bmSD_BUS_8BIT_EN;
						SDMI_CTL|=bmSD_BUS_4BIT_EN;
					}
					else
					{	
						SDMI_CTL&=~bmSD_BUS_4BIT_EN;
						SDMI_CTL&=~bmSD_BUS_8BIT_EN;
					}
   				}
				    		 
			    //Status = SdReadExtCSD();
			}
		}
		else  // MMC 3.1 只支持1bit模式		
		{
			SDMI_CTL&=~bmSD_BUS_4BIT_EN;
			SDMI_CTL&=~bmSD_BUS_8BIT_EN;
		}
    }	   
    return Status;   
}
#ifdef DEBUG_FLASH_ERASE	
STATUS SdReadExtCSD(void)
{
    STATUS Status;
    int RetryCount1 , RetryCount2;
    BOOL ReadyForData;

//	if (!SdCardExist())
//   		return STATUS_FLASH_ERROR;

    SdWaitCard();
  
    for(RetryCount1 = 0; RetryCount1 < 5; RetryCount1++)
    {
        ReadyForData = FALSE;
        for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
        {
            *((INT32U *)(&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=0xEC; //FIFOB0--11.30 DEREK  
						   //注意:EXT CSD的512字节数据在FIFO中从低到高排列~!
        *((INT32U *)(&SdCmdBuf[1])) = 0;
		Status = SdSendCmd(SEND_EXT_CSD, SdCmdBuf);
	    if(Status != STATUS_SUCCESS)
	        continue;

		//*******************************   
        if(SDMI_ST&bmSD_CRC16_ERR)
        {
            SDMI_ST &=~bmSD_CRC16_ERR;
            continue;
        }
        else
		{
           *((INT32U *)(&SdCmdBuf[1])) = RCA;
            Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
              
			return STATUS_SUCCESS;
		}
    }
    return STATUS_FLASH_ERROR;
}
#endif
//----------------------------------------------------------------------------
STATUS SdReset()
{
    STATUS Status;
    int i;

    RCA = 0;
    
    SdLoClk();
    Delay(5);  // Wait 5ms for stable clock
    for(i = 1; i <= 4; i++)
        SdCmdBuf[i] = 0;
    Status = SdSendCmd(GO_IDLE_STATE, SdCmdBuf);
    return Status;
}

//----------------------------------------------------------------------------
STATUS SdDetect(void)
{
    STATUS Status;
    UINT16 RetryCount;

    *((UINT32 *)(&SdCmdBuf[1])) = OPERATION_VOL_RANGE;
    if(SdVer2Flag)SdCmdBuf[1] = 0x40;		  //sd2.0卡支持high capacity support功能。Derek 2007.06.29
    Status = SdSendAppCmd(SD_SEND_OP_COND, SdCmdBuf);
    
    if(Status == STATUS_SUCCESS)	//如果返回成功标志,说明是SD卡
    {
        CardType = CARD_SD;	
 
        // Check if card power-up operation finished
        if(SdRespBuf[1] & CARD_PWRUP_FINISH)
            return STATUS_SUCCESS;

        // Wait until card power-up operation finished
        for(RetryCount = 0; RetryCount < 500; RetryCount++)
        {
            *((UINT32 *)(&SdCmdBuf[1])) = OPERATION_VOL_RANGE; //2007.06.29
            if(SdVer2Flag)SdCmdBuf[1] = 0x40;	  //Derek 2007.06.29
            Status = SdSendAppCmd(SD_SEND_OP_COND, SdCmdBuf);
            
            if(Status != STATUS_SUCCESS)
                continue;
                
            if(SdRespBuf[1] & CARD_PWRUP_FINISH)
                return STATUS_SUCCESS;           
        }
        return STATUS_FLASH_ERROR;
    }
    else	//否则,是MMC卡
    {
        CardType = CARD_MMC;   	
        
        // Wait until card power-up operation finished
        for(RetryCount = 0; RetryCount < 500; RetryCount++)
        {
            
            *((UINT32 *)(&SdCmdBuf[1])) = OPERATION_VOL_RANGE;
    
            Status = SdSendCmd(SEND_OP_COND, SdCmdBuf);

            if(Status != STATUS_SUCCESS)
                continue;
                
            if(SdRespBuf[1] & CARD_PWRUP_FINISH)
                return STATUS_SUCCESS;           
        }
        return STATUS_FLASH_ERROR;
    }
}	

//-----用来检测是否Sd 2.0卡-----------------------------------------------------
STATUS SdSendIFCon(void)
{
    STATUS Status;

    SdCmdBuf[3] = 0X01;
	SdCmdBuf[4] = 0XAA;

    Status = SdSendCmd(SEND_IF_COND, SdCmdBuf);

    return Status;
}

//----------------------------------------------------------------------------
STATUS SdGoIdentifyState(void)
{
    STATUS Status;
    int i;

    for(i = 1; i <= 4; i++)
        SdCmdBuf[i] = 0;
    Status = SdSendCmd(ALL_SEND_CID, SdCmdBuf);
    return Status;
}

//--------------------------------------------------------------------
STATUS SdGoStandbyState(void)
{
    STATUS Status;
    int i;
  	
    if(CardType == CARD_SD)
    {
        for(i = 1; i <= 4; i++)
            SdCmdBuf[i] = 0;
    }
    else
    {
        RCA = 0x00010000;	
        *((UINT32 *)(&SdCmdBuf[1])) = RCA;
    }

    Status = SdSendCmd(SEND_RELATIVE_ADDR, SdCmdBuf);

    if(CardType == CARD_SD)
        RCA = *((UINT32 *)(&SdRespBuf[1])) & 0xffff0000;

    return STATUS_SUCCESS;
    
    // SD and MMC adopt different ways to set their relative card 
    // address. That is, they have different response to CMD3 
    // (SEND_RELATIVE_ADDR).
    //
    // According to SD Standard Version 1.01 page 25:
    //     the host issues CMD3 (SEND_RELATIVE_ADDR) asks the 
    //     card to publish a new relative card address (RCA).
    //
    // According to MMC Standard Version 3.1 page 24:
    //     the host issues CMD3 (SEND_RELATIVE_ADDR) to assign
    //     to this card a relative card address (RCA).
    //
    // This means : when host send CMD3 to SD, it is SD telling host
    // its new address, that is, SD is the one giving the new address
    // (and host decides whether to accept it). Meanwhile, when host 
    // sends CMD3 to MMC, it is host assigning the card a new address,
    // that is, host is the one decides the address (and MMC must 
    // accept it).
    // 
    // For SD, CMD3 has a response of type R6, which contains address
    // value returns by SD. For MMC, CMD3 has a response of type R1, 
    // which tells host if MMC accepts the address or error happens.
}

//--------------------------------------------------------------------
STATUS SdReadCSD(void)			
{
    STATUS Status;	
    BYTE READ_BL_LEN;
    BYTE C_SIZE_MUTI;
    UINT32 C_SIZE;
     										  //SD 2.0和SD1.01格式不一样。C_SIZE【69:48】
    *((UINT32 *)(&SdCmdBuf[1])) = RCA;
    
    Status = SdSendCmd(SEND_CSD, SdCmdBuf);	 //读取SD卡的CSD信息
    if(Status != STATUS_SUCCESS)
        return Status;  

	if(CardType == CARD_MMC) {
	    if(((SdRespBuf[1]&0x3f)>>2)==4) MmcProtol = 1; //判断是何种卡4.0 ?3.1?
	    else MmcProtol = 0;							   //MMC 3.1
	} else {
		if(SdRespBuf[1]&0xC0)			 //2007.08.16-从SD CSD中判断是否HC SD。
			SdHcFlag = 1;
		else
			SdHcFlag = 0;
	}
if(SdHcFlag == 0) {		   //Derek  2007.07.02  V1.0,1.01的SD卡CSD
	//Derek 06.09.20
    READ_BL_LEN = SdRespBuf[6] & 0xf;
    C_SIZE = SdRespBuf[7] & 0x3;
    C_SIZE <<= 8;
    C_SIZE |= SdRespBuf[8];
    C_SIZE <<= 2;
    C_SIZE |= (SdRespBuf[9] >> 6);
    C_SIZE_MUTI = SdRespBuf[10] & 0x3;
    C_SIZE_MUTI <<= 1;
    C_SIZE_MUTI |= (SdRespBuf[11] >> 7);
  
    SdAvailableBlocks = (UINT32)((C_SIZE + 1) << (C_SIZE_MUTI + 2 + 
                             (READ_BL_LEN - BYTES_PER_SECTOR_SHIFT)));
} else {				//V1.1,2.0的SD卡CSD  CSIZE---CSD[69:48]
	C_SIZE = SdRespBuf[8] & 0x3F;
	C_SIZE <<= 8;
	C_SIZE |= SdRespBuf[9];
	C_SIZE <<= 8;
	C_SIZE |= SdRespBuf[10];

	SdAvailableBlocks = (UINT32)((C_SIZE+1) << 10);//memory capacity blocks = (C_SIZE+1)*512KB/512B
}
    SdAvailableBlocks -= 1;   //计算得到可用block数。默认block大小为512字节

    return STATUS_SUCCESS;
}	
#if 0
//--------------------------------------------------------------------
//读取SCR寄存器的值,判断SD卡确切的版本~
STATUS SdReadSCR(void)	//----		
{
    STATUS Status;	
    BYTE i;
for(i = 0;i < 10;i++){ 
    *((UINT32 *)(&SdCmdBuf[1])) = 0;
	SDMI_BUFBASE=0xF2; //FIFOB1
	SDMI_LENH = 0;
	SDMI_LENL = 8;    
    Status = SdSendAppCmd(SEND_SCR, SdCmdBuf);	 //读取SD卡的SCR信息
	SDMI_LENH = 0X02;
	SDMI_LENL = 0;
    if(Status == STATUS_SUCCESS) {//
		if((*(BYTE xdata*)(0xf200)&0x0F)>= 1)  //SD 1.10,2.00卡
			SdVer2Flag = 1;
		else 
			SdVer2Flag = 0;
        return Status;
	}
}
	SdVer2Flag = 0;
}
#endif
#if 0
STATUS SdProgCsd(void) //改写CSD
{
    STATUS Status;
    //BYTE CrcSts;
    int RetryCount1 , RetryCount2,i;
    BOOL ReadyForData;

    if(SDMI_ST & bmSD_WR_PROTECT)
        return STATUS_WRITE_PROTECT;
  
    SdWaitCard();

    for(RetryCount1 = 0; RetryCount1 < 5; RetryCount1++)
    {
        ReadyForData = FALSE;
        for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
        {
            *((INT32U *)(&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) //MMCerror2++;
            continue;
		//SdReadCSD();
        SDMI_BUFBASE=0xF2; //FIFOB0
		for(i=0;i<17;i++)
			((BYTE xdata *)DMA_FIFOB0)[i]=SdRespBufForProgCsd[i]; //.
		((BYTE xdata *)DMA_FIFOB0)[6] |= 0x0A;//
		
		Status = SdSendCmd(PROGRAM_CSD, SdCmdBuf);
    	if(Status != STATUS_SUCCESS)
    	    continue;
		//*******************************           
		///*CrcSts = (SDMI_ST&0x38) >> 3;
		//if(CrcSts != GOOD_CRC16_STS) //MMCerror3++;
		//	continue;
		//else	//
		return STATUS_SUCCESS;
	}
    
    return STATUS_FLASH_ERROR;
}
#endif

//----------------------------------------------------------------------------
STATUS SdGoTransferState(void)
{
    STATUS Status;
    BYTE CurrentState;
  	
    *((INT32U *)(&SdCmdBuf[1])) = RCA;
    Status = SdSendCmd(SELECT_CARD, SdCmdBuf);
    if(Status != STATUS_SUCCESS)
        return Status;  

    *((INT32U *)(&SdCmdBuf[1])) = RCA;
    Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
    if(Status != STATUS_SUCCESS)
        return Status;  

    CurrentState = (SdRespBuf[3] >> 1) & 0x0F;
    if(CurrentState == TRANSFER_STATE)
    {
        SdHiClk();
        if(CardType == CARD_SD)
        {
            Status = SdChangeBusWidth(4);
            if(Status != STATUS_SUCCESS)
                return Status;
        }
        else 
        {
			Status = SdChangeBusWidth(8);  //derek.
            if(Status != STATUS_SUCCESS)
                return Status;	
        }
    }   
    else
        return STATUS_FLASH_ERROR;
    
    return STATUS_SUCCESS;
}	
#if 0
//----------------------------------------------------------------------------
//  Description:
//    Stop the read or write command.
//	  Used for read or write multi blocks.
//----------------------------------------------------------------------------
STATUS SdStopCmd()
{
    STATUS Status;
    int i;

    SDMI_CTL&=~bmSD_AUTO_CLK_EN;

    for(i = 1; i <= 4; i++)
        SdCmdBuf[i] = 0;
    Status = SdSendCmd(STOP_TRANS, SdCmdBuf);
    if(Status != STATUS_SUCCESS)
        return Status;
 
    SdWaitCard();
      
    return STATUS_SUCCESS; 
}

//----------------------------------------------------------------------------
STATUS SdWaitCmd()
{
	CmdTimer = SD_CMD_TIMEOUT;	
	while((!(SDMI_INT&bmSD_COMPLETE_INT))&&CmdTimer); //等待命令执行完毕
	SDMI_INT&=~bmSD_COMPLETE_INT; //清除中断标志

	if (CmdTimer)				  //没有超时,返回成功标志
		return STATUS_SUCCESS;
	else 
	{
		SdCtrlReset();
		return STATUS_FLASH_ERROR;
	}
}
#endif	
 /*
//----------------------------------------------------------------------------
STATUS SdSetBlockLen(INT16U len)
{   
    STATUS Status;
    
    SdWaitCard();
    
	*((INT32U *)(&SdCmdBuf[1]))=len;
    Status = SdSendCmd(SET_BLOCKLEN,SdCmdBuf);
	if(Status == STATUS_SUCCESS)
    {
    	SDMI_LENH=len>>8;
    	SDMI_LENL=len;
    }
    	   
    return Status;   
}   
 */
//--------------------------------------------------------------------
// Read single sector of data from SD/MMC,
// Read the first sector when execute multi-read command.
//--------------------------------------------------------------------
#pragma OPTIMIZE(4)
STATUS SdReadOneSector(BYTE*buff, DWORD sector)
{
	STATUS Status;
    int RetryCount1 , RetryCount2;
    bool ReadyForData;
	 DWORD       SectorStart,SectorCount;
	 SectorStart= sector;
	 SectorCount =1;
	 //buff =DMA_FIFOB0;	
	  // (BYTE xdata *)DMA_FIFOB0
	if (!SdCardExist())
   		return STATUS_FLASH_ERROR;

    if(SectorStart > SdAvailableBlocks)
        return STATUS_PARAM_ERROR;

    SdWaitCard();			   //等待上次操作执行完毕

⌨️ 快捷键说明

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