STM32L4单片机基础——使用SDMMC接口读写SD卡

NB的老王 发表于 2019/12/13 17:20:54 2019/12/13
【摘要】 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SDMMC外设读取SD卡数据。1. 准备工作硬件准备开发板首先需要准备一个小熊派IoT开发板,并通过USB线与电脑连接。Micro SD卡小熊派开发板板载 Micro SD 卡槽,最大支持 32 GB,需要提前自行准备一张 Micro SD卡,如图:2.生成MDK工程选择芯片型号打开STM32CubeMX,打开...

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

mark

1. 准备工作

硬件准备

  • 开发板
    首先需要准备一个小熊派IoT开发板,并通过USB线与电脑连接。

mark

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

mark

2.生成MDK工程

选择芯片型号

打开STM32CubeMX,打开MCU选择器:
mark

搜索并选中芯片STM32L431RCT6:
mark

配置时钟源

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

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

这里我都使用外部时钟:

mark

配置串口

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

mark

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

接下来开始配置USART1

mark

配置 SDMMC 接口

知识小卡片 —— SDMMC接口

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

知识小卡片结束啦~

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

mark

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

mark

配置时钟树

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

mark

生成工程设置

mark

代码生成设置

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

mark

生成代码

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

mark

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

重定向printf( )函数

参考:单片机基础——重定向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)之前编写如下读取信息代码:



//
printf("Micro SD Card Test...\r\n");


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


mark

擦除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卡读出的数据:


//
//
uint8_t read_buf[512];
//


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



//
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


向SD卡块写入数据

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


uint8_t write_buf[512];


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



//
for(i = 0; i < 512; i++)
{
    write_buf


然后继续添加代码,将该缓冲区数据写入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


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


mark

mark

mark

mark

mark




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


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。