SDIO学习记录

为了使用SDIO对SD卡进行读写,移植了ST的官方使用例程源码,但是移植后发现程序执行 BSP_SD_WriteBlocks() 后卡死在 while((BSP_SD_GetCardState() != SD_TRANSFER_OK)) ,后来比对野火的例程(也是移植的ST官方)做出下面修改,问题得到解决:

  • 添加SDIO_IRQHandler、DMA2_Stream3_IRQHandler、DMA2_Stream6_IRQHandler的中断服务函数,并执行相应中断服务函数;
  • 将BSP_SD_WriteBlocks()改为BSP_SD_WriteBlocks_DMA();

SDIO协议

在硬件上的物理连接有:

  • CLK:上升沿时触发命令线/数据线的采样;
  • CMD命令线:传输“命令”和“响应”
  • 4条数据线(Data0~3)

STM32的SDIO外设由AHB总线接口SDIO适配器组成,其中SDIO适配器直接连接并与SD卡进行通信,AHB总线负责外设驱动、中断、DMA等内容。

SDIO适配器的时钟频率SDIOCLK=HCLK,CLK线的时钟频率SDIO_CK来源于此,具体配置有:

  1. 设置BYPASS模式,适配器时钟SDIOCLK通过一个连通旁路直接供给CLK时钟线,即SDIO_CK=SDIOCLK;
  2. 不设置BYPASS模式,按照公式

由于SD卡普遍的时钟频率要求不超过25MHz,一般通过第二种方式配置STM32的SDIO外设时钟频率。

对SD操作需要发送命令,SDIO协议规定了命令内容,每个命令有其功能,规定“有响应”的命令发送后SD卡会返回对应响应类型,规定“有数据”的命令需要接着继续发送数据;

STM32控制器可以控制使用单线或4线传输,其中Data0线可以通过低电平来表示BUSY状态。数据传输的模式有以下两种:

  1. 数据块:常用,一般数据块的大小为512字节;
  2. 数据流

传输数据时数据线的内容组成为:数据块+CRC(+BUSY),其中忙状态在对SD卡做写操作时才有。传输可以是单个数据块,也可以是多个数据块,单块和多块传输有自己的命令,像在HAL库中就有函数 SDMMC_CmdSingleBlock 和 SDMMC_CmdWriteMultiBlock 之分。如果是多块传输,需要手动发送停止命令才能结束数据传输;

上面演示的是一个大体的数据线工作流程,一个完整的数据包除了数据块和CRC,还有起始位(低电平)和终止位(高电平)。使用四线进行数据传输时,每一根数据线都要具备起始、终止和CRC。数据包有两种:

  1. 8位宽数据包
  2. 宽位数据包

下图是四条数据线传输8位宽数据包的示意图,特征是:

  • 先发低字节再发高字节
  • 先发高位再发低位

与之相比,宽位数据包的传输没有前后字节之分,而是传输512位数据,并且依旧符合先发高位再发低位。

CPSM是命令路径状态机,负责命令的传输管理

DPSM是数据路径状态机,负责数据的传输管理

SDIO应用逻辑

下面是HAL库中对SD卡做发送数据的函数流程

posted on   fhbui  阅读(4)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示