Appearance
SD卡
简介
SD卡的名字是Secure Digital Card 安全数字卡, 实际上就是nand flash加上控制芯片
只要有三种full size sd卡, Micro SD卡, 还有MiniSD卡
最常用的就是Micro SD卡
是在MMC卡的基础上面发展来的, 遵守的是SD协议, 下面使用的2.0版本的协议, 支持32G容量
容量大, 高安全性, 体积小, 传输速度快, 接口简单
寄存器
SDIO模式
常用的命令
RCA就是相对地址
响应
操作模式
SPI模式
命令
CMD9会在接收到respond之后返回16字节的CSD
相应
数据Token
主要通过返回的Token检查数据是否被正常接收
实际通信
各种模式
需要等待MISO的状态变化, 标志着数据已经写入了
编程实战
SPI模式
计算容量
获取csd寄存器值, 根据不同版本进行计算
c
/**
* @brief 获取SD卡的总扇区数(扇区数)
* @note 每扇区的字节数必为512, 如果不是512, 则初始化不能通过
* @param 无
* @retval SD卡容量(扇区数), 换成字节数要 * 512
*/
uint32_t sd_get_sector_count(void)
{
uint8_t csd[16];
uint32_t capacity;
uint8_t n;
uint16_t csize;
if (sd_get_csd(csd) != 0) /* 取CSD信息,如果期间出错,返回0 */
{
return 0; /* 返回0表示获取容量失败 */
}
/* 如果为SDHC卡,按照下面方式计算 */
if ((csd[0] & 0xC0) == 0x40) /* V2.00的卡 */
{
/* V2.0卡 计算容量的公式
* memory capacity = (C_SIZE+1) * 512K byte 这个相当于2^19
扇区数:memory capacity / 512byte 即 / 2^9
*/
/* C_SIZE低8位 C_SIZE中8位 C_SIZE高6位 */
csize = csd[9] + ((uint16_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
capacity = (uint32_t)csize << 10; /* 得到扇区数 */
}
else /* V1.XX的卡 / MMC V3卡 */
{
/* V1.0卡 计算容量的公式
* memory capacity = BLOCKNR * BLOCK_LEN
(C_SIZE+1)*MULT * (2^READ_BL_LEN)
(C_SIZE+1)*(2^(C_SIZE_MULT+2))
= (C_SIZE+1)*(2^(C_SIZE_MULT+2+READ_BL_LEN))
扇区数:memory capacity / 512byte 即 / 2^9
*/
/* READ_BL_LEN C_SIZE_MULT后1位 C_SIZE_MULT前2位 (移位操作是重新组合数据) */
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
/* C_SIZE低2位 C_SIZE中8位 C_SIZE高2位 (移位操作是重新组合数据) */
csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1; /* 公式中的(C_SIZE+1) */
capacity = (uint32_t)csize << (n - 9); /* 得到扇区数 */
}
return capacity; /* 注意这里返回的是扇区数量, 不是实际容量的字节数, 换成字节数 得 * 512 */
}
SDIO模式
在初始化的时候设置的分频参数直接设置为正常情况下的参数就可以了, 因为在进行初始化的时候会调用函数HAL_SD_InitCard, 在这个函数里面会使用一个新的结构设置时钟为初始化的时钟, 使用默认的配置实现
之后会在函数SD_PowerON函数里面进行初始化发送命令, 根据不同的版本进行不同的操作, 发送命令ACMD41获取电压信息是否匹配, 以及获取SD卡的大小
然后调用SD_InitCard, 发送CMD2, CMD3, CMD9获取相对地址等信息
最后按照我们的配置进行设置时钟速度等