通信控制篇

您所在的位置:网站首页 怎么看sd卡写入速度 通信控制篇

通信控制篇

2023-09-05 07:24| 来源: 网络整理| 查看: 265

通信控制篇——SD卡数据传输(一) 1.简介

利用FPGA实现SD卡数据传输——SPI模式。

2.原理 SD卡简介

SD卡——Secure Digital Memory Card。最早的SD卡是从MMC卡发展而来的,目前SD卡有三种规范——SD1.0、SD2.0和SD3.0,SD1.0已经不用了,目前主流的规范是SD2.0和SD3.0,SD2.0被称为高速卡,传输速度在2MB/s以上,SD3.0被称为超高速卡,传输速度可达104MB/s。

SD卡容量有3个级别——SD、SDHC和SDXC,下表为各等级的容量范围和标准磁盘格式:

容量等级容量范围磁盘格式SD不大于2GBFAT12,16SDHC2GB~32GBFAT32SDXC32GB~2TBexFAT

SD2.0规范中,规定了不同传输速率的等级,如下表:

速率等级性能要求Class 0无性能要求Class 2大于等于2MB/sClass 4大于等于4MB/sClass 6大于等于6MB/sClass 10大于等于10MB/s

在市面上买的SD卡,卡面上会印有“HC”字样,这代表这张卡是SDHC卡,同理,印有“XC”字样的代表是SDXC卡;而且,卡面上还印有一个圆圈圈起来的数字,这代表速率等级,如4就代表Class 4类型的卡。

在这里插入图片描述

SD卡数据通信

SD卡一般支持两种通信模式,SPI模式和SD模式,这两种模式分别需要使用到的信号及其对应关系如下表:

SD模式信号名SPI模式信号名SD_CLKSD_CLKSD_CMDSD_DATAINSD_DATA0SD_DATAOUTSD_DATA1-SD_DATA2-SD_DATA3SD_CS

在SD卡数据读写时间要求不是很严格的情况下,选用SPI模式可以说是一种最佳的解决方案。因为在SPI模式下,使用相对简单,只要四条线就可以完成所有的数据交换。本文主要介绍SPI模式的数据通信。

SD2.0命令协议

SD卡的协议是一种简单的命令/响应的协议。全部命令由主机发起,SD卡接收到命令后并返回响应数据。根据命令的不同,返回的数据内容和长度也不同。

SD卡命令是一个6字节组成的命令包,其中第一个字节为命令号,命令号高位bit7和bit6为固定的“01“,其它6个bit为具体的命令号。第2个字节到第5个字节为命令参数。第6个字节为7个bit的CRC校验加1个bit的结束位“1”。如果在SPI模式的时候,CRC校验位为可选。

SD卡命令格式:

First ByteByte 2-5Last Byte‘0’+‘1’+CommandArgument (MSB First)CRC+‘1’

SD卡对每个命令会返回一个响应,每个命令有一定的响应格式。响应的格式跟给它的命令号有关。在SPI模式中,有三种响应格式:R1(1个字节),R2(2个字节),R3(5个字节)。(具体可参照SD2.0协议官方文档,本文不再赘述)

下面列举一些常用的SD命令及响应格式:

CommandArgumentTypeDescriptionCMD0NoneR1Tell the card to reset and enter its idle stateCMD1632-bit Block LengthR1Select the block lengthCMD1732-bit Block AddressR1Read a single blockCMD2432-bit Block AddressR1Write a single blockCMD55NoneR1Next command will be application-specific (ACMD××)CMD58NoneR3Read OCR (Operating Conditions Register)ACMD41NoneR1Initialize the card SD卡初始化 选择SPI模式

SD卡上电后,默认为SD模式,只要在发送CMD0命令的同时使得CS置低,若SD卡返回响应无错误,则已经进入了SPI模式。一旦选择了SPI模式,只有当SD卡掉电重启后,才会退出SPI模式。

