STM32 SPI读取SD卡

七个响应类型:

R1 Response (Normal Response): R1响应是最基本的响应,包含一个字节的状态位,用于指示命令是否成功执行。常用。最高位为0。最低位为1表示是空闲状态。其他位是各种错误提示。

R1b Response (Normal with Busy): 类似于R1,但在命令执行完成后,卡会持续将忙位(busy)发送给主机,直到卡准备好执行下一个命令。

R2 Response (CID or CSD Register Response): 包含两个字节的数据,用于读取CID(Card ID)或CSD(Card Specific Data)寄存器内容。

R3 Response (OCR Register Response): 包含四个字节的数据,用于读取OCR(Operating Conditions Register)寄存器内容。第一个字节就是R1响应,然后是OCR寄存器。OCR中主要看CCS位(标志v2.0高容量和标准容量)和电压支持范围

R6 Response (Published RCA Response): 包含一个字节的状态位和一个字节的相对卡地址(RCA),用于获取卡的相对地址。

R7 Response (Card Interface Condition Response): 包含一个字节的状态位和一个字节的回应信息,用于卡初始化阶段。常用返回状态。命令8专属响应

Data Response (for Data Transfer Commands): 在读/写数据时,卡会响应数据响应,用于指示数据是否成功接收。

数据传输控制:

数据块传输时,存在Token控制传输。

1.数据响应Token:

一个字节,格式如下

XXX Status 1

其中Status三个bit,010数据正常接收,101 CRC校验失败。110写入错误

2.数据块开始和停止Token

单块读写多块读中数据块开头的Token是固定0xFE表示数据块开始

多块写使用0xFC开始,0xFD结束。

命令表:

 

初始化流程图:

这个流程图实际上是SDIO模式的,SPI在识别V1卡上有区别,然后并没有进入识别状态和请求RCA的过程。

 

1.上电后将SPI模式设置为低速模式要求小于400Kb/s。然后片选

2.等待至少47个CLK时间,一般发送8个无效字节即可

3.发送CMD0直至卡进入空闲状态(r1==0x01)

4.检查卡类型,发送CMD8,若有回应则是V2.0卡需进行后续判别,V1卡的识别是发送CMD8失败后,继续发送CMD55+ACMD41然后根据r1返回值小于等于1则是V1.0卡,不响应就要判断MMC和其他不受支持的卡。判断MMC卡是继续发送CMD1,如果响应是MMC卡,否则不受支持,均结束初始化。SPI模式中没有获取RCA步骤

5.如果确定是V2.0卡,为获得R3回复需再发送4个字节,第3第4字节分别为0x01和0xAA则支持2.7-3.6V。

6.再循环发送CMD55+ACMD41,直到返回0x00,进入Ready状态

7.发送CMD58,获得R1回复后再发送4字节获得OCR值(R3回复)。buff[0]&0x40就是V2HC,否则就是V2标准容量。

结束初始化。

数据传输:

SD卡单块读取流程:

发送CMD17开始读取数据块并等待R1响应,后继续等待数据起始令牌0xFE,然后接收数据,禁止片选即可完成读取。

对于标准容量卡数据块大小由CMD16设置,SDHC卡就是512字节

多块读取:

发送CMD18,等待R1响应,等待起始数据令牌0XFE,读第一块,等待数据令牌0xFE,读第二块

...

发送CMD12后等待R1

禁止片选

SD单块写入:

发CMD24,等待响应,发送数据起始令牌0xFE,写入第一数据块,检测MISO是否为低(低表示SD卡忙),MISO为高后发送两字节伪CRC 0xFF,禁止片选

多块写:

发ACMD23预擦除,发ACMD25开始写,发送起始令牌0xFC,写入第一个数据块,等待不忙了再写2字节伪CRC 0xFF,继续发起始令牌,第二块数据.....,发送结束令牌0xFD,禁止片选。

驱动代码:

