打印
[STM32F1]

STM32 基础篇——SD 卡实验

[复制链接]
3573|83
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
实验目标:
1. 复习 STM32 硬件 SPI
2. 学会对 SD 卡进行读写
沙发
aizaixiyuanqian|  楼主 | 2018-3-19 23:00 | 只看该作者
STM32 硬件 SPI
在上一次实验,讲述 FLASH 的时候,我们已经介绍过 STM32 的硬件设置了,其
实 SD 使用的 SPI 设置跟 FLASH 使用的 SPI 是一样的,只是它们的片选信号不
一样而已。

使用特权

评论回复
板凳
aizaixiyuanqian|  楼主 | 2018-3-19 23:02 | 只看该作者
SD 卡的原理图


使用特权

评论回复
地板
aizaixiyuanqian|  楼主 | 2018-3-19 23:02 | 只看该作者
SD 卡又两种操作方式,一种是 SDIO 模式,还有一种是 SPI 模式,今天我们
介绍的是使用 SPI 模式。所以在设置做实验的时候,SD 卡部分的跳帽跳到 IO 部
分。

使用特权

评论回复
5
aizaixiyuanqian|  楼主 | 2018-3-19 23:03 | 只看该作者
SD 卡简介
SD 卡是由 MMC 卡的基础上发展而来的,它是一种基于半导体快闪**器
的新一代**设备,被广泛应用于各种便携设备,如手机、数码相机、多媒体播
放器等

使用特权

评论回复
6
aizaixiyuanqian|  楼主 | 2018-3-19 23:04 | 只看该作者
SD 卡可以分为三类:SD 卡、SDHC 卡、SDXC 卡

使用特权

评论回复
7
aizaixiyuanqian|  楼主 | 2018-3-19 23:07 | 只看该作者
它的通信协议也分为两种,一种是 V1.0 版本和 V2.0 版本,所以不同的版本
操作过程中会有一定的差异。对于 SD 卡和 SDHC 卡来说,协议基本是兼容的,
不过 SDXC 卡,区别就大了。在这里我们主要讨论的是 SD 卡和 SDHC 卡。而
SD 卡的通信接口也有两种模式,一种是 SDIO 模式,还有一种是 SPI 模式,这
里我们主要讨论的是 SPI 模式下的 SD 卡。使用 STM32 的 SPI 驱动 SD 卡,最高
通信速度可达 18Mbps,每秒可传输数据 2M 字节以上,对于一般的应用足够了。

使用特权

评论回复
8
aizaixiyuanqian|  楼主 | 2018-3-19 23:10 | 只看该作者
SD 卡的操作
要操作 SD 卡,最重要的就是如何初始化 SD 卡、读 SD 卡、写 SD 卡。其他
的读取 SD 卡的其他型号信息等,都是次要的,只有偶尔才会用到。而学习初始
化 SD 卡,读 SD 卡之前,我们要先学会怎么向 SD 写命令

使用特权

评论回复
9
aizaixiyuanqian|  楼主 | 2018-3-19 23:11 | 只看该作者
SD 卡写命令操作
SD 卡的命令格式如下:


使用特权

评论回复
10
aizaixiyuanqian|  楼主 | 2018-3-19 23:11 | 只看该作者
长度为 48 位,一共分为第一个字节的最高 2 位必须是 01。接下来 6 位是命
令号,比如:CMD0 其实就是 0x00;CMD16 其实是 0x10。第 2 个字节到第 5
个字节是命令参数,命令参数是特定的命令才会有的。剩下第 6 个字节是一个 7
位的 CRC 效验和最低位为 1 组成。

使用特权

评论回复
11
aizaixiyuanqian|  楼主 | 2018-3-19 23:29 | 只看该作者
接下来我们来看一下 SD 卡的一些命令参数:

使用特权

评论回复
12
aizaixiyuanqian|  楼主 | 2018-3-19 23:29 | 只看该作者
从图上我们可以看出,每个命令后面都会有一个回应,所以 SD 卡和单片机
之间的通信是采用发送应答机制。
它的应答类型有 R1~R7,一共 7 种。不同的命令,长度可能不一样

使用特权

