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.

Timer A 1us Interrupt

Other Parts Discussed in Thread: MSP430F2132

Hi All,

I need to configure Timer A to generate an interrupt every 1us to provide a system tick.  Currently i am just toggling a pin but the end purpose is, system tick.

I only have an external 32.768KHz crystal.

I am using the MSP430F2132 under CCS.

Here is my code:

void clocks_config(void)
{
    BCSCTL1 = CALBC1_16MHZ;
    DCOCTL = CALBC1_16MHZ; 

}

void timer_a_conif(void)

{

    WDTCTL = WDTPW + WDTHOLD;               
    TACCTL1 = CCIE;                                                                 // TACCR1 interrupt enabled
    TA0CCR0 = 16;                                                                     // Tclk = 1/16MHz = 6.25E-8  hence 1us = 1E-6/6.25E-8 = 16
    TA0CTL = TASSEL_2 + ID_0 + MC_1 + TAIE;                 // SMCLK, 1:1 , Up to CCR0, Interrupts enabled

    __bis_SR_register(GIE);       // Enter LPM0 w/ interrupt
}

#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A_ISR (void)
{
    P1OUT ^= 0x02;
}

Currently i am getting into the interrupt every 15us.

Can anyone help me out here?

Thanks

  • Hi,

    you basically assign the wrong interrupt vector and also initializing the wrong register. If you want to use CCR0 interrupt try:

    void timer_a_conif(void)

    {

        WDTCTL = WDTPW + WDTHOLD;                
        TACCTL0 = CCIE;                                                    // TACCR0 interrupt enabled
        TA0CCR0 = 16;                                                        // Tclk = 1/16MHz = 6.25E-8  hence 1us = 1E-6/6.25E-8 = 16
        TA0CTL = TASSEL_2 + ID_0 + MC_1;                 // SMCLK, 1:1 , Up to CCR0, Interrupts enabled

        __bis_SR_register(GIE);       // Enter LPM0 w/ interrupt
    }

    and

    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void Timer_A_ISR (void)
    {
        P1OUT ^= 0x02;
    }

  • Hi Leo,

    Thanks for your response and corrections.

    This only produces an interrupt every 18us and not the 1us i am seeking.

    Could this be down to the value i load into the TACCR0 register?

  • Hi,

    although the solution above might work, i am not sure that it is a good idea to use software to generate the signal. The reason is only the the interrupt setting will consume almost all of the CPU performance.

    This is the rought estimation:

    - The CPU frequency is 16 MHz which means you have 16 cycles per 1 us.

    - The interrupt acceptance is 6 cycle

    - The P1OUT ^= 0x02, would consume about 4 cycles.

    - The RETI instruction executed at the end of ISR will consume 5 cycles

    So you lose 15 cycles out of 16 cycles per 1 us only to process the interrupt.

    I would strongly suggest you to use the hardware solution for this. You can use e.g. P1.1 on MSP4302132 as the T0.0 or P1.2 as TA0.1 to generate PWM output wihtout any CPU intervention.

    PS: without testing it, i think the code above should work. However it depends whether your application has another interrupt which might add the latency to the timer interrupt, or depending which instruction is executed in the remaining 1 cycle you have, you might also add the delay to the interrupt execution. So again, please use the hardware timer to generate PWM signal.

  • Leo,

    This is just for a 1us system tick.

    I want to enter the ISR every 1us where i can then increment a 'tick' variable.

    What way would you recommend?

  • Hi Sputnik,

    are you trying to make a scheduler or operating system?

    I still don't think that the MSP430 can cope with the 1us interrupt. 

    One alternative that i can think of is to use the TAR timer count register as your system tick variable. You can just supply the 8MHz SMCLK divided 8 (IDx bit of TACTL set as 11), and let the timer run in continuous mode. However your system tick is then limited to 16 bit.

    Let's see whether the rest of the forum might have another idea.

  • Sputnik said:
    This is just for a 1us system tick.
    I want to enter the ISR every 1us where i can then increment a 'tick' variable.

    Some simple math:

    CPU cycles needed to enter and exit an ISR: 11. Cycles needed to increment a global variable: 4. If done every µs, this means 15 CPU cycles/µs are required for this interrupt. Or in other words, the MSP running on 15MHz would be 100% busy.

    Baaaad idea :)

    Hoever, as already suggested: the timer can count 1MHz pulses in harware, giving you a 16 bit count of µs. All you need to do is counting tiemr overflows and you have a 32bit µs count.

    To trigger events at a certain count, things are more difficult. You'll need ot triger compare interrupts at  acertain timer count to trigger the scheduled jobs.

  • Do you want to vote for you on Nov 6 ;)

  • Thanks Jens-Michael Gross for bringing that to my attention.

    I have now implemented my Timing by r/w the TAR register as Leo suggested also.

    I am now trying to get my MCLK configured correctly...by that's a different thread.

    Cheers.

**Attention** This is a public forum