作者是初学者,水平有限,本文仅作为个人学习笔记使用,不能保证内容的正确性。部分资料来源于网络,参考了SD卡协议2.0手册等资料,如果有歧义,可以与作者联系。

目录

SD卡 SPI模式操作(1)初始化SD卡
SD卡 SPI模式操作(2)读操作
SD卡 SPI模式操作(3)写操作

简介

写入操作有两种类型:

  • 单次写操作
  • 连续写操作
    其中,每次写入的数据块长度由CMD16( SET_BLOCKLEN)命令设置。高容量SD卡的块大小固定为512字节,因此起始地址应与块边界对齐。

单次写操作

命令号 参数 响应 名称 描述
CMD24 [31:0]:数据地址,单位:字节(SDSC),单位:512字节(SDHC) R1 WRITE_BLOCK 写入一个块的数据,参数为块的首地址。块的长度由CMD16设置,对于高容量卡,块大小固定为512字节

通过发送CMD24(WRITE_BLOCK)命令,往参数指定的地址写入一个块的数据。因为高容量卡(SDHC)的块长度固定为512字节,所以发送地址的时候,需要将起始地址对齐到512字节,也就是说,起始地址需要为512的倍数。
在写入一个块的数据之前,需要发送数据起始令牌,该令牌为1个字节,格式为0xFE,表示开始传输数据块。
接下来需要发送一个数据块,该数据块的长度由CMD16(SET_BLOCKLEN)命令设置,一般在初始化时设置完毕。高容量卡(SDHC)的块长度固定为512字节。
发送完数据块之后,需要发送一个CRC,长度为2字节,在SPI模式下,要求不高的情况下可以省略掉,固定为0xFF。
当SD卡收到以上数据的时候,会对这些数据进行计算,并且返回一个数据应答令牌,指示当前数操作是否发生错误。如果接收到的数据块没有错误,将对其进行编程。只要SD卡忙着编程,就会向主机发送连续的忙令牌流,即将DO(对应MCU的MISO)拉低,直到SD卡完成操作,才会将DO拉高,表示空闲。
SD卡-SPI模式单次写操作.png

连续写操作

命令号 参数 响应 名称 描述
CMD25 [31:0]:数据地址,单位:字节(SDSC),单位:512字节(SDHC) R1 WRITE_MULTIPLE_BLOCK 连续写入多块数据,直到主机发送CMD12命令,参数为块的首地址。块的长度由CMD16设置,对于高容量卡,块大小固定为512字节

通过发送CMD25(WRITE_MULTIPLE_BLOCK)命令,从参数指定的地址开始,连续写入数据块。因为高容量卡(SDHC)的块长度固定为512字节,所以发送地址的时候,需要将起始地址对齐到512字节,也就是说,起始地址需要为512的倍数。
在写入一个块的数据之前,需要发送数据起始令牌,该令牌为1个字节,格式为0xFC,表示开始传输数据块。

注意:0xFC是连续写入的起始令牌,0xFE是单次读取、连续读取、单次写入的起始令牌。

接下来需要发送一个数据块,该数据块的长度由CMD16(SET_BLOCKLEN)命令设置,一般在初始化时设置完毕。高容量卡(SDHC)的块长度固定为512字节。
发送完数据块之后,需要发送一个CRC,长度为2字节,在SPI模式下,要求不高的情况下可以省略掉,固定为0xFF。
当SD卡收到以上数据的时候,会对这些数据进行计算,并且返回一个数据应答令牌,指示当前数操作是否发生错误。如果接收到的数据块没有错误,将对其进行编程。只要SD卡忙着编程,就会向主机发送连续的忙令牌流,即将DO(对应MCU的MISO)拉低,直到SD卡完成操作,才会将DO拉高,表示空闲。
这时候,可以继续重复以上的步骤,进行连续传输。当需要结束写入数据的时候,可以发送结束数据令牌,该令牌位1个字节,格式为0xFD。

注意:连续写入的结束条件是发送结束令牌,而不是发送CMD12命令,CMD12命令只适用于连续读操作。

SD卡-SPI模式连续写操作.png

当写入时发生数据错误,SD卡会停止写入,这时候可以发送ACMD12命令获取正确写入的块数。该命令的响应格式为4个字节的块数,以及2字节的CRC。

数据应答令牌格式

在发送完数据块内容和CRC之后,SD卡会返回一个数据应答令牌,指示当前数操作是否发生错误。该令牌为1个字节,低5位有效,第4位固定为0,第0位固定为1:
Pasted image 20230203183242.png

[1:3]位 描述
010 数据已接受
101 CRC错误,数据被拒绝
110 写入错误,数据被拒绝

关于写入完成之后的操作(可选)

可以继续发送CMD13(SEND_STATUS)命令。要求SD卡发送状态寄存器的内容,以获取SD卡的当前状态。

如果需要评论

因为是个人博客,因备案要求不能使用交互服务,如果需要评论,可以前往本文的CSDN页:
CSDN-SD卡 SPI模式操作(3)写操作

结尾

关于SD卡在SPI模式下的操作,到这里也介绍得差不多了,大家可以根据思路去编写代码,也可以去学习正点原子等厂家的代码。后续我会继续给大家介绍FatFS的使用。