本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SDMMC外设读取SD卡数据。

1. 准备工作

硬件准备

  • 开发板
    首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi):


  • Micro SD卡
    小熊派开发板板载 Micro SD 卡槽,最大支持 32 GB,需要提前自行准备一张 Micro SD卡,如图:


2.创建Cube工程

选择芯片型号

打开STM32CubeMX,打开MCU选择器:


搜索并选中芯片STM32L431RCT6:


配置时钟源

  • 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC;

  • 如果使用默认内部时钟(HSI),这一步可以略过;

这里我都使用外部时钟:


配置串口

小熊派开发板板载ST-Link并且虚拟了一个串口,原理图如下:


这里我将开关拨到AT-MCU模式,使PC的串口与USART1之间连接。

接下来开始配置USART1


配置 SDMMC 接口

知识小卡片 —— SDMMC接口

SDMMC接口的全称叫SD/SDIO MMC card host interface,SD/SDIO MMC 卡 主机接口,通俗的来说,就是这个接口支持SD卡,支持SDIO设备,支持MMC卡。

知识小卡片结束啦~

首先查看小熊派开发板的原理图:


然后根据原理图配置 SDMMC 接口:


配置时钟树

STM32L4的最高主频到80M,所以配置PLL,最后使HCLK = 80Mhz即可:


生成工程设置


代码生成设置

最后设置生成独立的初始化文件:


生成代码

点击GENERATE CODE即可生成MDK-V5工程:


3. 在MDK中编写、编译、下载用户代码

重定向printf( )函数

参考:

  • 【STM32Cube_09】重定向printf函数到串口输出的多种方法。

读取SD卡信息并打印

SD 卡系统(包括主机和 SD 卡)定义了两种操作模式:

  • 卡识别模式

  • 数据传输模式

系统复位后,主机处于卡识别模式,寻找总线上可用的 SD卡设备;同时,SD 卡也处于卡
识别模式,直到被主机识别到。

使用STM32CubeMX初始化的工程中会自动生成 SDMMC 初始化函数,向 SD 卡发送命令,当 SD 卡接收到命令后, SD 卡就会进入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式

所以在操作之前,需要先检查 SD 卡是否处于数据传输模式并且处于数据传输状态:

main函数中首先定义一个变量用于存储 SD 卡状态:

int sdcard_status = 0;HAL_SD_CardCIDTypeDef sdcard_cid;

然后在while(1)之前编写如下读取信息代码:

/* USER CODE BEGIN 2 */printf("Micro SD Card Test...\r\n");

