资讯详情

STM32外设SDIO和SD卡的配置

01 SD Card简介

SD卡(SD Card,Secure Digital Memory Card),它是一种安全数码卡。现在它已经被使用了。TF卡(MicroSD)取代。TF该卡已成为数字、存储等便携设备中应用最广泛的新型快闪存储卡。SD卡和TF卡有不同的容量标准和速度等级。

在这里插入图片描述

容量标准

SD卡和TF卡的容量标准如下表所示。

SD MicroSD 最大至2GB FAT12、FAT16
SDHC microSDHC 2GB至32GB FAT32
SDXC microSDXC 32GB至2TB exFAT
SDUC microSDXC 2TB至128TB exFAT

速度等级

速度等级如下表所示。

SD卡的结构

SD卡的结构组成包括接口、电源检测、接口控制器和接口驱动器。

  • 存储单元

存储单元通过存储单元接口和卡控制单元传输数据口和卡控制单元传输数据;

  • 电源检测单元

保证SD如果卡在适当的电压下工作,如果有电源故障或异常状态,它将重置控制单元和存储单元的接口;

  • 卡及接口控制单元

控制SD卡的运行状态包括几个特殊的寄存器;

  • 接口驱动器

控制SD卡引脚的输入和输出。

PIN脚定义

标准SD卡有九个外部触点,SD模式和SPI引脚定义在模式下不同。

  • DAT线和CMD线路需要连接拉电阻。
  • CD线在power up后能够作为SD卡检测端口或模式SPI模型的片选端。
  • RESERVED引脚还需要外部电阻,以避免浮空输入导致功耗增加。

SD Mode
1 CD/DAT3 Card detect / Data line[bit3]
2 CMD Command/Response
3 VSS1 Supply voltage ground
4 VDD Supply voltage
5 CLK Clock
6 VSS2 Supply voltage ground
7 DAT0 Data line[bit0]
8 DAT1 Data line[bit1]
9 DAT2 Data line[bit2]
SPI Mode
1 CS Chip Select(active low)
2 DataIn(MOSI) Host-to-card Commands and Data
3 VSS1 Supply voltage ground
4 VDD Supply voltage
5 CLK Clock
6 VSS2 Supply voltage ground
7 DataOut(MISO) Card-to-host Data an Status
8 RSV Reserved
9 RSV Reserved

存储单元

读写SD卡数据的基本单位是1 byte,所有数据都是以block的形式来传输的。SDHC标准卡的数据块长度为512 bytes。每个sector扇区的block大小是固定的,定义在CSD寄存器中。

block长度可以通过CSD寄存器自定义

SD卡的寄存器

CID 128 卡标识号
RCA 16 卡相对地址,在初始化的时候确定
CSD 128 卡描述数据,卡操作条件的信息
SCR 64 SD卡配置寄存器,SD卡的特殊信息
OCR 32 操作条件寄存器
SSR 512 SD卡状态寄存器
CSR 32 卡状态寄存器

OCR

Operation Conditions Register (OCR),操作条件寄存器,存储着SD卡的VDD电压配置文件,寄存器结构如下。

CID

Card Identification Register (CID),卡标识寄存器,长度共16字节,包含唯一的卡识别码。寄存器结构如下图所示。

CSD

Card Specific Data (CSD) Register,卡描述数据寄存器,用于获取SD卡的信息。具体结构大家可以查看官方手册。

RCA

Relative Card Address (RCA),卡相对地址寄存器,此地址用于卡识别程序后寻址的主机卡通信。

此外还有SSR和CSR等,而SPI模式下的寄存器基本一致,有些微小区别,具体可以查看官方手册。

SD总线

根据PIN脚定义可知,SD卡的MMC(MultiMediaCard)总线包括下图中的信号。

  • SD卡主从两个方向的传输都只以CLK 的上升沿有效。
  • SD卡的整个操作过程中会使用到两种不同频率的时钟来同步数据,一个是卡识别阶段的时钟频率FOD,最高为400kHz。另外一个是数据传输模式下的时钟频率FPP,默认最高为25MHz。如果通过相关寄存器配置使SD总线工作在高速模式,则最高频率可达到50MHz。

特点

