首页 > 其他分享 >STM32CubeMx之SD卡驱动

STM32CubeMx之SD卡驱动

时间:2022-12-01 12:34:53浏览次数:49  
标签:CODE hsd STM32CubeMx SDIO Init USER 驱动 SD

STM32CubeMx之SD卡驱动

1.SD卡简介

    SD存储卡(Secure Digital Memory Card)是一种基于半导体快闪存储器的新一代高速存储设备。SD存储卡的技术是从MMC卡(MultiMedia Card)格式上发展而来,在兼容SD存储卡基础上发展了SDIO(SD Input/ Output)卡,此兼容性包括机械,电子,电力,信号和软件,通常将SD、SDIO卡俗称SD存储卡。

      SD卡具有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性,它被广泛地应用于便携式装置上,例如数码相机、平板电脑和多媒体播放器等。

     SD卡支持两种总线方式:SD方式与SPI方式。其中SD方式采用 6 线制,使用CLK、CMD、DAT0~DAT3进行数据通信。而SPI方式采用4线制,使用CS、CLK、DataIn、DataOut 进行数据通信。

      SD 方式时的数据传输速度与SPI方式要快,STM32F103ZE自带SDIO接口驱动,4位模式最高速度可达24MHZ,8位总线模式下可达48MHZ,本章节将介绍如何使用HAL库完成对SD卡驱动。

STM32CubeMx之SD卡驱动_sd卡

2.SDIO简介

  SD/SDIO MMC卡主机模块(SDIO)在AHB外设总线和多媒体卡(MMC)、 SD存储卡、 SDIO卡和CE-ATA设备间提供了操作接口。

  • SDIO的主要功能如下:
  1. 与多媒体卡系统规格书版本4.2全兼容。支持三种不同的数据总线模式:1位(默认)、 4位和8位。
  2. 与较早的多媒体卡系统规格版本全兼容(向前兼容)。
  3. 与较早的多媒体卡系统规格版本全兼容(向前兼容)。
  4. 与SD存储卡规格版本2.0全兼容。
  5. 与SD I/O卡规格版本2.0全兼容,支持良种不同的数据总线模式:1位(默认)和4位。
  6. 完全支持CE-ATA功能(与CE-ATA数字协议版本1.1 全兼容)。
  7. 8位总线模式下数据传输速率可达48MHz

2.1SDIO总线拓扑

      总线上的通信是通过传送命令和数据实现。
      在多媒体卡/SD/SD  I/O总线上的基本操作是命令/响应结构,这样的总线操作在命令或总线机制下实现信息交换;另外,某些操作还具有数据令牌。
      在SD/SDIO存储器卡上传送的数据是以数据块的形式传输;在MMC上传送的数据是以数据块或数据流的形式传输;在CE-ATA设备上传送的数据也是以数据块的形式传输。

  • ​SDIO“无响应”和“无数据”操作

STM32CubeMx之SD卡驱动_HAL库_02

  • SDIO(多)数据块读操作

STM32CubeMx之SD卡驱动_SDIO驱动_03

  • SDIO(多)数据块写操作

STM32CubeMx之SD卡驱动_SDIO驱动_04

  • SDIO(多)数据块写操作

STM32CubeMx之SD卡驱动_sd卡_05

注意:当有Busy(繁忙)信号时, SDIO(SDIO_D0被拉低)将不会发送任何数据。

  • SDIO连续读操作

STM32CubeMx之SD卡驱动_SDIO驱动_06

  • SDIO连续写操作

STM32CubeMx之SD卡驱动_SDIO驱动_07

2.2 SDIO功能描述

SDIO包含2个部分:

    ● SDIO适配器模块:实现所有MMC/SD/SDIO卡的相关功能,如时钟的产生、命令和数据的传送。
    ● AHB总线接口:操作SDIO适配器模块中的寄存器,并产生中断和DMA请求信号。

  • SDIO框图

STM32CubeMx之SD卡驱动_SDIO驱动_08

      复位后默认情况下SDIO_D0用于数据传输。初始化后主机可以改变数据总线的宽度。

      如果一个多媒体卡接到了总线上,则SDIO_D0、 SDIO_D[3:0]或SDIO_D[7:0]可以用于数据传输。 MMC版本V3.31 和之前版本的协议只支持1 位数据线,所以只能用SDIO_D0。

      如 果 一 个 SD 或 SDIO 卡 接 到 了 总 线 上 , 可 以 通 过 主 机 配 置 数 据 传 输 使 用 SDIO_D0 或SDIO_D[3:0]。所有的数据线都工作在推挽模式。

      SDIO_CMD有两种操作模式:

      ● 用于初始化时的开路模式(仅用于MMC版本V3.31 或之前版本)。

      ● 用于命令传输的推挽模式(SD/SD I/O卡和MMC V4.2在初始化时也使用推挽驱动)。

      SDIO_CK是卡的时钟:每个时钟周期在命令和数据线上传输1 位命令或数据。对于多媒体卡V3.31 协议,时钟频率可以在0MHz至20MHz间变化;对于多媒体卡V4.0/4.2协议,时钟频率可以在0MHz至48MHz间变化;对于SD或SDIO卡,时钟频率可以在0MHz至25MHz间变化。

