Trying to blink LED STM32Cube IDE STM32F411E-DISCO - c

I'm trying to get started with STM32Cube IDE by blinking an LED on the board (PD15). I generated the starter C code by selecting the correct board, then added the following to the main loop:
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
HAL_Delay(200);
I know the board works because I can run the example code "Demonstrations" which uses all of the LEDs, unfortunately the source isn't provided. I think the problem might be with the auto generated code so here is the full code:
#include "main.h"
#include "usb_host.h"
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
}
}
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

From the thread on the original post, my problem was that I was not initializing the GPIO ports properly, and the following line was missing from below the HAL_Init() line:
__HAL_RCC_GPIOD_CLK_ENABLE();
With the changes I am able to control the LEDs

Related

STM32 Timer Interrupts causing Debug problems

I'm using STM32MP157A-DK1 Discovery kit with STM32MP157A MPU.
My problem is that when I terminate the debug and launch again my code stop in void HardFault_Handler(void); (in stm32mp1xx_it.c). The first debugging time works ok, the problem was in the second debug.
I tried removing HAL_TIM_Base_Start_IT(&htim14); and the problem stopped, but I need the timer. Also tried switching timers and the others also give me the same debugging problem.
I checked the hardware configuration (.ioc file) and it's all in default values except the timers that I'm using.
int main(void) {
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the system clock */
SystemClock_Config();
}
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
}else{
/* IPCC initialisation */
MX_IPCC_Init();
/* OpenAmp initialisation ---------------------------------*/
MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
}
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM14_Init();
/* USER CODE BEGIN 2 */
/*
* Create Virtual UART device
* defined by a rpmsg channel attached to the remote device
*/
log_info("Virtual UART0 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart0) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART0 failed.\r\n");
Error_Handler();
}
log_info("Virtual UART1 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart1) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART1 failed.\r\n");
Error_Handler();
}
//Need to register callback for message reception by channels
if(VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
if(VIRT_UART_RegisterCallback(&huart1, VIRT_UART_RXCPLT_CB_ID, VIRT_UART1_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
HAL_TIM_Base_Start_IT(&htim14); //Here is the trouble maker
while(1){
OPENAMP_check_for_message();
}
}
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if(htim == &htim14){
//do something
}
}
void VIRT_UART0_RxCpltCallback(VIRT_UART_HandleTypeDef *huart) {
//log_info("Msg received on VIRTUAL UART0 channel: %s \n\r", (char*) huart->pRxBuffPtr);
}
void VIRT_UART1_RxCpltCallback(VIRT_UART_HandleTypeDef *huart) {
log_info("Msg received on VIRTUAL UART1 channel: %s \n\r", (char*) huart->pRxBuffPtr);
}
I'm using Windows 10, STM32CubeIDE (Version: 1.8.0, Build: 11526_20211125_0815 (UTC)), STM32CubeMX (Version: 6.4.0-RC4, Build: 20211122-2105 (UTC)).
I just put
TIM14->DIER &= ~(TIM_IT_UPDATE);
TIM14->CR1 &= ~(TIM_CR1_CEN);
before call timer initialization
MX_TIM14_Init();
The problem was in Production Mode the A7 core controls all M4's peripherical, so it only reset the interruption when I reset the core A7. This code I use turn off the interrupt to prevent a interrupt call before initialization. You must call it for every peripheric interrupt (check how to disable it, for timers just change the TIM number. Ex: TIM3, TIM17, ...)
Don't know if it's the best way, it's working until now though.
Final main() code:
int main(void) {
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the system clock */
SystemClock_Config();
}
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
}else{
/* IPCC initialisation */
MX_IPCC_Init();
/* OpenAmp initialisation ---------------------------------*/
MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
}
/* USER CODE BEGIN SysInit */
TIM14->DIER &= ~(TIM_IT_UPDATE);
TIM14->CR1 &= ~(TIM_CR1_CEN);
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM14_Init();
/* USER CODE BEGIN 2 */
/*
* Create Virtual UART device
* defined by a rpmsg channel attached to the remote device
*/
log_info("Virtual UART0 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart0) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART0 failed.\r\n");
Error_Handler();
}
log_info("Virtual UART1 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart1) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART1 failed.\r\n");
Error_Handler();
}
//Need to register callback for message reception by channels
if(VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
if(VIRT_UART_RegisterCallback(&huart1, VIRT_UART_RXCPLT_CB_ID, VIRT_UART1_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
HAL_TIM_Base_Start_IT(&htim14); //Here is the trouble maker
while(1){
OPENAMP_check_for_message();
}
}

STM32: I2S input not working when using DMA

I am trying to interface a 'STM32F401RET6 Nucleo-64' microcontroller with an Adafruit I2S microphone in a mono setup. To accomplish this task, I would like to have DMA enabled.
I used the Device Configuration Tool in STM32 Cube IDE to activate I2S3 using the following parameters:
I2S3
Full Duplex Master
Transmission mode: Mode Master Receive;
Communication standard: MSB First (Left Justified);
Data and Frame Format: 24 Bits Data on 32 Bits Frame;
Selected Audio Frequency: 48 kHz;
Clock Source: I2S PLL Clock;
Clock Polarity: Low;
Master clock output disabled.
DMA
SPI_RX3, DMA 1 Stream 2, Peripheral to Memory, High Priority;
FIFO, Threshold = Full, Data Width = Half Word, Burst Size = Single;
In the NVIC settings, interrupts are enabled for both DMA 1 Stream 2 and SPI3.
Next, the Code Generator Tool was used to automatically generate starting code. Some changes were made to this starting code:
Set GPIO_PULL_DOWN so that tri-state always reads in 0;
I already used an oscilloscope to plot the digital data waveform coming from the microphone. This seemed to be correct, i.e., sound triggered the microphone and this was visible in the most significant bits. This makes that the error is in reading in the data into the correct format, if I'm correct.
To perform mono measurements, the datasheet states that one should use a 100k Ohm resistor, which is present in my setup.
In my main.c program, I'm using the HAL function 'HAL_I2S_Receive_DMA' to try to fill my array of 500 samples.
main.c:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
I2S_HandleTypeDef hi2s3;
DMA_HandleTypeDef hdma_spi3_rx;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2S3_Init(void);
static void MX_DMA_Init(void);
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2S3_Init();
MX_DMA_Init();
/* Infinite loop */
HAL_StatusTypeDef retval; // return value
volatile int16_t data[500] = {0};
int16_t data_shifted[500];
while (1)
{
retval = HAL_I2S_Receive_DMA(&hi2s3, data, 500);
// for(short i=0; i<500; i++){
// data_shifted[i] = data[i] >> 14;
// }
HAL_Delay(1000);
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* Configure the main internal regulator output voltage */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/* Initializes the RCC Oscillators according to the specified parameters
in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 84;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Initializes the CPU, AHB and APB buses clocks */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_I2S3_Init(void)
{
hi2s3.Instance = SPI3;
hi2s3.Init.Mode = I2S_MODE_MASTER_RX;
hi2s3.Init.Standard = I2S_STANDARD_MSB;
hi2s3.Init.DataFormat = I2S_DATAFORMAT_24B;
hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_48K;
hi2s3.Init.CPOL = I2S_CPOL_LOW;
hi2s3.Init.ClockSource = I2S_CLOCK_PLL;
hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;
if (HAL_I2S_Init(&hi2s3) != HAL_OK)
{
Error_Handler();
}
}
// Enable DMA controller clock
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
}
/*GPIO Initialization Function */
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
}
/* This function is executed in case of error occurrence. */
void Error_Handler(void)
{
/* Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
/**
Reports the name of the source file and the source line number
where the assert_param error has occurred.
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
}
#endif /* USE_FULL_ASSERT */
When I debug my code and put a breakpoint on line 34 in 'main.c', then the microcontroller memory does not update its values accordingly. All values stay equal to zero. Both DMA Status Flags are set to 1.
I guessing that the problem has something to do with timings, but I wasn't able to solve this problem until now.
Link to complete source code on GitHub
Link to HAL_I2S_Receive_DMA function on GitHub
Thanks in advance.
DMA must be initialized before ADC peripheral, but generated code performs initialization in wrong order. It is well known minor flaw in default configuration of current STM32CubeIDE. Try to change
MX_GPIO_Init();
MX_I2S3_Init();
MX_DMA_Init(); // wrong order
to
MX_GPIO_Init();
MX_DMA_Init(); // right order
MX_I2S3_Init();
To make permanent changes,
Open "Project Manager" (tab near Pinout / Clock Configuration)
Project Manager → Advanced Settings → Generated Function Calls
Use tiny arrow buttons near this list to move MX_DMA_Init() above
MX_I2S3_Init()
Save the project, generated code will have correct order
for my experience,
HAL_I2S_Receive_DMA() function is to configure the address
(if you learn the LL API, you need manually set source/dest address and length of data: [LL_DMA_SetDataLength()])
So, you can move it before While(1) loop.
if you want to read/process the buffer "data", you can use dma interrupt callback function, in HAL API is : HAL_I2S_RxHalfCpltCallback(), HAL_I2S_RxCpltCallback()
=====================================================================
update:
// init method and buff
...
xx_init()
volatile int16_t data[500] = {0};
int16_t data_shifted[500];
...
//
HAL_I2S_Receive_DMA(&hi2s3, &data[0], 250);
while(1){
if (FLAG_half){
FLAG_half=0;
// add your code: data shift [0:250]...
}
if (FLAG_comp){
FLAG_comp=0;
// add your code: data shift [250:500]...
}
} // end while
} end main
HAL_I2S_RxHalfCpltCallback(){
FLAG_half=1;
}
HAL_I2S_RxCpltCallback(){
FLAG_comp=1;
}

STM32 using CubeMX and STMStudio: 'int main()' doesn't work

I'm learning to code on STM32F429ZI Nucleo board and I've been trying to read temperature from ADC1 temperature sensor using STMStudio.
The code I found in one of tutorials didn't work so I tried checking value of "check" variable at various parts of code and then I've noticed that, not only the value of "check" variable doesn't change anywhere inside the main function, but also the STMStudio doesn't see any variables declared inside of the main function.
Any idea why is that?
I've tried different code which uses button to light up LED to check if the board is ok and it worked just fine.
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
uint16_t SenseADC;
float check = 0;
float Temperature;
float Vsense;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
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_ADC1_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start(&hadc1);
check = 2;
const float V25 = 0.76; // [V]
const float Vsupply = 3.0; // [V]
const float ADCResolution = 4095;
const float avg_slope = 0.0025; // [V/deg. C]
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK){
check = 3;
SenseADC = HAL_ADC_GetValue(&hadc1);
Vsense=(SenseADC*Vsupply)/ADCResolution;
Temperature = (Vsense - V25)/avg_slope + 25;
HAL_ADC_Start(&hadc1);
}
}
}
The compiler must have noticed that the check variable is only written and never read, and optimized away the writes as having no purpose. For debugging purposes, you can declare it as volatile to force all writes to get through to memory.
The const values in the program are likewise victims of the optimization, the compiler has used the values directly in the code, possibility precalculating parts of the expressions.

