#include "sd.h" #include "sdio.h" SD_HandleTypeDef _handle; #define NUM_OF_BLOCKS 1 #define TEST_ADDRESS 0 #define TEST_BLOCK_SIZE ((BLOCKSIZE * NUM_OF_BLOCKS) >> 2) // 定义数据大小,SD块大小为512字节,因为是32位的数组,所以这里除以4 BOOL sd_test(void) { BOOL res = FALSE; uint32_t i = 0; uint32_t write_buffer[TEST_BLOCK_SIZE]; uint32_t read_buffer[TEST_BLOCK_SIZE]; for (i = 0; i < TEST_BLOCK_SIZE; i++) // 将要写入SD卡的数据写入数组 { write_buffer[i] = i + 3; } res = sd_erase(TEST_ADDRESS, NUM_OF_BLOCKS); if (res == FALSE) { return FALSE; } while (sd_get_card_state() == FALSE) ; res = sd_write_blocks(write_buffer, TEST_ADDRESS, NUM_OF_BLOCKS); // 写入数据 if (res == FALSE) { return FALSE; } while (sd_get_card_state() == FALSE) ; res = sd_read_blocks(read_buffer, TEST_ADDRESS, NUM_OF_BLOCKS); // 读取数据 if (res == FALSE) { return FALSE; } while (sd_get_card_state() == FALSE) ; // 验证写入和读取的数据是否一致 for (i = 0; i < TEST_BLOCK_SIZE; i++) { if (read_buffer[i] != write_buffer[i]) { return FALSE; } } return TRUE; } void sd_info(void) { // SD卡信息结构体变量 HAL_SD_CardInfoTypeDef cardInfo; HAL_StatusTypeDef res = HAL_SD_GetCardInfo(&_handle, &cardInfo); if (res != HAL_OK) { return; } } void sd_init(void) { // MX_SDIO_SD_Init有问题,这里重新初始化 _handle.Instance = SDIO; _handle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; _handle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; _handle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; _handle.Init.BusWide = SDIO_BUS_WIDE_1B; // CUBEMX生成默认是4B,此处改为1B _handle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; _handle.Init.ClockDiv = 4; if (HAL_SD_Init(&_handle) != HAL_OK) { Error_Handler(); } if (HAL_SD_ConfigWideBusOperation(&_handle, SDIO_BUS_WIDE_4B) != HAL_OK) { Error_Handler(); } sd_info(); } /** * @brief 获取SD卡的状态 * * 该函数用于获取SD卡的当前状态,并返回一个布尔值表示SD卡是否处于传输状态。 * * @return BOOL - 如果SD卡处于传输状态,则返回TRUE,否则返回FALSE。 */ BOOL sd_get_card_state(void) { HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&_handle); return (state == HAL_SD_CARD_TRANSFER) ? TRUE : FALSE; } /** * @brief 擦除SD卡指定地址范围的数据 * * 该函数用于擦除SD卡上从指定的起始地址到结束地址之间的数据。 * * @param start_address - 擦除操作的起始地址 * @param end_address - 擦除操作的结束地址 * @return BOOL - 如果擦除操作成功,则返回TRUE,否则返回FALSE。 */ BOOL sd_erase(uint32_t start_address, uint32_t end_address) { if (HAL_SD_Erase(&_handle, start_address, end_address) != HAL_OK) { return FALSE; } else { return TRUE; } } BOOL sd_write_blocks(uint32_t *data, uint32_t write_address, uint32_t blocks) { if (HAL_SD_WriteBlocks(&_handle, (uint8_t *)data, write_address, blocks, 1000) != HAL_OK) { return FALSE; } else { return TRUE; } } BOOL sd_read_blocks(uint32_t *data, uint32_t read_address, uint32_t blocks) { if (HAL_SD_ReadBlocks(&_handle, (uint8_t *)data, read_address, blocks, 1000) != HAL_OK) { return FALSE; } else { return TRUE; } } /** * @brief 使用DMA方式从SD卡读取多个数据块 * * 该函数用于通过DMA方式从SD卡的指定地址读取多个数据块,并将数据存储在指定的缓冲区中。 * * @param data - 指向存储读取数据的缓冲区的指针 * @param read_address - 读取操作的起始地址 * @param blocks - 要读取的数据块数量 * @return BOOL - 如果读取操作成功,则返回TRUE,否则返回FALSE。 */ BOOL sd_read_blocks_dma(uint32_t *data, uint32_t read_address, uint32_t blocks) { if (HAL_SD_ReadBlocks_DMA(&_handle, (uint8_t *)data, read_address, blocks) != HAL_OK) { return FALSE; } else { return TRUE; } } /** * @brief 使用DMA方式向SD卡写入多个数据块 * * 该函数用于通过DMA方式向SD卡的指定地址写入多个数据块。 * * @param data - 指向要写入数据的缓冲区的指针 * @param write_address - 写入操作的起始地址 * @param blocks - 要写入的数据块数量 * @return BOOL - 如果写入操作成功,则返回TRUE,否则返回FALSE。 */ BOOL sd_write_blocks_dma(uint32_t *data, uint32_t write_address, uint32_t blocks) { if (HAL_SD_WriteBlocks_DMA(&_handle, (uint8_t *)data, write_address, blocks) != HAL_OK) { return FALSE; } else { return TRUE; } } /** * @brief BSP Tx Transfer completed callbacks * @retval None */ __weak void BSP_SD_WriteCpltCallback(void) { } /** * @brief BSP Rx Transfer completed callbacks * @retval None */ __weak void BSP_SD_ReadCpltCallback(void) { } /** * @brief Tx Transfer completed callbacks * @param _handle: SD handle * @retval None */ void HAL_SD_TxCpltCallback(SD_HandleTypeDef *_handle) { BSP_SD_WriteCpltCallback(); } /** * @brief Rx Transfer completed callbacks * @param _handle: SD handle * @retval None */ void HAL_SD_RxCpltCallback(SD_HandleTypeDef *_handle) { BSP_SD_ReadCpltCallback(); }