cancel
Showing results for 
Search instead for 
Did you mean: 

Delay function with TIM14 in nucleo G031K8

Tommino
Senior
void TIM14_init(void){
	RCC->APBENR2|=(1<<15);
	TIM14->PSC= 31;
	TIM14->SR=0;
	TIM14->CNT=0;
	TIM14->EGR|=(1<<0);
}
void TIM14_delay_us (int delay_us){
	TIM14->ARR = delay_us;
	TIM14->CR1|= (1<<0); // counter enabled
	while (!((TIM14->SR)&1)); // wait Update flag to be set
}

Hi,

I have written these two functions to init TIM14 and perform a us delay. It seems to not work. Can you help me?0693W00000UoGKvQAN.png0693W00000UoGKqQAN.png

9 REPLIES 9
Antoine Odonne
ST Employee

Dear Tomino,

The fact the SR LSB is already set is surprising in this setup indeed, but I don't see something incorrect. Did you tried to clear it within the delay_us function ?

Thank you and regards,

Antoine

> It seems to not work.

 How do you know?

JW

Hi @Community member​ 

Sorry if I was not complete but I thought that the mistake was in myTIM14 functions.

I discovered that they works correctly but only if TIM14_delay_us is put after this function  MX_GPIO_Init(); that MX produces automatically (I am not using any HAL functions but only creating the project automatically in STM32 cube ide selecting the nucleo board that I am using and  MX_GPIO_Init(); comes out)

TIM14_delay_us works fine if it is used in the while(1) loop after all the init functions.

TIM14_delay_us does not work if it is used before MX_GPIO_Init();

I did not figure out why it is happening so far

> TIM14_delay_us does not work

I still don't know what do you mean by "does not work" here.

JW

Sorry @Community member​ 

Does not work means that the function does not produce the delay (I can see it because I blink a led). I will try to give you some more details

Forget what I wrote before. My function TIM14_delay_us produces the delay in the led blinking only if write it twice.

example:

TIM14_delay(10000);

TIM14_delay(10000);

produces a 10 ms delay.

I will try to describe what happens

If I call the function only one time, in the TIM14 register I can see the UIF flag immediately raised (eventhough I write TIM14->SR=0;). I can see it in live expression

> TIM14->EGR|=(1<<0);

This sets the Update flag so clear SR before you start the counter in delay.

Also stop the counter after delay.

JW​

Tommino
Senior

Hi @Community member​ ,

I still have the same issue. The delay is produced only if I call TIM14_delay twice. Do you have any other suggestion?

Below there is the updated code.

void TIM14_init_delay(void){
	RCC->APBENR2|=(1<<15);
	TIM14->PSC= 16000-1; // 16 MHz clock --> 1000 Hz timer clock
	}
 
void TIM14_delay (int delay_ms){
	TIM14->SR=0;
	TIM14->CNT=0;
	TIM14->ARR = delay_ms;
	TIM14->CR1|= (1<<0); // counter enabled
	while (!((TIM14->SR)&TIM_SR_UIF)); // wait Update flag to be set
	TIM14->CR1&= ~(1<<0);
}

At this point I have no more ideas.

JW

Isn't it that only the very first delay after reset "does not work" (finishes much faster than all subsequent calls of the function)? If yes, that's because you *do* need the forced update (by setting EGR.UG) after setting PSC, as PSC is unconditionally preloaded. In other words, the very first run of that function works with the default PSC=0, and only after the Update happens at the end of that first run, PSC gets loaded and subsequent calls use it.

JW