引言:上一篇博文介绍了SD卡的理论知识,本文我们介绍如何利用FPGA实现SD卡的读写操作。
1.硬件电路
开发板上装有一个 Micro SD 卡座,FPGA 通过 SPI 数据总线访问 Micro SD 卡, SD 卡座和 FPGA的硬件电路连接如图1所示。
图1:SD卡硬件原理图设计
本文通过SD卡SPI模式进行读写操作,SPI模式管脚定义如图1所示。
2. SD卡协议简介
SD卡的协议是一种简单的命令/响应的协议。全部命令由主机发起,SD卡接收到命令后并返回响应数据。根据命令的不同,返回的数据内容和长度也不同。
SD卡命令是一个6字节组成的命令包,其中第一个字节为命令号,命令号高位bit7和bit6为固定的“01“,其它6个bit为具体的命令号。第2个字节到第5个字节为命令参数。第6个字节为7个bit的CRC校验加1个bit的结束位。如果在SPI模式的时候,CRC校验位为可选。如图2所示,Command表示命令,通常使用十进制表示名称,例如CMD17,这个时候 Command就是十进制的17。
图2:SD卡命令格式
SD卡对每个命令会返回一个响应,每个命令有一定的响应格式。响应的格式跟给它的命令号有关。在 SPI 模式中,有三种响应格式:R1,R2,R3。
图3:SPI模式响应R1格式
图4:SPI模式响应R2格式
图5:SPI模式响应R3格式
2.2.1 SD卡2.0版的初始化步骤
(1)上电后延时至少74clock,等待SD卡内部操作完成;
(2) 片选CS低电平选中SD卡;
(3)发送CMD0,需要返回0x01,进入Idle状态;
(4)为了区别SD卡是2.0还是1.0,或是MMC卡,这里根据协议向上兼容的,首先发送只有SD2.0才有的命令CMD8,如果CMD8返回无错误,则初步判断为2.0卡,进一步循环发送命令CMD55+ACMD41,直到返回0x00,确定 SD2.0卡;
(5)如果CMD8返回错误则判断为1.0卡还是MMC卡,循环发送 CMD55+ACMD41,返回无错误,则为SD1.0卡,到此SD1.0卡初始成功,如果在一定的循环次数下,返回为错误,则进一步发送CMD1进行初始化,如果返回无错误,则确定为MMC卡,如果在一定的次数下,返回为错误,则不能识别该卡,初始化结束。(通过CMD16可以改变SD卡一次性读写的长度);
(6) CS 拉高。
2.2.2 SD卡的读步骤
(1)发送 CMD17(单块)或 CMD18(多块)读命令,返回 0X00;
(2)接收数据开始令牌fe(或fc)+正式数据512Bytes+CRC校验2Bytes,默认正式传输的数据长度是 512Bytes。图 6:单块读操作
2.2.3 SD卡的写步骤
(1)发送 CMD24(单块)或 CMD25(多块)读命令,返回 0X00;
(2)接收数据开始令牌fe(或fc)+正式数据512Bytes+CRC校验2Bytes。
图 7:单块写操作
3.FPGA实现
(1)软件实现
本文要利用FPGA通过SPI接口实现SD卡读写操作。具体功能如下:
(1)SD卡SPI接口驱动设计;
(2)SD卡读写操作;
(3)读出数据显示在LED灯上;
(4)按键消抖功能。
软件功能模块划分如图8所示。
图8:软件功能模块框图
各个模块功能:
(1)sd_card_test.v模块为顶层模块,实现模块间互联;(2)spi_master.v实现SPI总线接口对外通信功能;
(3)sd_card_cmd.v实现SD卡命令协议功能;
(4)sd_card_sec_read_write.v实现SD卡读写命令状态机操作功能;
(5)sd_card_top.v实现SD卡读写功能顶层互联;
(6)KeyJitters.v实现按键操作消抖功能;
(7)sd_test_ctrl.v实现SD卡测试数据读写状态机控制。
(2)测试结果
软件下载至电路板,SD卡读出数据正常显示在LED上,如图9所示,显示读写操作正确。
图9:SD卡读出数据
图10:SD卡读出数据显示在LED灯上
感谢关注公众号,喜欢就多多转发吧!