Skip to main content
Nero
Associate
November 18, 2024
Solved

STM32 UART Byte-to-Byte treatment

Hello,

 

I am trying to receive and transmit byte-to-byte on a STM32F429 Discovery, I will be using a STM32U5 Discovery soon. I used UART IT method but maybe there is a better solution...

Objective & Issue:

I want to continuously receive and send byte-to-byte, goal is to apply a function to each byte before transmitting it. Right now I can receive and transmit but I lose some characters in the process.

For example if I send "Passphrase" to Uart using a python script, my implementation will transmit something like "PasPhase". It gets worst if I add more code to do something to the byte for instance...

How can I fix this ? This is not the case if I use a bigger buffer but I want to make sure I receive a byte, treat it and send it through UART ASAP, maybe there is a way to receive next byte at the same time I am treating the current byte ?

 

What I did:

I am using HAL_UART_Receive_IT and HAL_UART_Transmit_IT based on examples I found in the F4 firmware.
I am using a tag UartReady to SET and RESET to alternate between Receive and Transmit.

 

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define BUFFER_SIZE 1
/* USER CODE END PD */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
__IO ITStatus UartReady = RESET;
/* USER CODE END PV */

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

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

uint8_t volatile g_aui_read_buf[BUFFER_SIZE] = {0};

/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* MCU Configuration--------------------------------------------------------*/

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

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

 /* USER CODE BEGIN 3 */
 UartReady = RESET;
 if (HAL_UART_Receive_IT(&huart1, &g_aui_read_buf, BUFFER_SIZE) != HAL_OK)
 {
 Error_Handler();
 }
 while (UartReady != SET)
 {
 }

 UartReady = RESET;
 if (HAL_UART_Transmit_IT(&huart1, &g_aui_read_buf, BUFFER_SIZE) != HAL_OK)
 {
 Error_Handler();
 }

 while (UartReady != SET)
 {
 }

 /* Reset transmission flag */
 UartReady = RESET;
 }
 /* USER CODE END 3 */
}

/**
 * @brief USART1 Initialization Function
 * None
 * @retval None
 */
static void MX_USART1_UART_Init(void)
{

 huart1.Instance = USART1;
 huart1.Init.BaudRate = 115200;
 huart1.Init.WordLength = UART_WORDLENGTH_8B;
 huart1.Init.StopBits = UART_STOPBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
 Error_Handler();
 }
}
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *p_h_uart)
{
 /* Set transmission flag: transfer complete */
 UartReady = SET;
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *p_h_uart)
{
 UartReady = SET;
}

/* USER CODE END 4 */

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

 

 

This topic has been closed for replies.
mƎALLEm
mƎALLEmBest answer
ST Technical Moderator
November 18, 2024

Example of ring buffer implementation:

http://www.simplyembedded.org/tutorials/interrupt-free-ring-buffer/

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.

4 replies

Andrew Neil
Super User
November 18, 2024

That's a pretty inefficient way of doing it.

A common approach would be to use a Ring Buffer (aka Circular Buffer): your receiver puts its received characters into the buffer, and your processing takes characters from the buffer.

Thus the buffer takes up the "slack" between receiving & processing - to prevent data loss.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
mƎALLEm
mƎALLEmBest answer
ST Technical Moderator
November 18, 2024
To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
Andrew Neil
Super User
November 18, 2024

@mƎALLEm wrote:

Example of ring buffer implementation:


I'm actually using a simplified version of that at the moment!

@Nero don't be put off by the URL having "interrupt-free" in it: 

http://www.simplyembedded.org/tutorials/interrupt-free-ring-buffer/

The article most certainly is about interrupt-driven comms!

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Nero
NeroAuthor
Associate
November 19, 2024

Thank you both @Andrew Neil  @mƎALLEm  for your replies, I will take a look at this !