SDIO 读写
一、SDIO 简介
1.1 SD卡核心优势
- 海量存储:GB级容量,突破传统存储芯片限制
- 高性价比:供应链成熟,采购成本低
- 广泛兼容:统一标准接口,MCU/FPGA原生支持
- 简化设计:内置NAND控制器与ECC校验,主机端无需复杂存储管理
1.2 典型应用场景
- 关键数据黑匣子(工业/汽车/航空航天)
- 多媒体内容载体(图像/音频/视频存储)
- 固件程序存储器(支持现场升级)
- 系统参数配置库
1.3 SDIO vs SPI 对比
| 维度 | SPI模式 | SDIO模式 |
|---|---|---|
| 数据通道 | 单通道(MISO/MOSI) | 1/4线并行(DAT0-DAT3) |
| 最高速度 | 约25MHz | 50MHz+ |
| 协议复杂度 | 简单,开发周期短 | 较复杂,命令/响应机制完整 |
| 适用场景 | 低速验证、快速原型 | 高速数据传输、FPGA并行优势 |
选型结论:对速率要求较高的FPGA应用,SDIO四线并行模式为首选。
二、协议解析核心机制拆解
2.1 硬件接口信号
- SD_CLK:同步时钟,初始化≤400kHz,传输阶段可提升至25MHz+
- SD_CMD:双向命令/响应通道
- SD_DAT[3:0]:双向数据总线,可配置1位或4位宽度
- SD_CD_N:卡检测信号,低电平表示卡已插入
- 所有信号通过10kΩ电阻上拉至3.3V
(ALINX AX7102/AX7103开发板SD卡硬件接口电路)
2.2 命令-响应通信模型
半双工通信,主机(FPGA)主动发起,从设备被动响应
命令帧(48bit):起始位 + 传输位 + 6bit命令索引 + 32bit参数 + 7bit CRC7 + 结束位
响应类型:
- R1/R6/R7(48bit短响应):通用状态、RCA发布、CMD8专属
- R2(136bit长响应):读取CID/CSD寄存器
- R3(48bit):返回OCR寄存器(电压范围)
2.3 SD卡初始化完整流程(11步)
| 步骤 | 命令 | 说明 |
|---|---|---|
| 1 | - | 上电后等待≥74个CLK周期,CMD保持高电平 |
| 2 | CMD0 | 强制进入空闲状态(GO_IDLE_STATE),无响应 |
| 3 | CMD8 | 检测SD 2.0协议支持,返回R7响应 |
| 4 | CMD55+ACMD41 | 轮询等待Busy bit置1,初始化完成 |
| 5 | - | 解析OCR的CCS位,识别SDSC或SDHC/SDXC卡 |
| 6 | CMD2 | 获取CID唯一标识号,R2长响应 |
| 7 | CMD3 | 获取16位RCA相对地址,R6响应 |
| 8 | - | 提升时钟频率至25MHz |
| 9 | CMD7 | 使用RCA选中卡片,进入数据传输模式 |
| 10 | CMD16 | 设置块长度,标准512字节 |
| 11 | CMD55+ACMD6 | 配置4位总线宽度,初始化完成 |
三、设计实现 FPGA 逻辑开发
3.1 整体架构(模块化设计)
- sdio_ctrl(顶层核心):状态机管理、调度所有子模块
- bus_driver:命令与数据发送,并行转串行输出
- bus_monitor:响应与数据接收,串行转并行,CRC校验
- 对外接口:标准化读写地址、控制信号、数据I/O
3.2 核心状态机(sdio_ctrl)
- IDLE:初始态,等待card_ready信号
- INIT:初始化命令交互循环(CMD0/8/ACMD41等)
- TRANS_READY:就绪态,等待上层读写指令
- SEND_CMD17/18:单块/多块读操作
- SEND_CMD24/25:单块/多块写操作
- SEND_CMD12:终止多块传输
3.3 关键技术要点
- 时钟动态切换:
assign sd_clk = card_init_finish ? fast_clk : slow_clk; - 三态门控制:
assign sd_cmd = drv ? sd_cmd_o : 1'bz; - bus_driver发送流程:组装命令 → CRC7校验 → 下降沿逐位串行输出
- bus_monitor接收流程:检测起始位 → 上升沿采样 → CRC校验 → 并行输出
3.4 读写操作命令
- 单块读:CMD17 + 块地址 → SD卡返回响应 + 数据块
- 多块读:CMD18 → 连续发送递增块 → CMD12终止
- 单块写:CMD24 + 地址 → 发送数据块 → 返回写响应令牌
- 多块写:CMD25 → 连续推送多块 → 停止令牌结束
四、测试验证
4.1 测试平台搭建
- VIO(虚拟输入输出):动态配置块地址等参数,无需重新烧录
- ILA(集成逻辑分析仪):实时抓取信号波形,定位硬件问题
- 按键触发:KEY2单块读写,KEY3多块读写
- 自动验证机制:写后自动回读,与FIFO缓存逐位比对,error信号+LED指示
4.2 实验步骤
- SD卡格式化为FAT32
- 下载比特流,复位后LED1亮表示初始化成功
- VIO设置块地址(如0x80000),ILA配置触发条件
- 按键触发读写,观测波形与LED状态
4.3 验证结果
- 单块读写:rx_data_d与fifo_dout完全匹配,error保持低电平
- 多块读写:连续传输数据完整一致,无异常中断
- 结论:读写逻辑正确,时序稳定可靠
五、常见问题与故障排查
5.1 SD 卡无法识别(LED1不亮)
- 检查卡是否插好、是否为SD 2.0+版本
- 检查上拉电阻是否正确
- ILA抓取初始化波形,验证CMD0/CMD8的发送与响应
5.2 读写数据错误(LED2亮)
- 确认块地址未超出卡容量
- ILA逐位比对tx_data与rx_data,定位错误点
- 检查时钟频率是否过高导致时序违例
- 验证CRC校验逻辑是否正确
5.3 写操作失败
- 检查Data Response Token,判断错误类型(地址/锁定/CRC)
- 确认SD卡已完成擦除并进入接收状态
- 检查数据传输结束位标记是否正确
核心排查思路:从硬件连接入手,结合ILA工具分析波形,逐层定位协议与逻辑问题。
💡 完整视频讲解可前往 ALINX 视频号进行直播回看
更多细节欢迎关注我们黑金云课堂全年免费直播课,
黑金云课堂六月直播日历 我们将在每周二、三、四,同步推进Verilog开发、Vitis开发、Linux开发三大系列,带你从零开始,稳扎稳打掌握 FPGA 开发全流程!
| 系列 | 内容定位 |
|---|---|
| Verilog开发 | 硬件描述语言基础、逻辑设计、仿真调试 |
| Vitis开发 | Zynq软硬件协同、外设驱动、网络协议栈 |
| Linux开发 | 嵌入式Linux系统移植、驱动编写、应用开发 |