/* 检测SD卡是否正常(处于数据传输模式的传输状态) */sdcard_status = HAL_SD_GetCardState(&hsd1);if(sdcard_status == HAL_SD_CARD_TRANSFER){    printf("SD card init ok!\r\n\r\n");

    //打印SD卡基本信息    printf("SD card information!\r\n");    printf("CardCapacity: %llu\r\n",((unsigned long long)hsd1.SdCard.BlockSize*hsd1.SdCard.BlockNbr));    printf("CardBlockSize: %d \r\n",hsd1.SdCard.BlockSize);    printf("RCA: %d \r\n",hsd1.SdCard.RelCardAdd);    printf("CardType: %d \r\n",hsd1.SdCard.CardType);

    //读取并打印SD卡的CID信息    HAL_SD_GetCardCID(&hsd1,&sdcard_cid);    printf("ManufacturerID: %d \r\n",sdcard_cid.ManufacturerID);}else{     printf("SD card init fail!\r\n" );    return 0;}/* USER CODE END 2 */

编译下载后串口助手输出结果如下:


擦除SD卡块数据

为了验证实验的正确性或,先擦除数据:

/* 擦除SD卡块 */printf("------------------- Block Erase -------------------------------\r\n");sdcard_status = HAL_SD_Erase(&hsd1, 0, 512);if (sdcard_status == 0){    printf("Erase block ok\r\n");}else{    printf("Erase block fail\r\n");}

读取SD卡块数据

首先开辟一个全局缓冲区,用于存放从SD卡读出的数据:

/* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 */uint8_t read_buf[512];/* USER CODE END 0 */

然后在之前读取信息的代码之后添加读取数据的代码:

/* 读取未操作之前的数据 */printf("------------------- Read SD card block data Test ------------------\r\n");sdcard_status = HAL_SD_ReadBlocks(&hsd1,(uint8_t *)read_buf,0,1,0xffff);if(sdcard_status == 0){     printf("Read block data ok \r\n" );    for(i = 0; i 512; i++)    {        printf("0x%02x ", read_buf[i]);        if((i+1)%16 == 0)        {            printf("\r\n");        }    }}else{    printf("Read block data fail!\r\n " );}

向SD卡块写入数据

同样的,开辟一个全局缓冲区,用于存放即将要写入SD卡的数据:

uint8_t write_buf[512];

然后在之前读取数据的代码之后添加的代码,将缓冲区的数据赋初值:

/* 填充缓冲区数据 */for(i = 0; i 512; i++){    write_buf[i] = i % 256;}

然后继续添加代码,将该缓冲区数据写入SD卡:

/* 向SD卡块写入数据 */printf("------------------- Write SD card block data Test ------------------\r\n");sdcard_status = HAL_SD_WriteBlocks(&hsd1,(uint8_t *)write_buf,0,1,0xffff);if(sdcard_status == 0){     printf("Write block data ok \r\n" );}else{    printf("Write block data fail!\r\n " );}

添加完之后,为了检查数据是否正常写入,再将数据读出:

/* 读取操作之后的数据 */printf("------------------- Read SD card block data after Write ------------------\r\n");sdcard_status = HAL_SD_ReadBlocks(&hsd1,(uint8_t *)read_buf,0,1,0xffff);if(sdcard_status == 0){     printf("Read block data ok \r\n" );    for(i = 0; i 512; i++)    {        printf("0x%02x ", read_buf[i]);        if((i+1)%16 == 0)        {            printf("\r\n");        }    }}

将程序编译下载,最终的实验结果如下:






至此,我们已经学会如何使用硬件SDMMC接口读取SD数据。

sdio接口_单片机基础 —— 使用SDMMC接口读写SD卡数据相关推荐

  1. STM32单片机基础19——使用SDMMC接口读写SD卡数据

    本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SDMMC外设读取SD卡数据. 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32L4 ...

  2. 单片机读tf卡c语言程序,单片机读写SD卡,MMC卡,MiniSD,TF卡,MicroSD卡

    图一 一:系统构成: 1:89C51单片机(ISP 单片机,可不用编程器) 2:128x64LCD 3: 带SD ,MiniSD ,MicroSD(TFSD)卡座 送32MByte SD卡 4:支持红 ...

  3. 卡写入速度_看清商家买相机送SD卡的套路,一文教你掌握存储卡选购秘诀

    学摄影,可能并不比学一门艺术或学科更简单,它可能更难. 我的工作是摄影教学,想在短时间内让学摄影的人顺利毕业,注定需要不厌其烦的整理.疏导琐碎的摄影知识,搭建知识网络,然后研发成课程.最终复盘再优化再 ...

  4. SDIO——读写SD卡

    SDIO的设备分类: SD / IO卡:这不是一种卡,现在已经不常用了,用到时再查. SD存储卡:分局容量不同有三种名字① <= 2GB 的叫SDSC:② >2GB <= 32GB的 ...

  5. SDIO读写SD卡的速度

    SDIO(Secure Digital Input Output)是一种通用的接口,用于在计算机和其他设备之间传输数据.SD卡(Secure Digital Memory Card)是一种可移植的存储 ...

  6. 单片机读取SD卡数据解决方案

    随着电子技术的发展,SD卡作为大容量数据存储器越来越受到广大电子爱好者和客户的衷爱.但是由于SD卡FAT操作的编程复杂,很多电子爱好者望而却步,现在好了,我们推出了这块小巧玲珑的SD卡读卡模块,将复杂 ...

  7. SDIO读写SD卡速度有多快?

    前两天测试了SPI方式读写SD卡的速度<SPI方式读写SD卡速度测试>,今天来测试一下SDIO方式的读写速度. 测试条件: 单片机:STM32F407VET6 编译环境:MDK 5.30+ ...

  8. 掌握与SD卡“交流”的方法,轻松完成单片机读写SD卡的底层驱动程序

    从大二开始写代码至今已经五六年了,之前做过很多嵌入式项目,参加过很多竞赛:慢慢才发现之前很多是知其然不知其所以然,很多东西都是从CSDN,论坛,各个网站学习过来的:工作以后才发现,做出一个东西并不难, ...

  9. 显示器接口_显示器上的TypeC接口 可能绝大多数人都不知道这么大作用

    大多数的数码爱好者认识Type-C接口,估计都是从2015年的安卓手机开始的. 但估计不少用户不知道的是,电脑端的显示器上也有Type-C接口. 如果你是一个刚入门想买显示器的朋友,下面可以分别看看显 ...

最新文章

  1. 用python客户画像代码_客户画像与标签体系-Python数据科学技术详解与商业项目实战精讲 - Python学习网...
  2. 【前端】react and redux教程学习实践,浅显易懂的实践学习方法。
  3. 值传递、指针传递、引用传递的区别
  4. 1.几大开发模型区别与联系
  5. 在64位机器上无法调用迅雷的问题
  6. php数据字段多怎么存,一个保存时间的字段怎么存储数据
  7. MySQL-快速入门(1)基本数据库、表操作语句
  8. Windows 系统中 hosts 文件无法修改的问题
  9. GAN的目标函数(F散度;KL散度;JS散度;Pearson \chi^2 散度;IPM;Wasserstein距离;MMD)
  10. kali-网站克隆工具-httrack
  11. 第10章项目干系人管理__权力利益分配
  12. MTK平台 后视镜系列 声控参数调整方法
  13. C语言既有高级语言又有低级语言的特点,但为什么它不是低级语言呢?
  14. 从电影《心灵捕手》谈起
  15. 使用可道云在centos上搭建个人网盘(附带端口修改)
  16. 系统调用(Linux)
  17. Java开发自学教程!kafka配置文件参数说明
  18. cpu低端计算机配置清单,i3 4160/GTX750Ti剑灵/英雄联盟中低端组装机配置清单
  19. 空间三角形_被忽悠买下奇葩户型,三角形空间无从下手,空置一年被设计师拯救...
  20. yolov7正负样本分配详解

热门文章

  1. jquery-加入购物车动画
  2. Elasticsearch 定制评分(自定义评分)
  3. 生成器案例,#采集日志
  4. 聊聊spring-boot-starter-data-redis的配置变更
  5. 2016上半年中国云存储排行榜:阿里云居榜首
  6. 【转】c#处理3种json数据的实例
  7. Differential Geometry之第九章常平均曲率曲面
  8. InnoDB发展历史
  9. 使用Fastjson提示No serializer found for class
  10. 商品WEB开发的商品定单与存储过程的应用