1.通电后,默认情况下,SD卡只使用DAT0进行数据的传输 2.完成初始化后,SD总线允许动态配置数据线的数量

SPI总线

和普通SPI总线一样,带有SCK、CS、MOSI和MISO四个信号。SPI的相关SD配置,这里不展开,具体可以查看官方手册。

SD总线协议

SD 总线上的通信是基于命令和数据传输的。通信过程由一个起始位(“0”)启动,而由一个停止位(“1”) 终止。

SD总线的基本交互过程是命令和响应的交互,一般是主机向从机发送一个命令(Command),从设备在接收到命令后作出响应(Response),如果有数据的传递需求,则会有数据(Data)的传输参与到整个通信过程中。

命令格式

SD 命令格式固定为48bit,都是通过CMD 线连续传输的。

47 46 [45 : 40] [39 : 8] [7 : 1] 0
1 1 6 32 7 1
‘0’ ‘1’ x x x ‘1’
Start bit Transmission bit Command index Argument CRC7 End bit

命令类型

命令类型共有四种,分别是:

1.Broadcast(bc),无响应广播命令,发送到,不返回任务响应;

2.Broadcast w/Response(bcr),带响应广播命令,发送到,同时接收来自所有卡响应;

3.Addressed point-to-point(ac),寻址命令,发送到,DAT 线无数据传输;

4.Addressed point-to-point data transfer(adtc),寻址数据传输命令,发送到,DAT 线有数据传输。

另外还有两种通用命令,特定应用命令(ACMD) 和常规命令(GEN_CMD)。其中ACMD命令发送前,需要先发送CMD55 命令。

基本命令(Class 0)
CMD0 bc [31:0] stuff bits GO_IDLE_STATE 复位所有卡到idle状态
CMD2 bcr [31:0] stuff bits R2 ALL_SEND_CID 要求所有卡通过CMD返回CID值
CMD4 bcr [31:0] stuff bits R6 SEND_RELATIVE_ADDR 编程所有卡的DSR
CMD7 ac [31:16] RCA [15:0] don’t care R1b SELECT/DESELECT_CARD 选中/取消选中RCA地址对应的卡
CMD8 bcr [31:12] RSV [7:0] VHS R7 SEND_IF_COND 发送卡接口条件,包括主机支持的电压等信息,并询问卡支持与否
CMD9 ac [31:16] RCA [15:0] stuff bits R2 SEND_CSD 通过CMD发送CSD内容到选定卡
CMD10 ac [31:16] RCA [15:0] stuff bits R2 SEND_CID 通过CMD发送CID内容到选定卡
CMD12 ac [31:0] stuff bits R1b STOP_TRANSMISSION 强制停止卡传输
CMD13 ac [31:16] RCA [15:0] stuff bits R1 SEND_STATUS 通过CMD发送选定卡的状态寄存器
CMD15 ac [31:16] RCA [15:0] stuff bits GO_INACTIVE_STATE 使选定卡进入"inactive"状态
block读命令(Class 2)
CMD16 ac [31:0] 块长度 R1 SET_BLOCK_LEN 可设置标准SD卡的块长度,SDHC标准的SD卡命令长度固定为512bytes
CMD17 adtc [31:0] 数据地址 R1 READ_SINGLE_BLOCK 读取标准卡SEL_BLOCK_LEN的长度字节块,SDHC标准的SD卡固定读取512字节的block
CMD18 adtc [31:0] 数据地址 R1 READ_MULTIPLE_BLOCK 连续从SD卡读取数据block,直到被CMD12中断。其中块的长度和CMD17的相同
block写命令(Class 4)
CMD24 adtc [31:0] 数据地址 R1 WRITE_BLOCK 写入标准卡SEL_BLOCK_LEN的长度字节块,SDHC标准的SD卡固定读取512字节的block
CMD25 adtc [31:0] 数据地址 R1 WRITE_MULTIPLE_BLOCK 连续向SD卡写入数据block,直到被CMD12中断。其中块的长度和CMD17的相同
CMD27 adtc [31:0] stuff bits R1 PROGRAM_CSD 对CSD的可编程位进行编程
擦除命令(Class 5)
CMD32 ac [31:0] 数据地址 R1 ERASE_WR_BLK_START 设置擦除的起始块地址
CMD33 ac [31:0] 数据地址 R1 ERASE_WR_BLK_END 设置擦除的结束块地址
CMD38 ac [31:0] stuff bits R1b ERASE 擦除预先选定的块
卡命令(Class 7)
CMD32 adtc [31:0] stuff bits R1 LOCK_UNLOCK 加锁/解锁 SD卡
特定应用命令(Class 8)
CMD55 ac [31:16] RCA [15:0] stuff bits R1 APP_CMD 指定下个命令为特定应用命令,不是标准命令
CMD56 adtc [31:1] stuff bits [0] RD/WR R1 GEN_CMD 在通用命令或特定应用命令中,用于传输一个数据块。最低位用于表示读数据或写数据
SD卡特定应用命令
ACMD6 ac [31:2] stuff bits [1:0] Bus width R1 SET_BUS_WIDTH 定义数据总线宽度 (‘00’ = 1bit,‘10’ = 4bits)
ACMD13 adtc [31:0] stuff bits R1 SD_STATUS 发送SD状态
ACMD41 bcr [31:0] OCR R3 SD_SEND_OP_COND 要求卡发送它所支持的信息(HCS)和OCR寄存器内容
ACMD51 adtc [31:0] stuff bits R1 SEND_SCR 读取配置寄存器SCR

