文章目录
一. 认识SD卡
1. 介绍SD卡
SD存储卡是一种基于半导体快闪记忆器的新一代记忆设备,由于它体积小、数据传输速度快、可热插拔等优良的特性,被广泛地于便携式装置上使用,例如数码相机、平板电脑和多媒体播放器等。
控制器对SD卡进行读写通信操作一般有两种通信接口可选,一种是 SPI接口,另外一种就是 SDIO接口。
2. SD卡的物理结构
一般SD卡包括有存储单元、存储单元接口、电源检测、卡及接口控制器和接口驱动器 5个部分。
- 存储单元是存储数据部件,存储单元通过存储单元接口与卡控制单元进行数据传输;
- 电源检测单元保证SD卡工作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接口复位;
- 卡及接口控制单元控制SD卡的运行状态,它包括有8个寄存器;
- 接口驱动器控制SD卡引脚的输入输出。
3. SD卡寄存器
SD卡总共有8个寄存器,用于设定或表示SD卡信息。
这些寄存器只能通过对应的命令访问,SDIO定义64个命令,每个命令都有特殊意义,可以实现某一特定功能,SD卡接收到命令后,根据命令要求对SD卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现SD卡的控制以及读写操作。
- 寄存器及功能描述如下
寄存器名称 | 描述 |
---|---|
OCR | 32位的操作条件寄存器主要存储了VDD电压范围,SD卡操作电压范围为2~3.6V |
CID | 卡识别码寄存器,长度为16个字节,存储SD卡唯一标识号,该号在卡生产厂家编程后无法修改 |
CSD | 卡特性数据寄存器,包含了访问该卡数据时的必要配置信息 |
SCR | SD卡配置寄存器(SCR),提供了SD卡的一些特殊特性在这张卡内,长度为64位,这个寄存器内容由制造商在生产厂内设置 |
RCA | 卡相对地址寄存器是一个16位可写的地址寄存器,控制器可通过地址选择对应地址的SD卡 |
DSR | 驱动级寄存器,属于可选寄存器,用于配置卡的驱动输出 |
SSR | SD状态(SD Status):SD卡专有特征的信息 |
CSR | 卡状态(Card Status):卡状态信息 |
4. SD卡模式
- SD卡的操作模式:
SD卡模式(SDIO)
、SPI模式(默认为SD模式)
其中SD卡模式的信号线有:CLK、CMD、DAT0-DAT3,6根线。
SPI模式的信号线有:CS、CLK、MISO(DATAOUT)、MOSI(DATAIN),4根线。 - SD卡的命令格式:
命令CMD0就是0,CMD16就是16,以此类推。
SPI命令格式为6字节构成,高位在前(MSB)。 - 引脚分布如下:
- SD卡的主要引脚功能
引脚 | 功能 |
---|---|
CLK | 时钟信号,每个时钟周期传输一个命令或数据位,频率可在0~25MHz之间变化,SD卡的总线管理器可以不受任何限制的自由产生0~25MHz 的频率 |
CMD | 双向命令和回复线,命令是一次主机到从卡操作的开始,命令可以是从主机到单卡寻址,也可以是到所有卡;回复是对之前命令的回答,回复可以来自单卡或所有卡 |
DAT0~3 | 数据线,数据可以从卡传向主机也可以从主机传向卡 |
5. 初始化SD卡过程
SPI操作模式下:在SD卡收到复位命令时,CS为有效电平(低电平),则SPI模式被启用,在发送CMD之前要先发送74个时钟,64个为内部供电上升时间,10个用于SD卡同步;之后才能开始CMD操作,在初始化时CLK时钟不能超过400KHz。
- 初始化与SD卡连接的硬件条件(MCU的SPI配置,IO口配置);
- 上电延时(>74个CLK);
- 复位卡(CMD0),进入IDLE状态;
- 发送CMD8,检查是否支持2.0协议;
- 根据不同协议检查SD卡(命令包括:CMD55、CMD41、CMD58和CMD1等);
- 取消片选,发多8个CLK,结束初始化
- SD卡初始化流程图:
6. SD卡读取数据
这里通过CMD17来实现,具体过程如下:
- 发送CMD17;
- 接收卡响应R1;
- 接收数据起始令牌0XFE;
- 接收数据;
- 接收2个字节的CRC,如果不使用CRC,这两个字节在读取后可以丢掉。
- 禁止片选之后,发多8个CLK.
二. 实验操作——对SD卡进行数据读取
1. 硬件准备
- SD卡
注意:VCC要接5V!!! - 硬件连接方式
stm32 | SD卡模块 |
---|---|
PA4 | SDCS |
PA5 | SCK |
PA6 | MISO |
PA7 | MOSI |
VCC | VCC |
GND | GND |
- 连接图
2. 新建工程
详细的工程文件获取链接:https://pan.baidu.com/s/1MFVI8M022kbmuOlGbAl6aw
提取码:xhc1
CubeMX相关配置
-
SPI1选择全双工模式
-
USART1选择异步模式
-
FATFS中勾选User-defined
-
时钟设置
-
生成工程
3. 代码部分
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (unsigned