SDMMC--SD卡
本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SDMMC外设读取SD卡数据。
一. 准备工作
硬件准备
- 开发板:小熊派BearPi-IoT_Std开发板
- Micro SD卡: 小熊派开发板板载 Micro SD 卡槽,最大支持 32 GB,需要提前自行准备一张 Micro SD卡,如图:
- 完成STM32 CubeMX 安装
- 参考BearPi-IoT_Std十分钟上手教程完成MDK开发环境搭建。
二.生成MDK工程
1.选择芯片型号
打开STM32CubeMX,打开MCU选择器:
搜索并选中芯片STM32L431RCT6
:
2.配置时钟源
- 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC;
- 如果使用默认内部时钟(HSI),这一步可以略过;
这里使用外部时钟为例:
3.配置串口
小熊派开发板板载ST-Link并且虚拟了一个串口,原理图如下:
这里我将开关拨到AT-MCU
模式,使PC的串口与USART1之间连接。
接下来开始配置USART1
:
4.配置 SDMMC 接口
知识小卡片 —— SDMMC接口
SDMMC接口的全称叫SD/SDIO MMC card host interface
,SD/SDIO MMC 卡 主机接口,通俗的来说,就是这个接口支持SD卡,支持SDIO设备,支持MMC卡。
知识小卡片结束啦~
首先查看小熊派开发板的原理图:
然后根据原理图配置 SDMMC 接口:
5.配置时钟树
STM32L4的最高主频到80M,所以配置PLL,最后使HCLK = 80Mhz
即可:
6.生成工程设置
7.代码生成设置
最后设置生成独立的初始化文件:
8.生成代码
点击GENERATE CODE
即可生成MDK-V5工程:
三. 编译测试
1.编写用户代码
重定向printf( )函数
编写测试代码
在main.c
中首先定义相关变量及宏定义
HAL_SD_CardCIDTypedef SD_CardCID;
#define BLOCK_SIZE 512 // 块大小
#define NUMBER_OF_BLOCKS 8 // 块数量
#define WRITE_READ_ADDRESS 0x00002000 // 读写地址
#define WRITE_READ_ADDRESS2 0x00004000 // 读写地址
uint32_t Buffer_Block_Tx[BLOCK_SIZE*NUMBER_OF_BLOCKS]; // 据缓存
uint32_t Buffer_Block_Rx[BLOCK_SIZE*NUMBER_OF_BLOCKS] = {1,2}; // 数据缓存
HAL_StatusTypeDef sd_status; // HAL返回值
在main.c
中添加测试函数
static void ReadSD(void)//读取SD出厂参数
{
int State = 0;
State = HAL_SD_GetCardState(&hsd1);
if (State == HAL_SD_CARD_TRANSFER) {
HAL_SD_GetCardCID(&hsd1, &SD_CardCID);
printf("\r\n Initialize SD card successfully!\r\n\r\n");
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);
printf(" ManufacturerID: %d \r\n", SD_CardCID.ManufacturerID);
} else {
printf("SD card init fail!\r\n");
while (1); // 停机
}
}
static void SD_Write_Read_Test(int32_t addr, uint8_t* temp)//写入SD卡数据并读出数据
{
printf("\r\n\r\n*************Write SD card data *************\r\n");
sd_status = HAL_SD_WriteBlocks(&hsd1, (uint8_t *)temp, addr, NUMBER_OF_BLOCKS, 0xffff);
printf("Write data:%s,address:%x\r\n", temp, addr);
HAL_Delay(480);
if (sd_status == 0) {
printf("Write data test is OK\r\n");
} else
printf("Write data test is fail!\r\n ");
printf("*************Read SD card data *************\r\n");
sd_status = HAL_SD_ReadBlocks(&hsd1, (uint8_t *)Buffer_Block_Rx, addr, NUMBER_OF_BLOCKS, 0xffff);
printf("ReadSDData:%s,address:%x\r\n", (char*)Buffer_Block_Rx, addr);
if (sd_status == 0) {
printf("Read data test is OK\r\n");
} else
printf("Read data test is fail!\r\n ");
}
修改main
函数如下:
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t temp[]="欢迎来到小熊派开源社区";
uint8_t temp1[]="Welcome to BearPi";
/* 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();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_SDMMC1_SD_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
ReadSD();//读取SD卡初始化参数
HAL_SD_ReadBlocks(&hsd1,(uint8_t *)Buffer_Block_Rx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS,0xffff);
printf("Read SD old data1:%s,address:%x\r\n",(char*)Buffer_Block_Rx,WRITE_READ_ADDRESS);
memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx));
HAL_SD_ReadBlocks(&hsd1,(uint8_t *)Buffer_Block_Rx,WRITE_READ_ADDRESS2,NUMBER_OF_BLOCKS,0xffff);
printf("Read SD old data2:%s,address:%x\r\n",(char*)Buffer_Block_Rx,WRITE_READ_ADDRESS2);
memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx));
SD_Write_Read_Test(WRITE_READ_ADDRESS,temp);
memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx));
SD_Write_Read_Test(WRITE_READ_ADDRESS2,temp1);
memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
2.编译代码
选择project菜单,点击Build Project编译工程。
如果工具栏上有编译按钮快捷键,可以直接点击工具栏上的编译按钮:
3.设置下载器
4.下载运行
选择Flash菜单,点击Download下载程序到开发板上并运行。
如果工具栏上有下载按钮快捷键,可以直接点击工具栏上的下载按钮:
5.实验现象
下载运行后,可看到以下日志。
至此,我们已经学会如何使用硬件SDMMC接口读取SD数据。