SDIO使用两个时钟信号:

      ● SDIO适配器时钟(SDIOCLK=HCLK)
      ● AHB总线时钟(HCLK/2)

引脚定义:

引脚

定义

说明

SDIO_CK

输出

多媒体卡/SD/SDIO卡时钟。这是从主机至卡的时钟线。

SDIO_CMD

双向

多媒体卡/SD/SDIO卡命令。这是双向的命令/响应信号线。

SDIO_D[0:7]

双向

多媒体卡/SD/SDIO卡数据。这些是双向的数据总线。

2.3 SDIO适配器

STM32CubeMx之SD卡驱动_SDIO驱动_09

      SDIO适配器是多媒体/加密数字存储卡总线的主设备(主机),用于连接一组多媒体卡或加密数字存储卡,它包含以下5个部分:

    ● 适配器寄存器模块
    ● 控制单元
    ● 命令通道
    ● 数据通道
    ● 数据FIFO
注意:适配器寄存器和FIFO使用AHB总线一侧的时钟(HCLK/2),控制单元、命令通道和数据通道使用SDIO适配器一侧的时钟(SDIOCLK)

关于SDIO详细介绍请参考STM32中文手册。

3.SD硬件接口

STM32CubeMx之SD卡驱动_sd卡_10

引脚

SDIO

SPI

SDIO_D2(PC10)

数据线


SDIO_D3(PC11)

数据线

SPI_CS 片选

SDIO_CMD(PD2)

控制线

SPI_MOSI主机输出

SDIO_SCK(PC12)

时钟

SPI_SCK时钟线

SDIO_D0(PC8)

数据线

SPI_MISO主机输入

SDIO_D1(PC9)  

数据线


4 软件设置

  1.芯片选择

STM32CubeMx之SD卡驱动_SDIO驱动_11

 2.时钟配置

STM32CubeMx之SD卡驱动_HAL库_12

STM32CubeMx之SD卡驱动_SDIO驱动_13

 3.SDIO配置

STM32CubeMx之SD卡驱动_HAL库_14

5 代码生成

  1.SD初始化

  相关配置可参考STM32中文参考手册_V1.0第20.9.2时钟控制寄存器SDIO_CLKCR。

STM32CubeMx之SD卡驱动_SDIO驱动_15

void MX_SDIO_SD_Init(void)
{

/* USER CODE BEGIN SDIO_Init 0 */

/* USER CODE END SDIO_Init 0 */

/* USER CODE BEGIN SDIO_Init 1 */

/* USER CODE END SDIO_Init 1 */
hsd.Instance = SDIO;
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;//在主时钟SDIOCLK的上升沿产生SDIO_CK
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;//盘路时钟失能
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;//始终输出SDIO_CK
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;//总线宽度
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;//关闭硬件流控制
//当SD/SDIO卡或多媒体卡在识别模式, SDIO_CK的频率必须低于400kHz。
hsd.Init.ClockDiv = 6;//时钟分频系数,SDIO_CK=HCLK/(ClockDiv+2)
if (HAL_SD_Init(&hsd) != HAL_OK)//SD初始化
{
Error_Handler();
}
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)//配置总线宽度
{
Error_Handler();
}
/* USER CODE BEGIN SDIO_Init 2 */
hsd.Init.ClockDiv=0;//重新设置时钟速度
/* USER CODE END SDIO_Init 2 */

}

  2.SD读写扇区函数

 为了方便后续FATFS文件系统移植,我们这里封装两个函数SD卡写扇区和读扇区。

void SD_WriteDisk(uint8_t *buf,uint32_t sector_add,uint32_t cnt)
{
HAL_SD_WriteBlocks(&hsd,buf,sector_add,cnt,5000);//SD卡写块
while(HAL_SD_GetCardState(&hsd)!=HAL_SD_CARD_TRANSFER);//等待数据传输完成

}
void SD_ReadDisk(uint8_t *buf,uint32_t sector_add,uint32_t cnt)
{
HAL_SD_ReadBlocks(&hsd,buf,sector_add,cnt,5000);//SD卡读块
while(HAL_SD_GetCardState(&hsd)!=HAL_SD_CARD_TRANSFER);//等待数据传输完成
}

  3.主函数

      初始化HAL库、GPIO端口、LCD屏(FSMC驱动)、SD卡初始化;获取卡类型、卡容量,最后调用SD卡读写扇区函数实现数据读写测试。

