cancel
Showing results for 
Search instead for 
Did you mean: 

Again Microsecond timer on STM32C011F6U6

Sergii Volchenko
Associate III

Hi,

I tried to reach 1us delay. To do that I use a timer on 1MHz and try to reach more or less precision delay.

 

void delayMicro(uint16_t delayMc) {
    __HAL_TIM_SET_COUNTER(&htim16,0);  // set the counter value a 0
    while (__HAL_TIM_GET_COUNTER(&htim16) < delayMc);
}
    HAL_TIM_Base_Start(&htim16);
    while () {
        delayMicro(100);
        HAL_GPIO_TogglePin(OUT1_GPIO_Port, OUT1_Pin);
    }

 

SergiiVolchenko_2-1710415105639.png

 

SergiiVolchenko_0-1710414975564.png

And the result is always desired delay+6-8us

SergiiVolchenko_1-1710415059317.png

Even if I set delay = 1us, I get 7-8us.

I did something wrong or is this GPIO or microcontroller limitation?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> And the result is always desired delay+6-8us

Overhead. Your timer has a precision of 1us, so expect some jitter due to that.

7us on a 12 MHz chip is 84 ticks. That's not a lot. You're jumping/returning to a function, dereferencing pointers, accessing registers. Likely compiling under Release mode would do much better. Using direct register access will help a bit.

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

View solution in original post

8 REPLIES 8

You don't show any of the TIM initialization code.. check prescaler, check clocking via MCO pin.

You don't want to have interrupts.

Perhaps easier to delta the TIM16->CNT than keep resetting

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

>I did something wrong or is this GPIO or microcontroller limitation?

You did more than something wrong.

If you feel a post has answered your question, please click "Accept as Solution".
 htim16.Instance = TIM16;
  htim16.Init.Prescaler = 11;
  htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim16.Init.Period = 65534;
  htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim16.Init.RepetitionCounter = 0;
  htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

And I don't use interrupt for this timer.

SergiiVolchenko_0-1710416189625.png

Implementing delta for CNT didn't help.

TDK
Guru

> And the result is always desired delay+6-8us

Overhead. Your timer has a precision of 1us, so expect some jitter due to that.

7us on a 12 MHz chip is 84 ticks. That's not a lot. You're jumping/returning to a function, dereferencing pointers, accessing registers. Likely compiling under Release mode would do much better. Using direct register access will help a bit.

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

Yeah, I think the same but hope that I'm wrong. :)

Strange but even on 48MHz and release build I got 102uS instead 100us.

96 ticks of overhead is consistent with what you saw at 12 MHz clock.

I would guess about half of the overhead is within HAL_GPIO_TogglePin itself.

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

My belated thoughts -

Agree with Tesla, don't bother resetting the counter, just use it as a reference and compare it with a register/variable with a delta added to it.

If these things are critical, I would be doing something in assembler to minimise overheads (including loop overheads).