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


总结

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

相关推荐
霖002 天前
FPGA实战项目1——坦克大战
人工智能·经验分享·嵌入式硬件·学习·fpga开发·fpga
雪天鱼4 天前
DSP48E2 的 MAC模式功能仿真
fpga开发·fpga·dsp48e2
霖007 天前
FPGA中级项目8———UART-RAM-TFT
网络·经验分享·嵌入式硬件·fpga开发·显示器·fpga
XINVRY-FPGA15 天前
XCZU19EG-2FFVC1760I Xilinx赛灵思FPGA Zynq UltraScale+MPSoC
c++·嵌入式硬件·阿里云·fpga开发·云计算·硬件工程·fpga
XINVRY-FPGA16 天前
赛灵思 XC7K325T-2FFG900I FPGA Xilinx Kintex‑7
人工智能·嵌入式硬件·ai·fpga开发·fpga·pcb工艺·zynq
XINVRY-FPGA16 天前
XCZU7EG‑L1FFVC1156I 赛灵思XilinxFPGA ZynqUltraScale+ MPSoC EG
c++·嵌入式硬件·阿里云·fpga开发·云计算·fpga·pcb工艺
贝塔实验室17 天前
基于XC7V690T的在轨抗单粒子翻转系统设计
设计模式·fpga开发·系统架构·流程图·软件构建·个人开发·fpga
XINVRY-FPGA17 天前
XC7K410T‑2FFG900I 赛灵思XilinxFPGA Kintex‑7
嵌入式硬件·安全·阿里云·ai·fpga开发·云计算·fpga
XINVRY-FPGA21 天前
XC6SLX100T-2FGG484I 赛灵思 XilinxFPGA Spartan-6
c++·人工智能·嵌入式硬件·阿里云·ai·fpga开发·fpga
北城笑笑25 天前
FPGA 37 ,FPGA千兆以太网设计实战:RGMII接口时序实现全解析( RGMII接口时序设计,RGMII~GMII,GMII~RGMII 接口转换 )
fpga开发·fpga