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.

ask some question about TimerA

Other Parts Discussed in Thread: MSP430F2274

Hi friends,

I want to triggle LED every 1s with ACLK, up mode. However, I cannot enter into TimerA ISR. What's wrong?

int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
 
  P1DIR |= 0x01; // P1.0 output 

 TACTL = TASSEL_1 + TACLR;
  TACCTL0 = CCIE;                           // TACCR0 interrupt enabled
  TACCR0 = 32768-1;
  TACTL |= MC_1;               // ACLK, upmode
 
 __enable_interrupt();
 // __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3 w/ interrupt
 
  return 0;
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  P1OUT ^= 0x01;                            // Toggle P1.0 
}

 

Thank you for your help.

Suning

  • Hi

     

    The code is correct.

    You compile it with IAR? Verify if you are in simulate mode.

    If you do not enter in LPM3 please remove the "return (0);" instruction and put "while(1);"

     

    Best regards AES

  • Thank you for your help. Unfortunately, it does not work yet.

    I use IAR.

    I have removed return(0), and write while(1) instead.

    Actually, I checked some sample code from slac123,  most of sample use __bis_SR_register(LPM3_bits + GIE);

     

    if I use so, what should I change?

    Thank you

  • Can you give me more details about the hardware that you are using?

     

    Also:

    Confirme that IAR is in FET Debuger mode.

    Then download code to MSP430 and put the cursor in code line

        P2OUT ^= 0x02;                            // Toggle P1.0

    inside the Timer A0 interrupt service routine, then goto Debug > Run to Cursor. Execution will stop inside ISR.

    I tested your code with IAR and works fine.

     

    int main( void )
    {
      // Stop watchdog timer to prevent time out reset
      WDTCTL = WDTPW + WDTHOLD;
     
      P2DIR |= 0x02; // P2.1 output

      TACTL = TASSEL_1 + TACLR;
      TACCTL0 = CCIE;                                 // TACCR0 interrupt enabled
      TACCR0 = 32768-1;
      TACTL |= MC_1;                                   // ACLK, upmode
     
      __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3 w/ interrupt
     
    }

    // Timer A0 interrupt service routine
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
      P2OUT ^= 0x02;                                 // Toggle P1.0
    }

     

    AES

     

     

     

  • I tried to your recommendation. It does not work.

    I use EZ430 RF2500, family 2274.

     

    I really have no idea about that.

     

  • Hi,

    I know my problem sounds easy. however, I don't know why I cannot let TimerA work well.

    even if I download the sample code from slac123, and refer to the code to write my own code, it cannot work yet.

     

    I really need your help.

    btw:I try to the ez430-RF2500 demo about temp sensor. this code can run to TimerA ISR. I cannot find the difference between demo code and mine.

     

    Thank you very much

     

  •  

     

    It realy sounds like you're using the simulator and not the actual hardware. The simulator doesnt emulate a runnung timer, so you will never reach your TA_ISR.

    Rightclick on your Project and choose Options/Debuggger to activate the Hardware.

     

  • I have chosen the FET debugger not simulator.

     

    when I tried Demo code, the TimerA works well, so I guess my problem is related to project configuration.

    Code is almost the same

     

  • Hi

    I am using CCE v3.2 with the FET debugger and have a similar issue.  I have TimerA0 configured with a #pragma vector = TIMERA0_VECTOR for the ISR.  However, when I step through the code, the ISR is never executed.  TAR counts past TACCR0 without the ISR executing.  The interrupt should still execute despite being in debug mode correct?

  • I've also found that the ISR is only executed when I place a breakpoint within the ISR.  Otherwise the ISR does not execute.  Very strange.

  • I had a look at this post a while ago and think I've just found the solution!

    First, the MSP430F2274, as far as I know, does not have a second, external lower frequency crystal, instead the auxillary clock (ACLK) is sourced from the very low power, low frequency internal osciallator - the VLO.

    Here's some code that I've got working:

     

    void main(void)
    {  
       long clkFreq = 12000UL / 2;               // VLO ~= 12 kHz
       long freq = 1;                            // 1 Hz
       long count = (clkFreq / freq) - 1L;
           
       WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

       P1DIR |= 0x01;                            // Set P1.0 as output

       BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
       DCOCTL = CALDCO_1MHZ;
       BCSCTL3 |= LFXT1S_2;                      // LFXT1 = ACLK = VLO
     
       TACCTL0 = CCIE;                           // TACCR0 interrupt enabled
       TACCR0 = count;

       TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode
      
       __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
    }

    // Timer A0 interrupt service routine
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
      P1OUT ^= 0x01;                            // Toggle P1.0
    }

    I've highlighted the vital piece of code that sets the ACLK equal to the VLO.

    Hope this helps!

    Regards,

    Derek

  • Your solution to use the VLOCLK for ACLK is correct when using the eZ430-RF2500 development kit.
    The MSP430F2274 does support the external crystal connection through XIN/XOUT pair, however, the eZ430-RF2500 does not have an external 32.768KHz crystal on the target RF board where the MSP430F2274 is used.  Instead, it brings those pins to the General Purpose connector on the board.

    This would explain why selecting ACLK intially did not work and the modifications provided by DerekC are necessary.

  • Brandon,

    Thanks for the clarification. I think I should have said that the eZ430-RFxxxx does not have an external 32768 Hz crystal. ;-)

    So, if a 32768 Hz clock is not connected to a MSP430x2xx MCU (such as on the eZ430), this code routes the VLO to the ACLK.

    For more information, have a look at Chapter 5 in the MSP430x2xx Family User’s Guide, SLAU144E.

    Derek

  • I have another question, if i can count the timier A and compare which the main.. example

     

     

    #include "msp430x22x4.h"

    volatile unsigned int i;                    // volatile to prevent optimization

    volatile unsigned int j;                    // volatile to prevent optimization

    void main(void)

    {

      i==0;

      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

      P1DIR |= 0x03;                            // P1.0 output

      TACCTL0 = CCIE;                           // TACCR0 interrupt enabled

      TACCR0 = 50000;

      TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode

     

     __bis_SR_register(CPUOFF + GIE);      // LPM0 with interrupts enabled

     

    while(1)  

     {

    j=j+1;

      }

    }

    #pragma vector=TIMERA0_VECTOR

    __interrupt void Timer_A(void)

    {

      P1OUT ^= 0x01;                            // Toggle P1.0

      TACCR0 += 50000;                          // Add Offset to TACCR0

       i=i+1;

        if (i==10 && j==i)

      {

        P1OUT ^= 0x02;                          // Toggle P1.0 using exclusive-OR

                      

        

       }

       if (i==20 )

      {

        P1OUT ^= 0x02;                          // Toggle P1.0 using exclusive-OR

                                     

          

       }

    }

     

    The problem is the rutine to compare i which j [:(]

     

     

     

  • I assume this is just an example to understand why the variable j is not incrementing, correct?

    Based on this code, I would guess that your main() function never reaches the :

    while(1)
    {
      j=j+1;
    }

    The reason why I say this is that you place the CPU into the LPM0 mode, which turns of the CPU and MCLK.  The CPU will go into an idle state at the end of that instruction.  When you get a TimerA interrupt, the CPU will wake up and execute the interrupt service routine, which increments variable i.  But when you return from the interrupt service routine, you have not done anything with the SR register currently on the Stack which holds the state of the CPU when it pops off the stack at the end of the interrupt service routine.  Therefore, the original SR register will be restored and the CPU will go back to the LPM0 state.

    If you want the CPU to remain active after the ISR has finished, then you need to add the following at the end of Timer_A().

    __bis_SR_register_on_exit(CPUOFF)

    However, if you want to go back to the LPM0 after incrementing j, then you need to augment your while(1) loop as such:

    while(1)
    {
      j=j+1;
     __bis_SR_register(CPUOFF + GIE);      // LPM0 with interrupts enabled
    }

     

    Give this a try.

  • supercuate,

     

    May I ask what you are trying to do?

    With Brandon's implementation j will always equal i, therefore the condition j==i will always be true and the LED will toggle when i == 10 and when i == 20.

    Also I notice j is not initialised.

     

    Derek

**Attention** This is a public forum