RISC-V MCU中文社区

【分享】 【分享】SD卡初始化原理讲解与实现 队伍名称:Cambrain_20

发表于 中国研究生创芯大赛 2021-06-24 19:12:48
0
173
1

队伍名称:Cambrain_20

分享内容:SD卡

我们对 SD 的读写协议一般有 SPI 模式和 SDIO 模式两种,由于SPI 在芯片管脚上只占用四根线,而且SPI 实现SD卡读写只需要修改一些 SPI 接口逻辑就可以实现,因此,我们采用的是SPI 模式对SD卡进行操作。 SPI 是串行外设接口(Serial Peripheral Interface)的缩写。是 Motorola 公司推出的一种同步 串行接口技术,是一种高速的,全双工,同步的通信总线。SPI 具有支持全双工通信;通信简单;数据传输速率快;高速、同步、全双工、非差分、总线式;主从机通信模式等特点。 SPI 模式的信号线有:CSCLKMISOMOSI4 根线。

由于板子只能插入 TF 卡即 MicroSD card,我查阅相关资料得到 TF 卡的 SPI 模式接口(如图),通过这些接口,将 SD 卡和 FPGA 通过 SPI 模式连接起来对其进行操作。



图5.4:SD卡接口简介

 

SD卡管脚

FPGA管脚

 

 

sd_miso

F16

 

 

sd_clk

C18

 

 

sd_cs

F18

 

 

SD卡初始化步骤:

SD 卡初始化过程: 在对 SD 卡初始化之前,我们需要对其上电后复位。复位的方法为:

拉高 CS,发送至少 74 个时钟周期来使 SD 卡达到正常工作电压和进行同步

选低 CS,发送 CMD0,需要收到回应 0x01 表示成功进入等待状态

拉高 CS,发送 8 个时钟

复位成功后我们就可以对其进行初始化了。初始化的过程较复杂,对其过程总结如下:

使用 CMD,发送 CMD1,收到 0x00 表示成功

使用 CMD55+ACMD41

发送 CMD55(表示接下来要对其使用 ACMDx 类的命令),收到 0x01

发送 ACMD41,收到 0x00 表示成功

命令RTL代码


parameter CMD0 = {8'h40,8'h00,8'h00,8'h00,8'h00,8'h95}; parameter CMD8 = {8'h48,8'h00,8'h00,8'h01,8'haa,8'h87}; parameter CMD55 = {8'h77,8'h00,8'h00,8'h00,8'h00,8'hff}; parameter ACMD41= {8'h69,8'h40,8'h00,8'h00,8'h00,8'hff}; parameter DIV_FREQ = 200; parameter OVER_TIME_NUM = 25000;



 

状态机实现部分RTL代码

 case(cur_state)

            st_idle : begin 

                sd_cs <= 1'b1; 

                sd_mosi <= 1'b1; 

            end

            st_send_cmd0 : begin 

                cmd_bit_cnt <= cmd_bit_cnt + 6'd1;

                sd_cs <= 1'b0;

                sd_mosi <= CMD0[6'd47 - cmd_bit_cnt]; 

                if(cmd_bit_cnt == 6'd47)

                    cmd_bit_cnt <= 6'd0;

            end

            st_wait_cmd0 : begin

                sd_mosi <= 1'b1;

                if(res_en) 

                    sd_cs <= 1'b1;

                over_time_cnt <= over_time_cnt + 1'b1; 

                if(over_time_cnt == OVER_TIME_NUM - 1'b1)

                    over_time_en <= 1'b1;

                if(over_time_en)

                    over_time_cnt <= 16'd0;

            end

            st_send_cmd8 : begin 

                if(cmd_bit_cnt<=6'd47) begin

                    cmd_bit_cnt <= cmd_bit_cnt + 6'd1;

                    sd_cs <= 1'b0;

                    sd_mosi <= CMD8[6'd47 - cmd_bit_cnt];

                end

                else begin

                    sd_mosi <= 1'b1;

                    if(res_en) begin 

                        sd_cs <= 1'b1;

                        cmd_bit_cnt <= 6'd0;

                    end

                end

            end

            st_send_cmd55 : begin 

                if(cmd_bit_cnt<=6'd47) begin

                    cmd_bit_cnt <= cmd_bit_cnt + 6'd1;

                    sd_cs <= 1'b0;

                    sd_mosi <= CMD55[6'd47 - cmd_bit_cnt];

                end

                else begin

                    sd_mosi <= 1'b1;

                    if(res_en) begin 

                        sd_cs <= 1'b1;

                        cmd_bit_cnt <= 6'd0;

                    end

                end

            end

            st_send_acmd41 : begin 

                if(cmd_bit_cnt <= 6'd47) begin

                    cmd_bit_cnt <= cmd_bit_cnt + 6'd1;

                    sd_cs <= 1'b0;

                    sd_mosi <= ACMD41[6'd47 - cmd_bit_cnt];

                end

                else begin

                    sd_mosi <= 1'b1;

                    if(res_en) begin 

                        sd_cs <= 1'b1;

                        cmd_bit_cnt <= 6'd0;

                    end

                end

            end

            st_init_done : begin 

                sd_init_done <= 1'b1;

                sd_cs <= 1'b1;

                sd_mosi <= 1'b1;

            end

            default : begin

                sd_cs <= 1'b1;

                sd_mosi <= 1'b1;

            end

        endcase


     

喜欢1
用户评论
关于作者
Ada

Ada 未通过人工认证

懒的都不写签名

问答
粉丝
1
关注
2
  • RV-STAR 开发板
  • RISC-V处理器设计系列课程
  • 培养RISC-V大学土壤 共建RISC-V教育生态
RV-STAR 开发板