4、SDIO数据传输模式:块传输、流传输、SPI模式
SDIO 的数据传输方式,说白了就三种:块传输、流传输,以及 SPI 模式。这三种模式不是让你随便选的——卡的类型、硬件设计、总线带宽,都会限制你能用哪种。我个人习惯是先把卡的功能寄存器读出来,再决定后面走哪条路。
刚开始做 SDIO 验证时,我总觉得「块传输」就是标准答案。后来踩过几次坑才发现,某些 Wi-Fi 模组在高速数据流场景下,流传输反而更省事。嗯,咱们一个一个来看。
块传输(Block Transfer)
块传输是 SDIO 最主流的模式,也是和普通 SD 卡最像的地方。数据以固定大小的「块」为单位进行读写,块大小通常为 512 字节。每个块后面跟着 CRC 校验,保证了数据完整性。
我在项目中遇到过一块 BT/Wi-Fi 二合一的模组,厂商手册硬性规定必须用块传输。当时我图省事想用流传输来收大块数据,结果模组根本不理睬——CMD53 的块模式位没设对,直接返回超时。
块传输的关键参数:
- 块大小:由卡的功能寄存器
FN_BLOCK_SIZE决定,常见 512、1024、2048 字节。 - 块数:单次命令最多传输 65535 块(需要扩展命令)。
- 数据线宽:支持 1-bit、4-bit、8-bit 模式。
我建议你在写自动测试脚本时,先发送 CMD7 选择卡,然后用 CMD53(IO_RW_EXTENDED)的块模式来读写。下面是一个典型的块写命令流程:
// 伪代码示意 — 块写操作
CMD52(0x00, FN0_CIA, SELECT_CARD); // 主机准备
CMD53(WRITE, BLOCK_MODE, 0x100, 512); // 写 512 字节到地址 0x100
// 检查 Data0 上的 CRC 状态位
流传输(Stream Transfer)
流传输是 SDIO 独有的——普通 SD 卡可没有这玩意。它的特点是:没有块边界,数据作为连续的字节流传输。换句话说,卡和主机之间像一根管子,数据哗哗地流过去,没有 CRC 校验,也没有块尾填充。
为什么需要流传输?因为有些 SDIO 设备(比如摄像头模组)产生的数据是连续不断的,你不可能等它凑满一个块再读。流传输能让主机以最快速度把数据抓走,延迟很低。
流传输的使用场景:
- 高吞吐实时数据(视频流、音频流)
- 低速但连续的传感器数据
- 调试阶段的大批量数据抓取
我记得有一次调一个 GNSS 模组,它的 NMEA 报文是一行一行往外吐的,用块传输反而要拆包,改成流传输后代码清爽很多。不过要注意,CMD53 的流模式只支持 1-bit 数据线,不能开 4-bit。
SPI 模式
SPI 模式不是 SDIO 的「亲儿子」,但它兼容性极好。你拿一个普通的 SPI 主机控制器,接上 SDIO 卡(只要卡支持 SPI 模式),就能跑起来。代价是速度慢——SPI 模式最高只能到 25MHz,而且只支持 1-bit 数据线。
为什么要用 SPI 模式?说白了,很多 MCU 没有 SDIO 控制器,但几乎都有 SPI 外设。我早期做一个 IoT 项目,STM32F103 没有 SDIO 接口,只能用 SPI 模式读写 WiFi 模组。速度虽然只有 2MB/s,但胜在稳定。
SPI 模式下,SDIO 的命令和数据都用 SPI 帧格式传输。具体的引脚分配:
| SPI 信号 | SDIO 对应引脚 | 说明 |
|---|---|---|
| CS | DAT3 | 片选,低电平选中卡 |
| SCLK | CLK | 时钟,由主机提供 |
| MOSI | CMD | 主机输出,卡输入 |
| MISO | DAT0 | 卡输出,主机输入 |
需要注意:进入 SPI 模式后,卡就不能再用 SD 总线方式操作了。你得通过 CMD0 + 特殊参数让卡切换过去。我见过有人焊完板子忘了改初始化代码,结果 SPI 怎么都拉不起来,排查了半天才发现是上电时序没对。
三种模式的选择指南
不要等到代码写完了再考虑用哪种模式。先看卡的功能寄存器(FN0 的 CIA[0x08] ),它的 Bit[1:0] 就说明了支持的传输模式。我再给你一张总结表:
| 模式 | 是否有 CRC | 数据线宽 | 典型速率 | 适用场景 |
|---|---|---|---|---|
| 块传输 | 是 | 1/4/8-bit | 高 | 固件升级、配置 |
| 流传输 | 否 | 1-bit 仅限 | 极高(无校验开销) | 实时数据流 |
| SPI 模式 | 否(帧内可选) | 1-bit | 低(≤25MHz) | 无 SDIO 控制器的平台 |
下面这张图把三种模式的关系和切换条件画清楚了,你可以对着电路图和卡手册一步一步走:
画完图再啰嗦一句:自动测试用例应该覆盖所有卡声称支持的模式。别只测块传输——流传输的数据连续性和 SPI 的时序,往往是隐性 bug 的重灾区。