响应

响应由SD 卡通过CMD线向主机发出,有些命令要求响应,有些不要求,SDIO 总线共有7 种响应类型(R1 ~ R7)。

SD 卡不支持R4和R5 类型的响应

R1标准响应

如果有传输到卡的信号,那么在数据线上可能有busy的信号(R1b)出现

47 46 [45 : 40] [39 : 8] [7 : 1] 0
1 1 6 32 7 1
‘0’ ‘0’ x x x ‘1’
Start bit Transmission bit Command index Card status CRC7 End bit
R2 CID,CSD寄存器响应

CID寄存器的值是CMD2和CMD10命令的响应,而CSD寄存器内容是CMD9命令的响应

135 134 [133 : 128] [127 : 1] 0
1 1 6 127 1
‘0’ ‘0’ ‘111111’ x ‘1’
Start bit Transmission bit Reserved CID or CSD寄存器的值 End bit
R3 OCR寄存器响应

OCR寄存器的值是ACMD41命令的响应

47 46 [45 : 40] [39 : 8] [7 : 1] 0
1 1 6 32 7 1
‘0’ ‘0’ ‘111111’ x ‘111111’ ‘1’
Start bit Transmission bit Reserved OCR Register Reserved End bit
R6 发布的RCA寄存器响应

专用于CMD3的响应

R7 发布的RCA寄存器响应

专用于CMD8命令的响应,返回卡所支持的电压范围和检测模式

47 46 [45 : 40] [39 : 20] [19 : 16] [15 : 8] [7 : 1]
1 1 6 20 4 8 7
‘0’ ‘0’ ‘001000’ ‘00000h’ x x x
Start bit Transmission bit CMD8 Reserved Rev Voltage Check Mode CRC7

数据包

使用所有wide bus时,每一次数据传输4个bit,每条线路的CRC是独立计算和校验的。SD卡只在DAT0线路上向主机发送CRC状态响应和Standard busy信号。下图中CMD53命令和ACMD13命令的两个数据包传输例子。

卡状态类型和操作模式

卡识别模式

在该模式下,主机会对所有处于“卡识别模式”的SD 卡进行复位操作,然后确认其工作电压范围,识别SD卡类型,并且获取SD 卡的相对地址(RCA)。下图是该模式下的SD卡状态转换图。

1.主机也可以发送 CMD0让所有卡软复位进入空闲状态,但当前处于Inactive State的卡不会复位 2.主机在与卡开始通信前,需要先确认双方在互相支持的电压范围内。SD 卡内的寄存器有一个电压支持范围,主机当前的电压必须在该范围内才能与卡正常通信,CMD8可以用于该操作。 3.ACMD41命令可以识别或拒绝不匹配主机电压范围的SD卡 4.CMD2命令要求所有卡返回CID 5.CMD3命令是让卡推荐一个RCA,RCA是16bit的地址,相对于使用CID(128bit)进行通信会更简化

数据传输模式