SPI模式初始化步骤 发送CMD0,需要返回0x01,进入Idle状态(这一步同时需要令CS置低,选择SPI模式);为了区别SD卡是2.0还是1.0,或是MMC卡,这里根据协议向下兼容的原则,首先发送只有SD2.0才有的命令CMD8,如果CMD8返回无错误,则初步判断为2.0卡,进一步发送命令循环发送CMD55+ACMD41,直到返回0x00,确定SD2.0卡;如果CMD8返回错误则判断为1.0卡或是MMC卡,循环发送CMD55+ACMD41,返回无错误,则为SD1.0卡,到此SD1.0卡初始成功,如果在一定的循环次数下,返回为错误,则进一步发送CMD1进行初始化,如果返回无错误,则确定为MMC卡,如果在一定的次数下,返回为错误,则不能识别该卡,初始化结束。CS拉高。 初始化流程图

初始化流程图

流程图详细说明请参考SD2.0协议官方文档。

SD卡数据读取 发送CMD17(单块)或CMD18(多块)读命令,返回0x00;接收数据开始令牌0xfe(或0xfc)+正式数据512Bytes + CRC校验2Bytes。默认正式传输的数据长度是512Bytes,可用CMD16设置块长度。

在这里插入图片描述

SD卡数据写入 发送CMD24(单块)或CMD25(多块)写命令,返回0x00;发送数据开始令牌0xfe(或0xfc)+正式数据512Bytes + CRC校验2Bytes。

在这里插入图片描述

关于具体的SD2.0的时序和标准,请大家参考文档SD2.0_Final_bookmark.pdf

3.程序实现 SD卡初始化模块 library ieee; use ieee.std_logic_1164.all; entity sd_init is port ( sd_clk : in std_logic; --sd卡SPI时钟25MHz rst : in std_logic; --复位信号,低电平有效 sd_cs : out std_logic; --sd片选信号,低电平有效,在发送和接收数据时,CS都需要置0 sd_data_in : out std_logic; --sd卡数据输入 sd_data_out : in std_logic; --sd卡数据输出 rx : buffer std_logic_vector(47 downto 0); --接收sd卡输出数据(存储48位) init_o : out std_logic; --sd卡初始化完成信号,高电平有效 init_state : buffer std_logic_vector(3 downto 0) --sd初始化状态 ); end sd_init; architecture tt of sd_init is --常量定义 constant idle:std_logic_vector(3 downto 0):= "0000"; --状态为idle constant send_cmd0:std_logic_vector(3 downto 0):= "0001"; --状态为发送CMD0 constant wait_cmd0:std_logic_vector(3 downto 0):= "0010"; --状态为等待CMD0应答 constant wait_time:std_logic_vector(3 downto 0):= "0011"; --状态为等待一段时间 constant send_cmd8:std_logic_vector(3 downto 0):= "0100"; --状态为发送CMD8 constant wait_cmd8:std_logic_vector(3 downto 0):= "0101"; --状态为等待CMD8应答 constant send_cmd55:std_logic_vector(3 downto 0):= "0110"; --状态为发送CMD55 constant send_acmd41:std_logic_vector(3 downto 0):= "0111"; --状态为发送ACMD41 constant init_done:std_logic_vector(3 downto 0):= "1000"; --状态为初始化结束 constant init_fail:std_logic_vector(3 downto 0):= "1001"; --状态为初始化错误 --信号定义 signal CMD0:std_logic_vector(47 downto 0):= x"400000000095"; --CMD0命令, 需要CRC 95 signal CMD8:std_logic_vector(47 downto 0):= x"48000001aa87"; --CMD8命令, 需要CRC 87 signal CMD55:std_logic_vector(47 downto 0):= x"7700000000ff"; --CMD55命令, 不需要CRC signal ACMD41:std_logic_vector(47 downto 0):= x"6940000000ff"; --ACMD41命令, 不需要CRC signal reset:std_logic:= '1'; --复位信号,高电平时有效,进行延时片选sd卡复位;低电平时进行sd卡初始化 signal init_cnt:integer range 0 to 1023 := 0; --初始化计时计数器 signal delay_cnt:integer range 0 to 1023 := 0; --延时计数器 signal bit_cnt:integer range 0 to 47 := 0; --48位命令传输计数器 signal rx_valid:std_logic:= '0'; --接收数据有效信号(即接收48位命令完成) signal rx_start:std_logic:= '0'; --开始接收数据 begin --接收sd卡的数据 process(sd_clk) begin if(sd_clk'event and sd_clk = '1')then rx(0)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3