//mmc_sd.h
/*
GPIO初始化要求 片选线需要推挽输出默认输出高电平,高速。片选线低电平有效
SPI选用CPOL=1,CPHA=1,全双工,256分频,Motorola模式,软件NSS,不使用CRC,禁用TI模式
*/
#ifndef __SD_H
#define __SD_H

#include "main.h"
#include "spi.h"
#include <stdio.h>
//片选线宏定义,CubeMX初始化后还需要在这里设置一下宏定义
#define SD_CS_GPIO_Port GPIOA
#define SD_CS_Pin GPIO_PIN_3

#define SD_SPI hspi1

extern uint8_t SD_TYPE;

//SD卡类型
#define ERR     	0x00
#define MMC				0x01
#define V1				0x02
#define V2				0x04
#define V2HC			0x06

#define DUMMY_BYTE				 0xFF 
#define MSD_BLOCKSIZE			 512


//CMD定义
#define CMD0    0       //卡复位
#define CMD1    1
#define CMD8    8       //命令8 ,SEND_IF_COND
#define CMD9    9       //命令9 ,读CSD数据
#define CMD10   10      //命令10,读CID数据
#define CMD12   12      //命令12,停止数据传输
#define CMD16   16      //命令16,设置SectorSize 应返回0x00
#define CMD17   17      //命令17,读sector
#define CMD18   18      //命令18,读Multi sector
#define CMD23   23      //命令23,设置多sector写入前预先擦除N个block
#define CMD24   24      //命令24,写sector
#define CMD25   25      //命令25,写Multi sector
#define CMD41   41      //命令41,应返回0x00
#define CMD55   55      //命令55,应返回0x01
#define CMD58   58      //命令58,读OCR信息
#define CMD59   59      //命令59,使能/禁止CRC,应返回0x00

//数据写入回应字意义
#define MSD_DATA_OK                0x05
#define MSD_DATA_CRC_ERROR         0x0B
#define MSD_DATA_WRITE_ERROR       0x0D
#define MSD_DATA_OTHER_ERROR       0xFF
//SD卡回应标记字
#define MSD_RESPONSE_NO_ERROR      0x00
#define MSD_IN_IDLE_STATE          0x01
#define MSD_ERASE_RESET            0x02
#define MSD_ILLEGAL_COMMAND        0x04
#define MSD_COM_CRC_ERROR          0x08
#define MSD_ERASE_SEQUENCE_ERROR   0x10
#define MSD_ADDRESS_ERROR          0x20
#define MSD_PARA
要使用STM32SPI读取SD,可以按照以下步骤操作: 1. 配置SPI接口:首先,需要根据SD的通信协议,配置STM32SPI接口,包括时钟速率、数据位宽、模式等参数。可以通过寄存器设置或使用相关库函数来完成此步骤。 2. 初始化SD:在开始读取之前,需要将SD初始化为工作状态。这包括发送命令给SD,规定其工作电压和其他初始化参数,并等待SD准备好。 3. 发送命令:使用SPI接口向SD发送读取命令。这包括发送命令码和附加的命令参数。可以使用SPI的发送函数来实现此步骤。 4. 接收数据:为了接收从SD读取的数据,可通过SPI接口接收数据。可以使用SPI的接收函数来实现此操作。一般情况下,数据可以通过DMA方式直接存储到指定的内存区域,以提高读取速度。 5. 处理数据:读取到的数据可能需要进行处理,例如解码图片或读取文件等。这取决于您的具体应用,可以使用相关库函数或自定义代码来实现相应的数据处理。 6. 关闭SD:在读取完成后,可发送关闭命令给SD,使其进入待机状态。这可以通过SPI接口发送相应的命令码来实现。 需要注意的是,以上步骤只是一个基本的框架,具体的实现可能会因SD型号、应用需求等而有所不同。在实际应用中,还需要处理错误、处理文件系统等问题,以确保SD的正常读取
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值