Skip to main content
raducara
Associate
February 22, 2013
Question

Delay function with timer

  • February 22, 2013
  • 6 replies
  • 1998 views
Posted on February 22, 2013 at 09:12

Hi, 

I am trying to make a simple delay function using a timer but i get weird results .

Here is some of the code 

void TIMERS_init(){

  

TIM3->PSC = 23999; // f timer = fclk / 24000 => 1kHz

TIM3->ARR = 0xFFFF;

TIM3->CR1 = TIM_CR1_CEN;

DBGMCU->CR = DBGMCU_CR_DBG_TIM3_STOP;

}

void Delay_ms(uint16_t ms){

TIM3->CNT = 0;

while (TIM3->CNT < ms){}

}

while(1){

GPIOC->ODR ^= GPIO_ODR_ODR8;

Delay_ms(500); //delay 0.5 sec

GPIOC->ODR ^= GPIO_ODR_ODR8;

Delay_ms(500); //delay 0.5 sec

}

The while in main is to test that the blue LED blinks at 2 Hz .

I am using keil 4 . In debug if i run step by step works fine , but in continuously run the LED is half bright (probably is on and off at a high frequency) . I can't understand why because the prescalar remains set .
    This topic has been closed for replies.

    6 replies

    Tesla DeLorean
    Guru
    February 22, 2013
    Posted on February 22, 2013 at 09:35

    On a VL-Discovery board? Or something else?

    Did you enable the TIM3 clocks? What frequency do you see on a scope?

    Post sufficiently complete examples if you want support.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    raducara
    raducaraAuthor
    Associate
    February 22, 2013
    Posted on February 22, 2013 at 11:17

    STM32-discovery with 32F100 uc .

    Yes , i enabled the timer clk . I don't have a scope .

    ________________

    Attachments :

    Source_Code.rar : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HznG&d=%2Fa%2F0X0000000bSo%2Fh4gOY5ZIGYHyrBe2m.y.Wpc3kVJPeaQah9GXtNCJMaw&asPdf=false
    raducara
    raducaraAuthor
    Associate
    February 22, 2013
    Posted on February 22, 2013 at 12:27

    void Delay_ms(uint16_t ms){

    TIM3->ARR = ms;

    TIM3->CNT = 0;

    while((TIM3->SR & TIM_SR_UIF)==0){}

      TIM3->SR &= ~TIM_SR_UIF;

    }

    I did some changes and works fine now , but i can't understand why it didn't work the previous version .

    Tesla DeLorean
    Guru
    February 22, 2013
    Posted on February 22, 2013 at 19:24

    void Delay_ms(uint16_t ms)
    {
    uint16_t start = TIM3->CNT; // assumes struct is volatile
    while((TIM3->CNT - start) < ms);
    }

    Arguably a better solution would be to meter in micro seconds, and have a smaller prescaler.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    zhoupn138
    Associate
    March 1, 2013
    Posted on March 01, 2013 at 21:18

    This delay function needs to take care of the case when there is an overflow in the counter, i.e., TIM3->CNT wraps around.

    Tesla DeLorean
    Guru
    March 1, 2013
    Posted on March 01, 2013 at 22:09

    This delay function needs to take care of the case when there is an overflow in the counter, i.e., TIM3->CNT wraps around.

    Actually it does. It might have issues if you exceed the scope (ie >65.535 Seconds), but is otherwise sound.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..