This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to design a precise delay function

Other Parts Discussed in Thread: MSP430F2619

Dear Friends,

I found many delay function in the example projects and the most of them are using  __delay_cycles(n).

I want to know how to define the variable n if I want to let it delay for 1 ms.  The microprocessor I used is MSP430F2619 and running with a 32.768KHz crystal.

Thank you.

Sunglin.

  • Hi Sunglin,

    In __delay_cycles(n), n = CPU cycles.  If you are sourcing MCLK (CPU clock) with a 32.768KHz crystal, then you can calculate the number of cycles needed to achieve a 1ms delay using __delay_cycles(n).

    1ms/(1/32.768KHz) = n

     

  • Sunglin Chen said:
    I want to know how to define the variable n if I want to let it delay for 1 ms.

    __delay_cycles generates code that does nothing for a given number of CPU cycles. So the value of n for a specific time delay depends on the current CPU speed.

    The code is generated at compile time, so it is a fixed delay and cannot be used for dynamic delays at runtime.

    Also, if there are interrupts, the execution tiem for any itnerrupt is added to the delay (as the delay depends on executing certain code, and the execution is of course stopped while an ISR runs)

    A good way to generate delays is by using a timer. Depending on size of the delay and speed of the timer, there are different ways.

    Personally, I always have a timer running with 1MHz clock (independent of CPU speed). The timer is conficured to trigger an interrupt every 1000 ticks (every 1ms). The ISR will increment a global counter that counts milliseconds and another one that counts seconds.

    For long delays with 1ms resolution (up to 65535ms), the code can just wait until the counter has advanced the required number of ms. for longer delays, the 1s counter cna be used with 1s resolution and delays up to 18hrs (if a word counter is used) or 136 years (if a long counter is used)

    This can be even expanded sao that the CPU is sent to LPM0 while it is waiting, and the timer ISR wakes it when thedelay has passed, saving some power.

    For precision short delays below 1ms (>12µs) I use another funciton that programs a CCR unit of this timer by setting CCR1 = TAR+n (n = delay in µs) and check for the CCIFG bit being set.
    Programming the CCR unit and calling the delay function limits this delay to at least 12µs (on 8MHz CPU clock, less on faster CPU), but gives µs precision.

    The big advantage on using a timer for the delay is that ISRs that execute during the delay won't affect the delay at all. Only if an ISR is executed when teh delay ends, then the end of the delay is stretched to the end of this ISR's execution.

  • Hi Jens-Michael,

    Thank you for your detailed explanation. I'll take a test according to your suggestions. Thank you again.

    Sunglin.

  • Hi,

    This is a function I've been using; it gives precise (well, as precise as your DCO) ms delays during which the CPU is put into LPM0, with TimerA. You do have to take into account the overhead of the instructions (20 cycles per ms + 24 static) and the interrupt latency (5 cycles entrance, 5 cycles to clear SR, 5 cycles to return).

    void timer_sleep_ms(int msec) {
    // change according to your SMCLK frequency
      TA0CCR0 = 16000;
      TA0CTL = TASSEL_2 + MC_2;
      for(int i = 0; i < msec; ++i) {
        TA0R = 0;
        TA0CCTL0 = CCIE;
    while(TA0R < 16000) {
         __bis_SR_register(LPM0_bits|GIE);
         __no_operation();
    }
      }
      TA0CTL = 0;
    }

    and of course this only works with the appropriate Timer ISR:

    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void Timer_A (void)
    {
      // wake on CCR0 count match
      TA0CCTL0 = 0;
      __bic_SR_register_on_exit(LPM0_bits|GIE);
    }

    Hope this is useful.

    Tony

    [edited to fix minor omission in code]

  • Dear Tony Kao,

    Thank you for your sample code. It is very useful to me and I will try it soon.

    Sunglin.

**Attention** This is a public forum