freertos_f407/User/board/sd.c

226 lines
5.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();
}