cancel
Showing results for 
Search instead for 
Did you mean: 

Incorrect interrupt time

Nmo.1
Associate III

Hi everyone,

I'm using Nucleo H723 board. I have used 8 timers in encoder mode to read the encoders. I have also activated another timer to make an interrupt every 4ms to send the data via Usart.

everything work good but when I use sprint code to put the data in Usart, the interrupt time has been changed and it's not 4ms.

Part of my code inside interrupt:

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
 
 	timer2 = __HAL_TIM_GET_COUNTER(&htim2);
 	timer5 = __HAL_TIM_GET_COUNTER(&htim5);
 	timer23 = __HAL_TIM_GET_COUNTER(&htim23);
 	timer24 = __HAL_TIM_GET_COUNTER(&htim24);
 	timer1 = __HAL_TIM_GET_COUNTER(&htim1);
 	timer3 = __HAL_TIM_GET_COUNTER(&htim3);
 	timer4 = __HAL_TIM_GET_COUNTER(&htim4);
 	timer8 = __HAL_TIM_GET_COUNTER(&htim8);
 
	 count_FL_1=timer1/4;
	 count_FR_1=timer3/4;
	 count_RR_1=timer5/4;
	 count_RL_1=timer23/4;
 
	 count_FL_2=timer2/4;
	 count_FR_2=timer4/4;
	 count_RR_2=timer8/4;
	 count_RL_2=timer24/4;
 
 
         sprintf(buffer_FL_1, "FL_1: %ld\n", count_FL_1);
	 sprintf(buffer_FR_1, "FR_1: %ld\n", count_FR_1);
	 sprintf(buffer_RR_1, "RR_1: %ld\n", count_RR_1);
	 sprintf(buffer_RL_1, "RL_1: %ld\n", count_RL_1);
	 sprintf(buffer_FL_2, "FL_2: %ld\n", count_FL_2);
	 sprintf(buffer_FR_2, "FR_2: %ld\n", count_FR_2);
	 sprintf(buffer_RR_2, "RR_2: %ld\n", count_RR_2);
	 sprintf(buffer_RL_2, "RL_2: %ld\n", count_RL_2);
 
 
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_i,strlen(buffer_i), 100);
 
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_FL_1,strlen(buffer_FL_1), 100);
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_FR_1,strlen(buffer_FR_1), 100);
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_RR_1,strlen(buffer_RR_1), 100);
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_RL_1,strlen(buffer_RL_1), 100);
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_FL_2,strlen(buffer_FL_2), 100);
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_FR_2,strlen(buffer_FR_2), 100);
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_RR_2,strlen(buffer_RR_2), 100);
	 HAL_UART_Transmit(&huart3, (uint8_t *) buffer_RL_2,strlen(buffer_RL_2), 100);
 
 
    i++;
    j=i/1000;
 
 
 
 
}

Hier is my timer configuration.

0693W00000KaQ7ZQAV.pngwhen I delete the sprint codes the timer 4ms runs again correctly.

I appreciate it if you help me.

7 REPLIES 7
Peter BENSCH
ST Employee

sprintf consumes a lot of memory and takes a lot of time.

What about your heap size?

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

O.K. Thank you so much. I'm a beginner and didn't know that. So I need to try another way to sent data to PC.

How can I find heap size?

It looks like you create your skeleton program using STM32CubeMX or the STM32CubeIDE: just open your project > Project Manager, where you can set the heap size and the stack size.

Alternatively you can change it in the file ***_FLASH_ld, but that would be under the level of CubeMX, because it doesn't know about it and overwrites it again when the code is regenerated. The default value there is:

_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x400 ; /* required amount of stack */

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Nmo.1
Associate III

Thnaks. I changed it in FLASH.ld to the

_Min_Heap_Size = 0x100 ; /* required amount of heap */

_Min_Stack_Size = 0x1000 ; /* required amount of stack */

but the time is still incorrect.

I have also tried 0 and 800 or 100 and 800 but it didn't work.

You'd do better queuing the data you want to send, and using functions that don't block execution, but rather manage that in the UART interrupt, and don't generate data faster than the serial port can output.

At 9600 baud every character takes around 1 ms

HAL_UART_Transmit() blocks, it has no place in an interrupt.

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

Thanks for your reply.

But there is a lot of data (15000 numbers) I think queuing is not possible.

And when I use the HAL_UART_Transmit in the While loop it does the send data not every 4ms.

It's very important to record the data every 4ms. Doing the record I have no problem. I have only problem sending the data to PC to save them. (logging)

Do have any idea how I can do it?

As @Community member​ already said, one should urgently leave time-consuming activities out of an interrupt routine, especially such blocking calls. In your case, this is exacerbated by the fact that you convert the values into decimal numbers, which contain a lot of "hot air", i.e. redundancy.

If you have to send data permanently and cannot store it temporarily in a FIFO or ring buffer, then please do so at maximum speed and in binary in order to achieve maximum data throughput.

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.