int main(void)
{
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_FSMC_Init();
MX_SDIO_SD_Init();
MX_USART1_UART_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
char buff[200];
NT35310_Init();//LCD初始化
LCD_Display_Str(LCD_WIDTH/2-strlen("SD卡初始化")/2*8,20,16,(u8 *)"SD卡初始化",BLACK);
if(hsd.State!=HAL_SD_STATE_READY)
{
LCD_Display_Str(20,40,16,(u8 *)"SD Init ERR",RED);
}
else
{
LCD_Display_Str(20,40,16,(u8 *)"SD Init OK",RED);
LCD_Display_Str(20,60,16,(u8 *)"卡类型:",RED);
if(hsd.SdCard.CardType==CARD_SDHC_SDXC)//2.0告诉卡
{
LCD_Display_Str(20+8+strlen("卡类型:")*8,60,16,(u8 *)"SDHC",RED);
}
else if(hsd.SdCard.CardType==CARD_SDSC)//2.0普通卡
{
LCD_Display_Str(20+8+strlen("卡类型:")*8,60,16,(u8 *)"SDSC",RED);
}
snprintf(buff,sizeof(buff),"块大小: %d byte\n",hsd.SdCard.BlockSize);
LCD_Display_Str(20,80,16,(u8 *)buff,RED);
snprintf(buff,sizeof(buff),"卡容量大小: %.2f GB\n",(hsd.SdCard.BlockNbr>>11)/1024.0);
LCD_Display_Str(20,100,16,(u8 *)buff,RED);
}
LCD_Display_Str(LCD_WIDTH/2-strlen("SD数据读写测试")/2*8,130,16,(u8 *)"SD数据读写测试",BLACK);
SD_WriteDisk(buf_tx,100,2);
LCD_Display_Str(20,150,16,(u8 *)"SD写数据: OK",RED);
SD_ReadDisk(buf_rx,100,3);
LCD_Display_Str(20,170,16,(u8 *)"SD读数据: OK",RED);
LCD_Display_Str(20,190,16,(u8 *)"数据内容:",RED);
LCD_Display_Str(20,210,16,(u8 *)buf_rx,BLUE);
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

4.运行效果

STM32CubeMx之SD卡驱动_HAL库_16




























标签:CODE,hsd,STM32CubeMx,SDIO,Init,USER,驱动,SD
From: https://blog.51cto.com/u_15688123/5897417

相关文章

  • lsmod (option相关驱动)
    option                27680 0ppp_async              8112 0ppp_generic           24594 3pppoepppoe     ......
  • MobPush 厂商通道SDK集成指南
    开发工具:AndroidStudio集成方式:Gradle在线集成安卓版本支持:minSdkVersion19集成准备MobPush快速集成在使用厂商通道之前,请确保您已申请MobTech开发者账号并已按照​​MobP......
  • 视频美颜SDK的AI磨皮功能是怎么实现的?
    在上篇中,小编讲到了美颜SDK的AI美颜算法与传统美颜算法的区别,大家反响强烈。今天,小编为继续为大家讲解AI美颜相关的功能——AI磨皮。传统的磨皮功能大家应该比较熟悉,因为技......
  • 升级黑苹果EFI内OpenCore和驱动等
    之前给我电脑适配过​​黑苹果​​​​EFI​​​,是在前辈放弃的项目上适配的,我测试使用的时候各种bug,经过我的修复接近完美,但是由于wifi网速慢一直没用,今天看到itlwm更新......
  • 优恩鉴于对ESD管(静电二极管)与TVS管的异同分析文
    ESD静电二极管,简称ESD管;称瞬态抑制二极管,简称TVS管。上诉所提到的两种器件目前都是行业内较为热销的电子防护元件产品,两者在外形上极为相似,因此,常常被人混为一谈,也出现了很......
  • 升级黑苹果EFI内OpenCore和驱动等
    之前给我电脑适配过黑苹果EFI,是在前辈放弃的项目上适配的,我测试使用的时候各种bug,经过我的修复接近完美,但是由于wifi网速慢一直没用,今天看到itlwm更新日志里面有对我电......
  • [15-445]Join Algorithms memo (Join 为什么要用小表做驱动表)
    NestedLoopJoin这一章节主要讲解join的算法,我想记录一些重点的地方。有趣的是关于NestedLoopjoin对驱动表为什么小表会更好这个问题,搜遍简中的blog都是一些错......
  • 企业运维强驱动
    说起云服务器,很多企业都感觉像找到了航行中的舵手,但随之而来的,也有诸多问题:企业在面对庞大的服务器集群,应该怎样选择云服务器呢?为什么在使用云服务器之后,就能保证运维工作提......
  • SDL播放视频数据
    //代码来源:原文链接:https://blog.csdn.net/weixin_49406295/article/details/121569759//Created2022/11/29.//#include<iostream>#include<stdio.h>#include......
  • 3-4 计算长方形的周长和面积 sdut-oj
    #include<iostream>usingnamespacestd;classRect{ private:  doublelen,width; public:  Rect(doublea=0,doubleb=0);  Rect(constRect&r);  voi......