FPGA上实现SD卡连续多块读的命令

在FPGA上实现SD卡连续多块读的命令

CMD17命令一次只能读取1个块

CMD18命令一次可以连续读取多个块,直到停止命令CMD12

CMD18命令读的块数程序可任意设置

目录

前言

一、SD卡多块读命令CMD18

二、停止读命令CMD12

三、SD卡初始化+SD卡连续块读操作的verilog代码

总结


前言

在用FPGA驱动LCD显示屏播放视频时,视频数据是存到SD卡里面的,播放视频对数据量的读需求非常大。如果用单块读CMD17命令显然无法满足我屏幕320*320的分辨率单像素16bit 24帧的需求,因为实测发现SD卡每次发单块读CMD17命令后,中间都要等很长一段时间,SD卡才会开始返回数据,这个等的时间比返回512个字节的时间还要多。所以得发送CMD18命令,改命令发一次可以连续读取多个块,直到发送停止命令CMD12,SD卡停止读,这样方可满足播放视频的需求。以下内容是对SD卡连续多块读操作的说明,同时也给出了相应的时序波形图,方便理解。


++提示:以下是本篇文章正文内容,均为作者本人原创,写文章实属不易,希望各位在引用时附上本文链接。++

一、SD卡多块读命令CMD18

关于SD的初始化,单块读写操作见文章,基于FPGA的SD卡音乐播放器之SD卡篇_sdio verilog-CSDN博客本文不再叙述。

CMD18命令芯片手册描述如下:

可见,发一次命令返回多个块,发送CMD18命令格式如下:

cmd_rd <= {8'h52,rd_sec_addr_buf,8'hff}; //写入连续读多个快CMD18

其中rd_sec_addr_buf是读的32位起始扇区地址,由于SD卡在SPI模式下默认不开启CRC校验,所以校验字节直接填的8'hff。发完命令后等8bit R1的响应,正常情况下响应的8bit为全0,然后准备开始解析SD卡返回的数据头0xfe, 解析到数据头0xfe后,接下来接收SD卡返回的512个字节的数据,紧接着又会有下一块,依然是先解析到数据头0xfe后,再接收SD卡返回的512个字节的数据,如此循环直到发送CMD12这个停止命令。由此可见一次读多少个块是由主机什么时候发停止命令决定的。为了方便,我在编程的时候定义了一个参数,即一次连续读多少个块,读够后即发送停止命令,该参数可随意设置,设置成1就和单块读没区别。

该命令的实测波形图如下,注意由于MISO下降沿稳定,所以ILA抓取时注意用clk的下降沿取抓数据。

观察这张波形图,就能明白为什么我开始说的发命令后等的时间比返回512个字节的时间还要多了。放大发命令的部分如下图所示,可见发完命令后,SD卡会返回R1数据8'h00。

返回数据部分放大如下:

下面是抓取的解析后的数据,解析时是每两个字节凑成16bit,和winhex中的数据完全对得上。

下图是两个块交界处的时序,可见第一个块数据返回完后,会接着有两字节的CRC,然后又去解析FE,之后便是下一个块的数据。

可见块连续读,一个块的数据返回完后,过24个CLK(图中9793-9769,2个FF+1个FE)就会接着返回下一个块的数据,比单块读效率高多了。

二、停止读命令CMD12

CMD12命令芯片手册描述如下:

R1b和R1类似,只是其带有忙信号。发送CMD18命令格式如下:

cmd_rd <= {8'h4C,32'b0,8'hff}; //停止读命令CMD12

parameter RD_BLOCKS = 20'd400; //SD卡连读读一次的块数

我在程序中定义了SD卡连读读一次的块数,支持修改为任意值,这里400是因为320*320的16bit像素一帧需要连续读400个块的数据。

三、SD卡初始化+SD卡连续块读操作的verilog代码

代码已经完成了SD卡的初始化,设置RD_BLOCKS后,连续读只需要将sd_rd_start_en拉高一个电平,在电平拉高的同时,给sd_rd_sec_addr复制块读开始读的扇区地址后,接下来sd_rd_val_en和sd_rd_val_data就会返回数据,其中sd_rd_val_en是是数据有效标志。

sd_ctrl_top

#(

.RD_BLOCKS(RD_BLOCKS)

)

u_sd_ctrl_top(

.clk_ref (clk),

.clk_ref_180deg (!clk),

.rst_n (rst_n),

//SD卡接口

.sd_miso (sd_miso),

.sd_clk (sd_clk),

.sd_cs (sd_cs),

.sd_mosi (sd_mosi),

//用户读SD卡接口

.rd_start_en (sd_rd_start_en),

.rd_sec_addr (sd_rd_sec_addr),

.rd_busy (sd_rd_busy),

.rd_val_en (sd_rd_val_en),

.rd_val_data (sd_rd_val_data),

.sd_init_done (sd_init_done)

);

https://download.csdn.net/download/m0_66360845/90601476https://download.csdn.net/download/m0_66360845/90601476


总结

以上就是本文全部内容,给出了每个步骤的时序图,对理解块读操作很有帮助。写这篇文章的目的一是为了分享知识,二是为了记录实现方法,方便自己回顾。

相关推荐
FPGA小迷弟10 小时前
FPGA 与卫星:从星载硬件到在轨智能的完整技术解析
fpga开发·架构·fpga·1024程序员节·无线电
LabVIEW开发1 天前
FlexRIO 在轨图像取舍:判决要跑在数据进内存之前
labview·fpga·labview功能·labview程序·flexrio
FPGA小迷弟1 天前
FPGA 与无线电:从软件定义无线电到 5G 基带的硬件实现之路
5g·fpga开发·架构·dsp开发·fpga·无线电
yingheceping1 天前
2026 国产 FPGA 核心板怎么选?工控/视觉/通信/科研,四场景对板指南
fpga开发·fpga
FPGA小徐2 天前
FPGA离散数列信源熵:原理、计算与硬件实现全解
fpga
玄芯散人3 天前
【元婴·114】SD卡和FatFS文件系统:数据持久化
stm32·sd卡·fatfs
FPGA小徐3 天前
【FPGA数字信号处理】离散信源香农熵计算:原理详解 + 纯Verilog可综合实现 + 全套仿真代码
fpga
FPGA小迷弟5 天前
FPGA开发Vivado Block Design/Vitis/SDK/xlinx/开发教程,保姆级别,一看就会!
网络协议·tcp/ip·fpga开发·verilog·fpga
FPGA小迷弟5 天前
基于FPGA实现智能网卡的概念,什么是智能网卡
网络协议·tcp/ip·fpga开发·verilog·fpga
hi冻鱼6 天前
PCIe + DDR架构(一):实测——块长从4 KiB 换 1 MiB,带宽从133 MB/s 涨到 3179 MB/s
性能测试·fpga·pcie·mig·xdma·1024程序员节·ddr3