Get SD card capacity by SPI (V2.0)

The following is the CSD register content of the SD card V2.0 protocol, from the official manual:

How does the microcontroller determine that the current SD card follows the V2.0 protocol

The CSD register is 128 bits, or 16 bytes. It is judged by checking whether bit126 of the CSD register is 0 or 1. If it is 1, it is the V2.0 version.

The relevant code is as follows:

u8 SD_GetCSD(u8 *csd_data)
{
    u8 r1;   
    
    /* 发送读取 CSD 指令 */
    r1=SD_SendCmd(CMD9,0,0x01);、
    if(r1==0)
    {
        r1=SD_RecvData(csd_data, 16);
    }
    
    /* 取消片选 */
    SD_DisSelect();
    
    if(r1)return 1;
    else return 0;
} 
    /* 访问出错返回 */
    if(SD_GetCSD(csd) != 0) return 0;     
    
    /* 确保为 V2.0 的卡 */
    if((csd[0]&0xC0)==0x40)

In the CSD register of V2.0, the bits describing the capacity are shown in the following figure:

The C_SIZE of V2.0 is related to the capacity, there are 22 bits in total, from bit48~69, located in csd[7], csd[8], csd[9].

The formula and method of calculation provided in the manual are shown in the following figure:

In summary:

csize = csd[9] + ((uint32_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
Capacity = csize << 9;

Note: The capacity unit calculated by Capacity is bytes. In practical applications, pay attention to the conversion of the unit.

Program Addendum

u8 SD_GetResponse(u8 Response)
{
    u16 Count  =0xFFFF;
    
    /* 等待响应 */
    while ((SD_SPI_ReadWriteByte(0XFF) != Response)&&Count)Count--;
    
    if (Count==0)
        return MSD_RESPONSE_FAILURE;
    else
        return MSD_RESPONSE_NO_ERROR;
}

u8 SD_RecvData(u8*buf,u16 len)
{                 
    /* 等待响应 */
    if(SD_GetResponse(0xFE))return 1;
    
    while(len--)
    {
        *buf = SPI1_ReadWriteByte(0xFF);
        buf++;
    }

    /* 发送 2 个伪 CRC */
    SD_SPI_ReadWriteByte(0xFF);
    SD_SPI_ReadWriteByte(0xFF);                                                         
    return 0;
}

u32 SD_GetSectorCount(void)
{
    u8 csd[16];
    u32 Capacity;  
    u32 csize;  
    
    if(SD_GetCSD(csd)!=0) return 0;   
  
    if((csd[0]&0xC0)==0x40)
    {   
        csize = csd[9] + ((uint32_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
        Capacity = csize << 9;
    }
    
    return Capacity;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325402493&siteId=291194637