评论回复
13
aizaixiyuanqian|  楼主 | 2018-3-19 23:30 | 只看该作者
从上面,我们可以看出,R1 的长度为 48 位,而 R2 的长度为 136 位。不过
虽然回应的长度不同,不过呢,它们的应答都有一个特点,那就是最高两位都为
00(大家可以通过查看《SD 卡 2.0 协议》等对比),这个时候表示命令发送成功。

使用特权

评论回复
14
aizaixiyuanqian|  楼主 | 2018-3-19 23:30 | 只看该作者
写命令的操作步骤为:
1) 如果上次片选没有取消,那么先取消片选,取消片选之后提供格外
的 8 个时钟周期,方便 SD 卡准备好。
2) 选择片选。
3) 检测 SD 卡是否准备好,也就是一直发送 0xFF,直到接收到非 0xFF
为止。
4) 发送 6 个字节的命令格式。包括 1 个字节命令序号,4 个字节的命令
参数,1 个字节的 CRC 效验。注意第 1 个字节最高两位为 01。第 6
个字节最低位为 1。
5) 如果是 CMD12 停止数据传输命令的话,多发送 8 个时钟周期。也就
是发送 0xFF 一次,为了避免影响之后检测是否发送成功。
6) 检测是否发送命令成功。因为我们不知道回应有多少个字节,所以
一直读取回应数据,直到最高两位为 00 时,说明发送成功。

使用特权

评论回复
15
aizaixiyuanqian|  楼主 | 2018-3-19 23:38 | 只看该作者
向 SD 卡发送一个命令.SD 卡一个命令格式包括 8 位 命令,32 位命令参数和 7 位 CRC 效验位,最后一位为 1
static uint8_t SD_WriteCmd(uint8_t cmd, uint32_t dat, uint8_t crc)
{
uint8_t r1 = 0;
uint16_t i = 0;
//--复位 SD 卡,取消上次片选--//
SD_CS_SET;
SPI2_WriteReadData(0xFF); //额外提供 8 个时钟
SD_CS_CLR;
while(SPI2_WriteReadData(0xFF) != 0xFF) //等待卡是否准备好
{
i++;
if(i > 100)
{
return 0xFF; //等待失败返回
}
}
//--发送数据--//
SPI2_WriteReadData(cmd | 0x40);
SPI2_WriteReadData(dat >> 24); //发送 Dat 的最高 8 位
SPI2_WriteReadData(dat >> 16);
SPI2_WriteReadData(dat >> 8);
SPI2_WriteReadData(dat & 0x00FF);
SPI2_WriteReadData(crc & 0x01);
if(cmd == SD_CMD12) //如果是停止数据传输命令,额外多发
一个时钟
{
SPI2_WriteReadData(0xFF);
}
i = 0;
do
{
r1 = SPI2_WriteReadData(0xFF);
i++;
if(i > 100)
{
return 0xFF;
}
}
while((r1 & 0x80) != 0); //发送成功的最高位是 0
return r1;

}

使用特权

评论回复
16
aizaixiyuanqian|  楼主 | 2018-3-20 16:19 | 只看该作者
初始化的时候我们要用到
CMD0、CMD8、ACMD41、CMD58。其中 CMD8、CMD58 都要查看相应
应答,这里我们来讲一下这些命令的应答。

使用特权

评论回复
17
aizaixiyuanqian|  楼主 | 2018-3-20 16:20 | 只看该作者
CMD8
CMD8 的应答是 R7,它返回的数据类型如下

使用特权

评论回复
18
aizaixiyuanqian|  楼主 | 2018-3-20 16:21 | 只看该作者
CMD58。
CMD58 的返回值是 R3,R3 的数据类型如下:


使用特权

评论回复
19
aizaixiyuanqian|  楼主 | 2018-3-20 16:21 | 只看该作者
要读取的 CCS 是在返回值的第 2 个字节(OCR
的第 30 位,注意的是它返回的时候是从高字节开始返回的,所以是第 2
个字节,第 1 个字节是 R1);而要确认电压是在返回值的第 5 个字节的
第 7 位。

使用特权

评论回复
20
aizaixiyuanqian|  楼主 | 2018-3-20 16:22 | 只看该作者
上电之后初始化之后,进行至少 74 个时钟周期的上电延时,这个是
必须的(具体大家可以查看数据手册复位部分)。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

1353

帖子

6

粉丝