cancel
Showing results for 
Search instead for 
Did you mean: 

I am trying to send 20486 bytes of data through UART at 2 Mbps. However, I am not able to send full data at this baud rate. Baudrate of 115200 works fine for sending this data however at 2000000 baudrate, it is sending only partial data?

AIsla.1
Associate II

Below is the code for sending data at 2 Mbps baudrate.

#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#include "stm32f446xx.h"
#include "stm32f4xx_hal_cortex.h"
#include "stm32f4xx_hal_tim.h"
#include "main.h"
#include <string.h>
#include <stdint.h>
 
#define BUFFER_SIZE		20486
#define DATA_SIZE 20480
UART_HandleTypeDef uart2_handle;
TIM_HandleTypeDef tim_config;
 
uint8_t data_buffer[BUFFER_SIZE] = {0};
 
volatile int timer_count = 0;
 
int main(void)
{
	  data_buffer[0] = 'T';
	  data_buffer[1] = 'R';
	  data_buffer[2] = 'A';
	  data_buffer[3] = 'A';
	  memset((void *)data_buffer+4, 0x55, DATA_SIZE);
 
	  data_buffer[BUFFER_SIZE-2] = 'Z';
	  data_buffer[BUFFER_SIZE-1] = 'Z';
 
 
	//Initialize the peripherals
	HAL_Init();
 
	//SystemConfig
	SystemClock_Config();
 
	//Initialize the UART
	UART2_Init();
 
 
 
	  //Repeat two data transfers after every 800ms
 
	//uint8_t start_buffer[2] = {'T', 'R'};
 
	HAL_StatusTypeDef uart_status;
 
 
 
while(1)
{
		
	       do
			{
				
				uart_status = HAL_UART_Transmit_IT(&uart2_handle, (uint8_t *)data_buffer, (uint16_t)sizeof(data_buffer)/sizeof(data_buffer[0]));
				if(uart_status == HAL_OK)
				{
					break;
				}
 
				else if(uart_status == HAL_ERROR)
				{
					error_handler();
					break;
				}
			}while(uart_status == HAL_BUSY);
	
 
	
}
 
 
 
 
 
}
 
void UART2_Init(void)
{
	//Enable the UART2 and GPIOA clock.
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_USART2_CLK_ENABLE();
 
	//Configure the UART2 peripheral
	uart2_handle.Instance = USART2;
	uart2_handle.Init.BaudRate = 2000000;
	uart2_handle.Init.Mode = UART_MODE_TX;
	uart2_handle.Init.WordLength = UART_WORDLENGTH_8B;
	uart2_handle.Init.StopBits = UART_STOPBITS_1;
	uart2_handle.Init.Parity = UART_PARITY_NONE;
	uart2_handle.Init.OverSampling = UART_OVERSAMPLING_8;
 
	if(HAL_UART_Init(&uart2_handle) != HAL_OK)
	{
		//Initialization failed.
		error_handler();
	}
 
 
 
}
 
 
 
 
 
 
void SystemClock_Config(void)
{
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
 
  __HAL_RCC_PWR_CLK_ENABLE();
 
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    error_handler();
  }
 
    /**Initializes the CPU, AHB and APB busses 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();
  }
 
 
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
 
 
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
 
 
void error_handler(void)
{
	//Hang in a while loop.
	while(1);
}

10 REPLIES 10
JoniS
Senior

Are you using flow control? How is the PCB layout? How do you observe that only partitial data is being sent?

with such speeds small details quickly becomes important.

It is not sending the data, or your receiver side is not able to sink it successfully?

Review the signal on a scope or logic analyzer.

How close to 2MBaud does it actually get based on the AHB clocks? You should perhaps be running the MCU at some multiple of 32 MHz for this to work well.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
AIsla.1
Associate II

.

No I am not using flow control. I am using STM32F446RE Nucleo Board. I have written receiver code on Raspberry pi and STM is sending data through UART (Virtual COM) to raspberry pi.

Similar partial data send i observed at baudrate of 921600. I verified it via teraterm that it is sending partial data at 921600 baud.

I will check the signal on logic analyzer. I am using PLL clock at 84Mhz as HCLK. UART clock is running at 42 Mhz (APB1).

Not really a robust test of things.

These tests assume the achieved baud rate matches within a couple of percent, I expect you are operating way out of specification. Do the math.

Try 1050000 baud, also 2625000, 2100000 or 1750000

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Pick baud rates where the integer division yields workable numbers.

You can changes the baud rates, or run the processor at derated speeds to achieve specific baud rates.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal

Have you tried to use transmission with DMA?

I think the OP has misdiagnosed the problem. The data is getting sent.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..