新闻  |   论坛  |   博客  |   在线研讨会
详解 STM32 之 SD 卡(2)
鱼鹰谈单片机 | 2022-12-21 19:11:45    阅读:2819   发布文章

五、SD卡物理层协议

  SD卡的协议相对于SPI、I2C等协议的存储器来说相对复杂,包含SD卡物理层(机械封装、管脚、芯片结构、命令集等)、SD卡接口(SDIO)、SD主机控制器,甚至是软件设计的流程,都进行了详细的规定。

1、接口

① SDIO接口

  参考《Simplified_SDIO_Card_Spec.pdf》

图片

<1> CLK 时钟同步线

<2> CMD 命令信号线,主机发出的命令以及从机对命令的响应都是通过这条线进行传输

<3> DAT[3:0] 表示4条数据线,主机和从机的数据都是从这四条数据线上传输

② SPI接口

图片

2、命令格式

图片

3、响应格式

  以R1为例

图片

4、SD卡的工作状态

图片

 

5、SD卡的两种状态信息

① Card Status

  执行命令过程中的状态信息,比如地址不对齐错误、块长度错误、卡锁、ECC校验错误等等

② SD Status

  SD卡的专有特征,编程中不经常涉及。这个状态值有512位,不是通过命令线传送给主机,而是通过数据线。

六、STM32与SD卡相配的外设--SDIO适配器

 1、SDIO adapter 结构图

图片

2、命令状态机(CPSM)

  当发送命令和接收响应时,启动CPSM状态机。

图片

3、数据通道状态机

  当传输数据时,启动数据通道状态机。

图片

4、FIFO

  有关FIFO的资料参考:异步FIFO的FPGA实现

  数据FIFO(先进先出)子单元是一个具有发送和接收单元的数据缓冲区。

  FIFO包含一个每字32位宽、共32个字的数据缓冲区,和发送与接收电路。因为数据FIFO工作在AHB 时钟区域(HCLK/2),所有与SDIO时钟区域(SDIOCLK)连接的信号都进行了重新同步。依据TXACT和RXACT标志,可以关闭FIFO、使能发送或使能接收。TXACT和RXACT 由数据通道子单元设置而且是互斥的:

    ─ 当 TXACT 有效时,发送 FIFO 代表发送电路和数据缓冲区
    ─ 当 RXACT 有效时,接收 FIFO 代表接收电路和数据缓冲区

5、SDIO的特殊功能寄存器

  • SDIO电源控制寄存器(SDIO_POWER)

  • SDIO时钟控制寄存器(SDIO_CLKCR) : 时钟选择、分频

  • SDIO参数寄存器(SDIO_ARG)

  • SDIO命令寄存器(SDIO_CMD):控制发送命令

  • SDIO命令响应寄存器(SDIO_RESPCMD):包含响应命令中的命令索引

  • SDIO响应1..4寄存器(SDIO_RESPx):包含响应命令中的卡状态信息

  • SDIO数据定时器寄存器(SDIO_DTIMER)

  • SDIO数据长度寄存器(SDIO_DLEN):读或者写的长度,通常是是512的倍数

  • SDIO数据控制寄存器(SDIO_DCTRL):控制数据的读写方向、使能传输等信息

  • SDIO数据计数器寄存器(SDIO_DCOUNT):当DPSM状态机从Idle state切换到Wait_R或者Wait_S状态时,SDIO_LEN的数值加载到该寄存器中

  • SDIO状态寄存器(SDIO_STA)

  • SDIO清除中断寄存器(SDIO_ICR)

  • SDIO中断屏蔽寄存器(SDIO_MASK)

  • SDIO FIFO计数器寄存器(SDIO_FIFOCNT):当SDIO_DCTRL中的DTEN使能,并且DPSM处于Idle state时,SDIO_LEN/4的数值加载到该寄存器中

  • SDIO数据FIFO寄存器(SDIO_FIFO):读写数据缓冲FIFO

七、SD卡编程

  SD卡的编程在STM32官方固件库中就有例程,而且野火开发板对该例程进行了中文注释,不必再把源码贴入。这里着重讲一下SD卡编程流程,主要包含SD卡初始化、SD卡读、SD卡写、SD卡擦除。

1、SD卡编程的内容

  SD卡主要就是用来存储数据的,所以核心就是读写。为了实现这个目标,必须实现响应的驱动。

  配置过程中,不仅要设置好SD控制器,还需要将SD卡设置到合适的状态。在读取状态的时候,不仅涉及到SD控制器的状态,还涉及到SD卡的状态。

2、SD卡初始化

① STM32外设SDIO初始化

  1. 端口配置、端口时钟、SDIO时钟、DMA2时钟使能

  2. SDIO寄存器复位

  3. 设置时钟SDIO_CK为400KHz以下,设置数据线宽度,开启时钟、开启SDIO电源

② SD卡上电初始化

图片

  上电初始化流程如上图所示,笔者认为官方库提供的例程没有完全按照这个流程图的指示去做。事实上,官方库的程序只做了如上图红色方框内的流程,之外的没涉及。

  CMD0命令复位所有的卡。

  SD协议规定:在初始化的时候,使用ACMD41之前,必须先使用CMD8命令。而且ACMD41命令属于应用命令,在使用之前需要先发送命令CMD55。

  CMD8命令是为了核查电源是否匹配。ACMD41命令不断询问SD卡是否支持主机提供的电压,并且询问SD卡是否上电完成进入准备状态。ACMD41命令还能询问SD卡的类型(SDSC、SDHC)。

③卡进一步核查、获取卡信息

  发送命令CMD2,以获取CID信息。

  发送命令CMD3,以获取RCA相对地址,可以通过多次发送CMD3获取不同的RCA值,但是只有最后一次的才是有效的RCA地址。

  发送命令CMD9,以获取CSD寄存器。

④ 设置SDIO工作在数据传输模式

  设置SDIO的时钟为24MHz、数据线宽度为4位。

  通过SD_GetCardInfo函数将之前得到CID、CSD处理成卡的信息。

  通过CMD7命令选择匹配地址的卡,而取消选择其他的卡。

  至此,初始化完成。

3、读SD卡的一个块

  •  数据控制寄存器(SDIO_DCTRL)清零

  •  发送命令CMD16,设置SD卡的Block大小

  •  调用函数SDIO_DataConfig设置SDIO数据传输方式

  •  发送命令CMD17,读单个块

  •  SDIO数据传输结束中断使能

  •  SDIO的DMA传输功能使能

  •  DMA设置,并使能

4、写SD卡的一个块 

  •  数据控制寄存器(SDIO_DCTRL)清零

  •  发送命令CMD16,设置SD卡的Block大小

  •  发送命令CMD24,写单个块

  •  调用函数SDIO_DataConfig设置SDIO数据传输方式

  •  SDIO数据传输结束中断使能

  •  DMA设置,并使能

  •  使能SDIO的DMA传输功能 


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客