SD 卡系统处于数据传输模式下,主机才可以对其进行数据读写。数据传输模式下可以将主机SD

时钟频率设置为FPP,默认最高为25MHz。

1.数据传输模式下,主机和目标卡通信都是通过RCA来点对点通信的 2.CMD7命令用来选中和取消选中卡

02 STM32的SDIO接口

以下内容以STM32F407xx为例。

SDIO的结构

STM32的SDIO由SDIO适配器和APB2接口组成。其中,SDIO适配器提供主机功能,包括SD时钟、发送命令和数据传输等。而APB2接口用于控制SDIO适配器的寄存器,并可产生中断和DMA请求。

SDIO的时钟

SDIOCLK

是SDIO适配器的时钟,频率为48MHz。

PCLK2

是APB2总线的时钟。

SDIO_CK

是SDIO接口与SD卡同步的时钟,时钟源是SDIOCLK = 48MHz。当使能BYPASS模式时,SDIO_CK = SDIOCLK = HCLK。而禁止BYPASS时,SDIO_CK = SDIOCLK / (2 + CLKDIV)。

注意 1.配置时钟时,要留意不能超过25MHz 2.PCLK >= (3 / 8) x SDIO_CK

SDIO适配器

SDIO 适配器是SD卡系统中的主机端。共由五个单元组成,分别是:

  • 控制单元
  • 适配器寄存器单元
  • 命令路径单元
  • 数据路径单元
  • 数据FIFO

1.适配器寄存器和 FIFO 使用 APB2 总线时钟域 (PCLK2) 2.控制单元、命令路径和数据路径使用 SDIO 适配器时钟域 (SDIOCLK)

控制单元

控制单元由电源管理子单元和时钟管理子单元组成。电源管理子单元会在断电阶段和上电阶段中禁止卡总线输出信号。而时钟管理子单元负责生成和控制 SDIO_CK 信号。

命令路径

命令路径单元向卡发送命令并从卡接收响应。而命令的格式可以看上述“”章节。

命令路径以半双工模式运行,因此CMD线可以发送或者接收命令和响应

命令路径状态机

当发送命令和接收响应时,会启动CPSM状态机。

命令超时为64个SDIO_CK 时钟周期的固定值

响应

SDIO 支持两种响应类型,以适配SD卡的响应。两种类型均使用 CRC 错误校验。包括:

  • 136位长响应
  • 48位短响应

响应的格式可以看上述“”章节。

数据路径

数据路径子单元负责主机与卡相互传输数据。如果使能了 4 位宽度的总线模式,则 使用所有四个数据信号线 (SDIO_D[3:0]) 在每个时钟周期内传输 4 个数据位,8位宽度则是8个数据位。数据包的格式可以看上述“”章节。

未使能宽总线模式时,则每个时钟周期使用 SDIO_D0传输一位数据位

数据路径状态机

DPSM 以 SDIO_CK 的频率运行,卡总线信号上的数据与 SDIO_CK 的上升沿保持同步。

数据FIFO

数据 FIFO子单元是一个数据缓冲器,带有发送和接收单元。传输 FIFO和接收FIFO是互斥关系的。传输或接收的标志可以触发中断或DMA请求。

数据 FIFO是在 APB2 时钟域 (PCLK2) 中运行的,所以来自 SDIO 时钟域 (SDIOCLK) 子单元中的所有信号都将要重新同步

03 SD卡的配置和应用

SD卡热插拔检测

SD卡的热插拔可以通过CD/DAT3信号脚来检测,实现的步骤如下。

1.将CD/DAT3 信号连在MCU中断引脚上,并通过510K电阻下拉,而MCU配置为高电平触发中断;

2.在没有SD卡插入时,该信号为低电平,一但有SD卡插入,SD卡内部通过50KΩ把 DATA3 信号拉高至高电平,MCU随即产生一个中断,再在中断服务函数里写处理逻辑,从而实现热插拔的功能。

SD卡的初始化

SD卡的初始化一般分为“SDIO初始化”、“上电”、“获取卡信息”和“设置数据传输模式”四个过程。具体过程可以查看上述“”章节。

SDIO初始化

初始化SDIO为1位总线宽度,频率不超过400KHz。