stm32f051r8t6 TIM14 interrupt handler not working after reset

I am using STM32CubeMX to generate code into IAR, and I am using a stm32f051r8t6 microcontroller,
The problem I am having is that when first loading the code onto the chip, it all works perfect, however after pressing restart on either the board or IAR debugger, the TIM14 interrupt handler is not entered, but as soon as I leave the debugger and enter again, it starts working until I press restart. Has anybody come across this problem before? My code is below
static void MX_TIM14_Init(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM14)
{
HAL_GPIO_WritePin(GPIOA, USART1_TE_Pin, GPIO_PIN_SET);
}
}
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_DMA_Init();
MX_ADC_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_TIM14_Init();
HAL_TIM_Base_Start(&htim14);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
FslBufferControl();
MimModeCheck();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 0 */
/* USER CODE END TIM14_Init 0 */
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 47999;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 1;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}
You need to add to enable the interrupt.
MX_TIM14_Init();
HAL_NVIC_EnableIRQ(TIM14_IRQn); // <----------------------------
HAL_TIM_Base_Start(&htim14);
Just check the IRQn TIM14 UG event number. They are defined in the IRQn_Type enum type defined in the STM32F___.h file where ___ is the model of your micro (you will find it in the include folder)

Writing data to micro SD card from microcontroller STM32F401RET6

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.
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.
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 */
}
}

Resources