SD卡读写

特别说明:以下所涉及代码参考网络、相关开发板厂家。只用于自己学习、理解和感悟。

SD存储卡( Secure Digital Memory Card)是一种基于半导体快闪存储器的新一代高速存储设备。SD 卡是现在嵌入式设备重要的存储模块。通常SD卡中都有文件系统,可以安装文件名和目录路径来读写文件。SD卡结构如下图所示:
在这里插入图片描述

  1. SD卡协议简介

在这里插入图片描述

数明:SD卡命令是6字节组成的命令包。
a) 命令码:
命令码由1个字节组成,第7位和第6位固定为“01”。
b) 校验与结束码:
校验与结束码由7位CRC校验和1位结束码组成。
c) 命令参数码:
2. 响应:
SD卡对每个命令多有响应,在SPI模式下有三种响应模式:R1、R2、R3。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. SD卡2.0版的初始化步骤:
    a.上电后延时至少 74clock,等待 SD 卡内部操作完成。
    b. 片选 CS 低电平选中 SD 卡。
    c. 发送 CMD0,需要返回 0x01,进入 Idle 状态。
    d. 为了区别 SD 卡是 2.0 还是 1.0,或是 MMC 卡,这里根据协议向上兼容的,首先发送只有 SD2.0 才有的命令 CMD8,如果 CMD8 返回无错误,则初步判断为 2.0 卡,进一步循环发送命令CMD55+ACMD41,直到返回 0x00,确定 SD2.0 卡。
    e. 如果 CMD8 返回错误则判断为 1.0 卡还是 MMC 卡,循环发送 CMD55+ACMD41,返回无错误,
    则为 SD1.0 卡,到此 SD1.0 卡初始成功,如果在一定的循环次数下,返回为错误,则进一步发
    送 CMD1 进行初始化,如果返回无错误,则确定为 MMC 卡,如果在一定的次数下,返回为错
    误,则不能识别该卡,初始化结束。(通过 CMD16 可以改变 SD 卡一次性读写的长度)。
    f. CS 拉高。

  2. SD卡的读步骤:
    a. 发送 CMD17(单块)或 CMD18(多块)读命令,返回 0X00。
    b. 接收数据开始令牌 fe(或 fc)+正式数据 512Bytes + CRC 校验 2Bytes 默认正式传输的数据长度是 512Bytes。

  3. SD 卡的写步骤:
    a 发送 CMD24(单块)或 CMD25(多块)写命令,返回 0X00。
    b. 发送数据开始令牌 fe(或 fc)+正式数据 512Bytes + CRC 校验 2Bytes。

相关代码如下:

  1. spi_master.v
    module spi_master(
    input sys_clk,
    input rst,
    output nCS,
    output DCLK,
    output MOSI,
    input MISO,
    input CPOL,
    input CPHA,
    input nCS_ctrl,
    input[15:0] clk_div,
    input wr_req,
    output wr_ack,
    input[7:0] data_in,
    output[7:0] data_out
    );
    localparam IDLE = 0;
    localparam DCLK_EDGE = 1;
    localparam DCLK_IDLE = 2;
    localparam ACK = 3;
    localparam LAST_HALF_CYCLE = 4;
    localparam ACK_WAIT = 5;
    reg DCLK_reg;
    reg[7:0] MOSI_shift;
    reg[7:0] MISO_shift;
    reg[2:0] state;
    reg[2:0] next_state;
    reg[15:0] clk_cnt;
    reg[4:0] clk_edge_cnt;
    assign MOSI = MOSI_shift[7];
    assign DCLK = DCLK_reg;
    assign data_out = MISO_shift;
    assign wr_ack = (state == ACK);
    assign nCS = nCS_ctrl;
    always @(posedge sys_clk or posedge rst)
    begin
    if(rst)
    state <= IDLE;
    else
    state <= next_state;
    end
    always @(*)
    begin
    case(state)
    IDLE:
    if(wr_req == 1’b1)
    next_state <= DCLK_IDLE;
    else
    next_state <= IDLE;
    DCLK_IDLE:
    if(clk_cnt == clk_div)
    next_state <= DCLK_EDGE;
    else
    next_state <= DCLK_IDLE;
    DCLK_EDGE:
    if(clk_edge_cnt == 5’d15)
    next_state <= LAST_HALF_CYCLE;
    else
    next_state <= DCLK_IDLE;
    LAST_HALF_CYCLE:
    if(clk_cnt == clk_div)
    next_state <= ACK;
    else
    next_state <= LAST_HALF_CYCLE;
    ACK:
    next_state <= ACK_WAIT;
    ACK_WAIT:
    next_state <= IDLE;
    default:
    next_state <= IDLE;
    endcase
    end
    always @(posedge sys_clk or posedge rst)
    begin
    if(rst)
    DCLK_reg <= 1’b0;
    else if(state == IDLE)
    DCLK_reg <= CPOL;
    else if(state == DCLK_EDGE)
    DCLK_reg <= ~DCLK_reg;
    end
    always @(posedge sys_clk or posedge rst)
    begin
    if(rst)
    clk_cnt <= 16’d0;
    else if(s
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值