cancel
Showing results for 
Search instead for 
Did you mean: 

How to ensure UART transmits data every second ?

SA.17
Associate III

Hi,

I am using STM32L0 MCU

I am using HAL_USART_TRANSMIT function to send data to a computer

I am using Timer interrupt to ensure that UART transmits data every second

But when i see log on computer ,its not exactly 1 sec, and this change also varies with baudrate ,so if Baud rate is 115200 ,getting data on uart every 1.3 sec (approx.) and it is not same everytime,whereas with 9600 it is slower .

How to ensure that uart sends data at every 1sec ( with HAL API or LL API or any other way) ?

timer code(using systick timer)

 

void SysTick_Handler(void)
 
 {
 
 /* USER CODE BEGIN SysTick_IRQn 0 */
 
 /* USER CODE END SysTick_IRQn 0 */
 
 HAL_IncTick();
 
 /* USER CODE BEGIN SysTick_IRQn 1 */
 
if(flag_uart_delay == 0)
 
 {
 
 counter_uart ++ ;
 
 if(counter_uart >= 1000)
 
 {
 
  flag_uart_delay = 1 ;
 
  counter_uart = 0;
 
 }
 
 }
 
}

Main Code

 

if(flag_uart_delay == 1)
 
{
 
//HAL_TRANSMIT_DATA ( ... )
 
flag_uart_delay = 0 ;
 
}

1 ACCEPTED SOLUTION

Accepted Solutions

This is my understanding after reading your code.

With current code, during transmission, flag_uart_delay is 1, so all SysTick Handler execution during the UART TX phase, have no impact on counter_uart which remains = 0. counter_uart increments will restart after TX, once flag_uart_delay is reset to 0.

What you have now is :

<--- 1 sec period ----><--TX--><--- 1 sec period ----><--TX--><--- 1 sec period ----> ...

If you want to have :

<--- 1 sec period ----><--- 1 sec period ----><--- 1 sec period ----> ...
<--TX-->               <--TX-->               <--TX-->

You need either :

  • to still increment timer during the Tx (by setting flag_uart_delay = 0 after TX start if you use polling mode)
  • to use IT or DMA mode for ensuring TX process. IT and MDA API calls only initiate the TX steps, and function exit (return to main() will not need that TX is ended

Guenael

View solution in original post

10 REPLIES 10

Is that a regular timer interrupt, triggered by timer Update? You don't change anything with the timer within that interrupt, do you?

Show code.

JW

added code in question

SA.17
Associate III

I am using systick timer,not changed anything in timer configuration,used the code as it is generated by stm32cubemx

Ozone
Lead

> But when i see log on computer ,its not exactly 1 sec, and this change also varies with baudrate ,so if Baud rate is 115200 ,getting data on uart every 1.3 sec (approx.) and it is not same everytime,whereas with 9600 it is slower .

How sure you are about the measurements on PC side ? Windows is no RT OS either.

Toggle a pin during UART send, and check with a scope.

If you find that same large variance with a scope, you can use the same method to find out where the "lost" MCU time is spent.

SA.17
Associate III

I am using Tera term on computer to receive it ,and have enabled time on it,so whenever it(tera term) receives signal it attaches time and date to log (where time and date are taken from computer clock) . Even if windows is not RTOS ,clock is always accurate on it

, I will try with oscilloscope

Measure signal with a scope to be sure to know where the issue is. Probably not the time base of the STM32 with a crystal.

Check clocks parameters and dividers.​

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

Hi @SA.17​ 

Are you using HAL UART transmit API in Polling mode (HAL_UART_Transmit() API) ?

If so, this means that in your main(), flag_uart_delay variable, once set to 1 in Systick Handler, will be set to 0 again after transmission time, so depends on baudrate and nb of transmitted data.

In such case, 1 sec time period is not the time between the start of 2 TX sequences, but rather the time between end of last Tx sequence, and start of next one.

Guenael

yes i am using polling mode,

you mean to say i should make flag_uart_delay variable set to 0 before using UART transmit API

or should i use it in interrupt mode

This is my understanding after reading your code.

With current code, during transmission, flag_uart_delay is 1, so all SysTick Handler execution during the UART TX phase, have no impact on counter_uart which remains = 0. counter_uart increments will restart after TX, once flag_uart_delay is reset to 0.

What you have now is :

<--- 1 sec period ----><--TX--><--- 1 sec period ----><--TX--><--- 1 sec period ----> ...

If you want to have :

<--- 1 sec period ----><--- 1 sec period ----><--- 1 sec period ----> ...
<--TX-->               <--TX-->               <--TX-->

You need either :

  • to still increment timer during the Tx (by setting flag_uart_delay = 0 after TX start if you use polling mode)
  • to use IT or DMA mode for ensuring TX process. IT and MDA API calls only initiate the TX steps, and function exit (return to main() will not need that TX is ended

Guenael