2023-04-08 04:16 PM
I'm trying to receive more than 1 byte but it receive only 1 byte. Poll method or IT, it doesn't matter. Always receives 1 byte and writes it in rx_buffer[0]. When I search it I found out the reason is timeout, I increase timeout 1000 from 100ms but nothing changes. Can anyone help me please?
Here is my code for poll
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "string.h"
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart6;
DMA_HandleTypeDef hdma_usart1_rx;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART6_UART_Init(void);
USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
char rx_buffer[50];
char tx_buffer[50];
while (1)
{
HAL_UART_Receive(&huart1,(uint8_t*)rx_buffer,4,1000);
memcpy(tx_buffer,rx_buffer,4);
HAL_UART_Transmit(&huart6,(uint8_t*)tx_buffer,strlen(tx_buffer),1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
Solved! Go to Solution.
2023-04-16 09:06 AM
From what i see, main_buffer is pointless as you are not doing anything with it.
My UART2 is your UART1 and my UART1 is your UART6 which this is working on a Nucleo-L432 board
uint8_t tx_buffer[rx_buff];
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART2)
{
/* start the DMA again */
memset(&tx_buffer, 0, sizeof(tx_buffer)); // clear tx buffer
memcpy(&tx_buffer, &rx_buffer, Size); // copy only what was received
HAL_UART_Transmit_DMA(&huart1, tx_buffer, Size); // use Size instead of sizeof(rx_buffer)
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t *) rx_buffer, sizeof(rx_buffer));
}
}
2023-04-08 06:23 PM
You don't check the return error/status.
It's not really a guarantee you'll receive data, that depends on a source sending data, and when and how often it does that.
If you know that 4 characters will come in, increase the timeout to near infinite.
Consider receiving bytes at a time and building a buffer, usually these things are bounded by specific characters or protocol dependent.
You don't know when things align or synchronize, or if you miss things.
Most STM32 interrupt on a per byte basis, you can handle streams in a stateful manner.
strlen() perhaps not appropriate in this situation, it expects NULs
2023-04-10 06:01 AM
Hello @MÇETİ.1
First let me thank you for posting.
It looks like you are trying to receive multiple bytes using the HAL_UART_Receive function, but it is only receiving a single byte. There are a few things you can check to try and solve this issue:
I hope this helps!
Thx
Ghofrane
2023-04-10 11:42 AM
More than likely your device transmitting is only sending a single byte. A timeout of 100ms is more than enough to receive 4 bytes let alone 1000ms.
You don't clear the rx and tx buffers. So after the first reception, rx buffer will always have the same data. Then you copy that data again to the tx buffer. So you'll see the same data being transmitted over and over with a pause of your receive timeout delay.
Check this post that I replied to https://community.st.com/s/question/0D53W00002CeLaOSAV/cannot-receive-full-string-on-uart-receive-st32h745-disco-board
I have an example of receiving from UART 2 and transmitting to UART 1 which loops back. It uses DMA with idle so you can receive any variable size string. It also uses a ring buffer so the code knows when there is new data received and new data to be transmitted.
2023-04-15 06:01 PM
Hello,
Firstly, I wanna thank you for your suggestings.
I checked my settings then used DMA with Idle Line. It really improved the way receiving data. Now, I'm trying to learn how to transmite whole data that I received.
Thx
Mine
2023-04-15 06:15 PM
Hi,
Thank you for your reply!
I tried to increase timeout but it does not work. I used dma and solve the receiving problem now it's time to figure out how to send whole data.
2023-04-15 07:16 PM
I'm so grateful for your answer.
I used dma with idle line and receive 1.091 bytes but I couldn't figure out how to use TX functions to work them properly.I saw Karl's answer but it is so complex for me actually. I need a bit simplified solution. Could I use HAL_UART_Transmit_DMA ?
2023-04-15 07:38 PM
Yes you can use HAL_UART_Transmit_DMA.
2023-04-15 08:28 PM - edited 2023-11-20 08:41 AM
I used it, first it sent just one time then I also call it in HAL_UARTEx_RxEventCallback at the end. It work exactly what I want I meant when I send a data from UART1 it sends data back from UART6. However, when I send new data it writes it first byte and sends new data and the data I sent before it. I want to receive only last data.
It receives 1 and then changes first byte of the data I sent before 1, and transmite them together.
I receive data with rx_buffer but store whole data sequentially in main_buffer. I tried to transmit both of them but nothing change.
HAL_UART_Transmit_DMA(&huart6,rx_buffer, sizeof(rx_buffer));
2023-04-15 09:06 PM
post your code