/* SDIO Initialization Frequency (400KHz max) */
#define SDIO_INIT_CLK_DIV ((uint8_t)0x76) /* 48MHz / (SDMMC_INIT_CLK_DIV + 2) < 400KHz */

SD_InitTypeDef Init;

/* Default SDIO peripheral configuration for SD card initialization */
Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
Init.BusWide             = SDIO_BUS_WIDE_1B;
Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
Init.ClockDiv            = SDIO_INIT_CLK_DIV;

/* Initialize SDIO peripheral interface with default configuration */
SDIO_Init(hsd->Instance, Init);

SD卡上电

SD卡的上电过程如下图所示。注意上电后要给74个clock,给足够长的时间SD卡准备。

/* Disable SDIO Clock */
__HAL_SD_DISABLE(hsd);

/* Set Power State to ON */
(void)SDIO_PowerState_ON(hsd->Instance);

/* Enable SDIO Clock */
__HAL_SD_ENABLE(hsd);

/* Identify card operating voltage */
errorstate = SD_PowerON(hsd);

获取卡信息

/* Card initialization */
SD_InitCard(hsd);

设置SDIO工作在数据传输模式

/* Configure SD Bus width (4 bits mode selected) */
HAL_SD_ConfigWideBusOperation(&sdHandle, SDIO_BUS_WIDE_4B);

SD卡的读写操作

普通读写

/* Read SD block*/
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
{ 
        
  uint8_t sd_state = MSD_OK;

  if (HAL_SD_ReadBlocks(&sdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) != HAL_OK)
  { 
        
    sd_state = MSD_ERROR;
  }

  return sd_state;
}

/* Write SD block*/
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
{ 
        
  uint8_t sd_state = MSD_OK;

  if (HAL_SD_WriteBlocks(&sdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) != HAL_OK)
  { 
        
    sd_state = MSD_ERROR;
  }

  return sd_state;
}

DMA读写

使用DMA读写前要先配置DMA通道,一个用于发送,另一个用于接收。

#define SDIO_DMA_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
#define SDIO_TX_DMA_CHANNEL DMA_CHANNEL_4
#define SDIO_RX_DMA_CHANNEL DMA_CHANNEL_4
#define SDIO_TX_DMA_STREAM DMA2_Stream6
#define SDIO_RX_DMA_STREAM DMA2_Stream3
#define SDIO_TX_DMA_IRQ DMA2_Stream6_IRQn
#define SDIO_RX_DMA_IRQ DMA2_Stream3_IRQn

/* SDIO_RX Init */
hdma_sdio_rx.Instance = SDIO_RX_DMA_STREAM;
hdma_sdio_rx.Init.Channel = SDIO_RX_DMA_CHANNEL;
hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
if (HAL_DMA_Init(&hdma_sdio_rx) != HAL_OK)
{ 
        
    Error_Handler();
}

__HAL_LINKDMA(hsd,hdmarx,hdma_sdio_rx);

/* SDIO_TX Init */
hdma_sdio_tx.Instance = SDIO_TX_DMA_STREAM;
hdma_sdio_tx.Init.Channel = SDIO_TX_DMA_CHANNEL;
hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
if (HAL_DMA_Init(&hdma_sdio_tx) != HAL_OK)
{ 
        
    Error_Handler();
}

__HAL_LINKDMA(hsd,hdmatx,hdma_sdio_tx);

DMA读写

/* Read SD block*/
uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
{ 
        
  uint8_t sd_state = MSD_OK;

  /* Read block(s) in DMA transfer mode */
  if (HAL_SD_ReadBlocks_DMA(&sdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks) != HAL_OK)
  { 
        
    sd_state = MSD_ERROR;
  }

  return sd_state;
}

/* Write SD block*/
uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
{ 
        
  uint8_t sd_state = MSD_OK;

  /* Write block(s) in DMA transfer mode */
  if (HAL_SD_WriteBlocks_DMA(&sdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks) != HAL_OK)
  { 
        
    sd_state = MSD_ERROR;
  }

  return sd_state;
}

参考文献

1.SD Card association

2.《Sandiskmanual-SecureDigital2.2》

3.《SD Specifications Part 1 Physical Layer Simplified Specification》

4.《RM0090》

标签: r5k电阻电阻hsd电阻130k能通电吗

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台