利用周末的时间和大家分享一下使用STM32cube MX软件配置SD卡的过程。
一:SD卡相关知识
SD 卡的规范由 SD 卡协会明确,可以访问 https://www.sdcard.org 查阅更多标准。SD 卡主要有 SD、Mini SD 和 microSD(原名 TF 卡,2004 年正式更名为 Micro SD Card,为方便本文用microSD 表示)三种类型,Mini SD 已经被 microSD 取代,使用得不多,根据最新的 SD 卡规格列出的参数如下所示
二: STM32 cube MX 软件配置如下所示:
三:软件代码如下所示:
3.1 SD卡的初始化过程:
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; hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; hsd.Init.BusWide = SDIO_BUS_WIDE_1B; hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE; hsd.Init.ClockDiv = 4; if (HAL_SD_Init(&hsd) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SDIO_Init 2 */ /* USER CODE END SDIO_Init 2 */ }
3.2 向SD卡写入数据如下所示:
uint8_t sd_read_disk(uint8_t *pbuf, uint32_t saddr, uint32_t cnt) { uint8_t sta = HAL_OK; uint32_t timeout = SD_TIMEOUT; long long lsector = saddr; __disable_irq(); /* 关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!) */ sta = HAL_SD_ReadBlocks(&g_sdcard_handler, (uint8_t *)pbuf, lsector, cnt, SD_TIMEOUT); /* 多个sector的读操作 */ /* 等待SD卡读完 */ while (get_sd_card_state() != SD_TRANSFER_OK) { if (timeout-- == 0) { sta = SD_TRANSFER_BUSY; } } __enable_irq(); /* 开启总中断 */ return sta; }
3.3 向SD卡读取数据如下所示:
uint8_t sd_write_disk(uint8_t *pbuf, uint32_t saddr, uint32_t cnt) { uint8_t sta = HAL_OK; uint32_t timeout = SD_TIMEOUT; long long lsector = saddr; __disable_irq(); /* 关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!) */ sta = HAL_SD_WriteBlocks(&g_sdcard_handler, (uint8_t *)pbuf, lsector, cnt, SD_TIMEOUT); /* 多个sector的写操作 */ /* 等待SD卡写完 */ while (get_sd_card_state() != SD_TRANSFER_OK) { if (timeout-- == 0) { sta = SD_TRANSFER_BUSY; } } __enable_irq(); /* 开启总中断 */ return sta; }
四:实物测试如下所示: