使用STM32 SDIO接口实现TF卡读写
基于STM32H743芯片使用 SDIO读取 TF卡
SD卡简介
SD 卡 (Secure Digital Memory Card) 在我们生活中已经非常普遍了,控制器对 SD 卡进行读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外一种就是 SDIO 接口。SDIO 全称是安全数字输入/输出接口,多媒体卡 (MMC)、SD 卡、SD I/O 卡都有 SDIO 接口。STM32F10x 系列控制器有一个 SDIO 主机接口,它可以与 MMC 卡、SD 卡、SD I/O 卡以及 CE-ATA 设备进行数据传输。
MMC 卡可以说是 SD 卡的前身,现阶段已经用得很少。SD I/O 卡本身不是用于存储的卡,它是指利用 SDIO 传输协议的一种外设。比如 Wi-Fi Card,它主要是提供 Wi-Fi 功能,有些 Wi-Fi 模块是使用串口或者 SPI 接口进行通信的,但 Wi-Fi SDIO Card 是使用 SDIO 接口进行通信的。并且一般设计 SD I/O 卡是可以插入到 SD 的插槽。CE-ATA 是专为轻薄笔记本硬盘设计的硬盘高速通讯接口。
SD 卡的操作模式及切换
SD卡的识别模式
SD 卡系统 (包括主机和 SD 卡) 定义了两种操作模式:卡识别模式和数据传输模式。在系统复位后,主机处于卡识别模式,寻找总线上可用的 SDIO 设备;同时,SD 卡也处于卡识别模式,直到被主机识别到,即当 SD 卡接收到 SEND_RCA(CMD3) 命令后,SD 卡就会进入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式。在每个操作模式下,SD 卡都有几种状态,
在卡识别模式下,主机会复位所有处于“卡识别模式”的 SD 卡,确认其工作电压范围,识别 SD卡类型,并且获取 SD 卡的相对地址 (卡相对地址较短,便于寻址)。在卡识别过程中,要求 SD 卡工作在识别时钟频率 FOD 的状态下。
数据传输模式
只有 SD 卡系统处于数据传输模式下才可以进行数据读写操作。数据传输模式下可以将主机 SD时钟频率设置为 FPP,默认最高为 25MHz,频率切换可以通过 CMD4 命令来实现。
CMD7 用来选定和取消指定的卡,卡在待机状态下还不能进行数据通信,因为总线上可能有多个卡都是出于待机状态,必须选择一个 RCA 地址目标卡使其进入传输状态才可以进行数据通信。同时通过 CMD7 命令也可以让已经被选择的目标卡返回到待机状态。数据传输模式下的数据通信都是主机和目标卡之间通过寻址命令点对点进行的。卡处于传输状态下可以使用表 35‑2 中面向块的读写以及擦除命令对卡进行数据读写、擦除。CMD12 可以中断正在进行的数据通信,让卡返回到传输状态。CMD0 和 CMD15 会中止任何数据编程操作,返回卡识别模式,这可能导致卡数据被损坏。
Cubemx配置
配置SDMMC1为SD 4 bits模式
代码分析
void SD_Test_Task(void)
{
// HAL_SD_WideBusOperation_Config(&hsd, SDIO_BUS_WIDE_4B);
HAL_StatusTypeDef status;
status = HAL_SD_Init(&hsd1);
if(status != HAL_OK)
{
usb_printf("SD card initialize failed!\n");
while(1)
{
HAL_Delay(1000);
usb_printf("SD card initialize failed!\n"); /*使用了USB的串口输出功能*/
}
}
while(1)
{
HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&hsd1);
if(state == HAL_SD_CARD_TRANSFER)
{
HAL_SD_GetCardCID(&hsd1, &SD_CardCID);
usb_printf("\nInitialize SD card sucessfully!\n");
usb_printf("SD card information\n");
usb_printf("Capacity :%llu\n", ((unsigned long long)hsd1.SdCard.BlockSize*hsd1.SdCard.BlockNbr));
usb_printf("BlockSize :%d\n", hsd1.SdCard.BlockSize);
usb_printf("RCA :%d\n", hsd1.SdCard.RelCardAdd);
usb_printf("CardType :%d\n", hsd1.SdCard.CardType);
usb_printf("ManufacturerID :%d\n", SD_CardCID.ManufacturerID);
}
else
{
usb_printf("SD card initialize failed.\n");
}
HAL_Delay(1000);
}
}
实验结果
作者:cat_milk