cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_Transmit on STM32L152C-DISCO

UCTst32
Associate II

I have set up a UART on a STM32L152C Discovery board on bare metal.  No Embedded OS but using HAL.

I'm running a single thread.  The UART is being configured as:

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;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;

A simple function call in the while loop in main:

uint8_t myString[40];
int i=0;

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
  i++;
  sprintf((char*) myString, "Count %i\r\n", i);
  HAL_UART_Transmit(&huart1, myString, strlen((char*) myString), HAL_MAX_DELAY);
  while (HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY) {
}
  HAL_Delay(1);
    
/* USER CODE END WHILE */
}

yields the following output.
The first original buffer contents of the first HAL_UART_Transmit call just repeat:

Count 1
Count 1
Count 2
Count 3    .
    .
    .
Count 63
Count 1
Count 2
    .
    .
(repeats a cycle of 63)

IF HAL_Delay is changed to
HAL_Delay(5);

The output wraps at 23.

If HAL_Delay(10);

The output wraps at 13

If HAL_Delay is any value above 130,

The initial HAL_UART_Transmit call appears to just repeat:
Count 1

What am I missing here?
How is this supposed to be implemented to properly transmit an updated buffer on subsequent loops?

Comments appreciated.
Thanks

9 REPLIES 9
Issamos
Lead II

Hello @UCTst32 

You should debug your code. That will show you what is happening every time and you will find the issue.

Best regards.

II

Thank you for the suggestion.

However, I have already traced through this using the debugger.
The index is incrementing as expected.
But it is unclear how the HAL_UART_Transmit function is running from what I see in the debugger.

Does the use of the HAL appear correct?

Bob S
Principal

Is that REALLY your code (i.e. did you copy/paste into the forum post), or did you re-type it?  There is no OBVIOUS reason for that behavior.  If the snprintf() were overflowing your buffer the it might corrupt your loop variable, but that shouldn't happen (see below).  Maybe a stack overflow?  Set breakpoints and see what it going on.

Probably not the source of your issue, but:

  • When using HAL_UART_Transmit(), you don't need to following code that checks the state.  The function won't return until it is done.
  • Do yourself a favor and NEVER use sprintf(), always use snprintf().  Likewise, strncpy() not strcpy(), etc.  Yes, in your example you will never overflow the buffer.  But code defensively and make SURE it can never happen.  Code changes.  Buffer declarations are not always easily visible from where they are used.

I copied/pasted the snippets that seemed relevant.

Thanks for the suggestion.
Sounds like other than the need to use snprintf(), the code itself doesn't seem suspect

The code has to be working fine. You may consider use another product in your next project because this board is not recommended by ST for new projects.

Best regards.

II

TDK
Guru

Sounds like you have a watchdog enabled and the chip is getting reset at a given time after reset.

If you feel a post has answered your question, please click "Accept as Solution".

/*#define HAL_IWDG_MODULE_ENABLED */
This is commented out in stm32l1xx_hal_conf.h
Don't see a WD enabled anywhere else.
Thanks for the suggestion though.

Use STM32CubeProgrammer to connect and check the option bytes for a hardware enabled IWDG.

If you feel a post has answered your question, please click "Accept as Solution".

I'm using the STM32CubeProgrammer now to read the bytes.
I see that the software independent watchdog is active
What else am I looking for?

Thanks