Writing data to micro SD card from microcontroller STM32F401RET6

2.9k Views Asked by At

I am using the board Nucleo F401RE based on micro-controller STM32F401RET6. I connected to the board a Micro SD slot, and interested in writing data to the SD Card and read data from it. I used the software STM32CubeX to generate code and in particular the SD library with built-in functions. I tried to write a simple code which writes an array to a specific array and tries to read the same data afterwords. The code is as follows:

uint32_t to_send[512] = {1, 2, 3, 4, 5};
uint32_t to_receive[512];

int main(void)
{

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_SDIO_SD_Init();

  char buffer[14] = "Hello, world\n";
  uint64_t address = 0x00; 
  HAL_SD_ErrorTypedef write_result = HAL_SD_WriteBlocks(&hsd, to_send, address, 512, 1);
  HAL_SD_ErrorTypedef read_result = HAL_SD_ReadBlocks(&hsd, to_receive, 0x00, 512, 1);
  HAL_UART_Transmit(&huart2, (uint8_t *) &write_result, 1, 1000);
  HAL_UART_Transmit(&huart2, (uint8_t *) &read_result, 1, 1000);


  while (1)
  {
      //HAL_UART_Transmit(&huart2, (uint8_t *)buffer, 14, 1000);
      HAL_UART_Transmit(&huart2, (uint8_t *)to_receive, 512, 1000);


}

Though, I don't succeed in writing the data, the function HAL_SD_WriteBlocks() returns the value SD_CMD_CRC_FAIL, which means that : "Command response received (but CRC check failed)". What am I missing ? I checked the hardware configuration many times and the micro SD card is correctly connected to the microcontroller. I can add the implementation of the HAL built-in functions if needed. Thank you.

2

There are 2 best solutions below

2
On

Make sure that your sdio clock is within valid limits (see function SystemClock_Config):

/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M      8
#define PLL_N      336

/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2

/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      7

When using the defines above when initialize the clock (RCC_OscInitTypeDef) the SDIO clock will be 336 / (7*2) = 25Mhz

(Given that PLL_M is the same as the HSE / HSI)

If the frequency is too high (>50Mhz) then perhaps you will get errors in the communication which will explain your symptoms.

0
On
I didnt use usart for my project, i write the value to sd card and read the value ,
you must arrange the code for your expectations, my code is 


#include "main.h"
#include "stm32f4xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;


/* USER CODE BEGIN PV */
/* Private variables --------------------------------------------------------*/
uint8_t to_send[512] = "sener suat sd card";
uint8_t to_receive[512];
uint8_t sener[3]={7,5,4};

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDIO_SD_Init(void);
static void MX_USART2_UART_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* 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();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SDIO_SD_Init();

  /* USER CODE BEGIN 2 */
   uint32_t address = 0x55;
  HAL_SD_MspInit(&hsd);
  HAL_SD_Init(&hsd);
  HAL_SD_WriteBlocks(&hsd,to_send,address,1,500);
  HAL_Delay(100);
  HAL_SD_ReadBlocks(&hsd,to_receive,address,1,500);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */

  }


}