2022-10-18 03:28 AM
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?
2022-10-18 06:12 AM
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
2022-10-18 10:34 AM
> It seems to not work.
How do you know?
JW
2022-10-19 06:16 AM
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
2022-10-19 06:25 AM
> TIM14_delay_us does not work
I still don't know what do you mean by "does not work" here.
JW
2022-10-19 07:56 AM
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
2022-10-19 08:09 AM
> 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
2022-10-21 12:47 AM
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);
}
2022-10-21 01:06 AM
At this point I have no more ideas.
JW
2022-10-21 01:10 AM
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