队伍名称:Cambrain_20
分享内容:SD卡
我们对 SD 的读写协议一般有 SPI 模式和 SDIO 模式两种,由于SPI 在芯片管脚上只占用四根线,而且SPI 实现SD卡读写只需要修改一些 SPI 接口逻辑就可以实现,因此,我们采用的是SPI 模式对SD卡进行操作。 SPI 是串行外设接口(Serial Peripheral Interface)的缩写。是 Motorola 公司推出的一种同步 串行接口技术,是一种高速的,全双工,同步的通信总线。SPI 具有支持全双工通信;通信简单;数据传输速率快;高速、同步、全双工、非差分、总线式;主从机通信模式等特点。 SPI 模式的信号线有:CS、CLK、MISO、MOSI,4 根线。
由于板子只能插入 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 卡初始化之前,我们需要对其上电后复位。复位的方法为:
1 拉高 CS,发送至少 74 个时钟周期来使 SD 卡达到正常工作电压和进行同步
2 选低 CS,发送 CMD0,需要收到回应 0x01 表示成功进入等待状态
3 拉高 CS,发送 8 个时钟
复位成功后我们就可以对其进行初始化了。初始化的过程较复杂,对其过程总结如下:
4 使用 CMD,发送 CMD1,收到 0x00 表示成功
5 使用 CMD55+ACMD41
6 发送 CMD55(表示接下来要对其使用 ACMDx 类的命令),收到 0x01
7 发送 ACMD41,收到 0x00 表示成功
命令RTL代码
状态机实现部分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