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.

Error in Timer

Other Parts Discussed in Thread: MSP430G2553

Hi, I need to produce a timer in which P1.0  and P1.6 will turn on/off  alternately every 1 sec. I already made a program and I can't seem to get my desired output. Can anyone be able to help? 

This is my program:

#include <msp430g2553.h>
int i;
void main(void){
WDTCTL = WDTPW + WDTHOLD; //Stop Watchdog Timer
P1DIR |= 0x41; //Setting P1.0 and P1.6 as output direction
CCTL0 = CCIE; //Enable CCR0 interrupt
CCR0 = 32768; //32768/32768=1Hz
TACTL = TASSEL_1 + MC_1; //ACLK,UPMODE
i=0;
while(1){
_BIS_SR(GIE); //enter LPM0 with interrupt
if (i<2) //turn LED1 on and turn off LED2 for 1sec.
{P1OUT = 0X01;}
if (i>2) //turn on LED2 and turn off LED1 for 1sec.
{P1OUT = 0X40;}
if (i==3)
{i=0;}
}}

//timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{i++;}

  • "int i;" should be "volatile int i;" so main sees the changes from the ISR.

    Do you have a 32kHz crystal installed on your board? As I recall, the crystal is not pre-installed on the G2 Launchpad, though there may be one floating around in the box.

  • Thank you very much for helping. However, I still don't get my desired output even though i already did as you suggested. I did have a crystal oscillator soldered in my launchpad which is already included in the box when I bought it and I still get the same problem. The LED1 just kept on as an output and it won't change to LED2. Any suggestions? I am still new in MSP430 though. I'll be very glad for the help. Thanks.
  • Sorry, I missed this before: You have 3 cases: (i<2), (i>2), (i==3). After the third interrupt, i becomes both >2 and ==3, so you turn on LED2 but then set i=0 (so it is then <2), and so immediately switch back to LED1 before you can see LED2 lit.

    You probably want to either test for (i>=2)[2nd case] or (i==4) [3rd case] so there's a visible time gap where LED2 is lit.
  • It still doesn't work. I even change different values of i on the three cases but it still doesn't work. What must be wrong?
  • Crystals can be finicky.
    SMCLK (running from the DCO) is pretty reliable, but it's running pretty fast (~1MHz). But if you set

    TACTL = TASSEL_2 | ID_3 | MC_1; // SMCLK/8, Up mode

    it should cycle at 1MHz/8/32768 or about 4 times per second. The LEDs should then blink twice per second -- long enough to see, at least.
    If this works, then you should probably check the crystal solder joints. (Sometimes putting your finger on the crystal solder pads will add enough capacitance to make the crystal run. Or not, but it only takes a few seconds to try it.)
  • Thanks. You were right. I made 2 programs, one with the SMCLK and another with ACLK, in which both have satisfied me for my desired output . Using SMCLK, I was able to produce alternating delay on each LED with almost 1s delay. In another program using ACLK, you were right that the crystal might be the problem so I give it a push and tried to work on my first program and made some editing. Please have a look on my programs if you still have something to add?

    ************************************Here is my code with the use of SMCLK: *******************************************
    #include <msp430g2553.h>
    volatile int i;
    void main(void){
    WDTCTL = WDTPW + WDTHOLD; //Stop Watchdog Timer
    P1DIR |= 0x41; //Setting P1.0 and P1.6 as output direction
    CCTL0 = CCIE; //Enable CCR0 interrupt
    CCR0 = 16384;
    TACTL = TASSEL_2 | ID_3 | MC_1; // SMCLK/8, Up mode
    i=0;
    while(1){
    _BIS_SR(GIE); //enter LPM0 with interrupt
    if (i<=7) //turn LED1 on and turn off LED2 for 1sec.
    {P1OUT = 0X01;}
    if (i>7) //turn on LED2 and turn off LED1 for 1sec.
    {P1OUT = 0X40;}
    if (i==14)
    {i=0;}
    }}

    //timer A0 interrupt service routine
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void Timer_A(void)
    {i++;}


    *************************************Here is my code using ACLK: ***************************************************************
    #include <msp430g2553.h>
    volatile int i;
    void main(void){
    WDTCTL = WDTPW + WDTHOLD; //Stop Watchdog Timer
    P1DIR |= 0x41; //Setting P1.0 and P1.6 as output direction
    CCTL0 = CCIE; //Enable CCR0 interrupt
    CCR0 = 16384; //32768/32768=1Hz
    TACTL = TASSEL_1 + MC_1; //ACLK,UPMODE
    i=0;
    while(1){
    _BIS_SR(GIE); //enter LPM0 with interrupt
    if (i==1) //turn LED1 on and turn off LED2 for 1sec.
    {P1OUT = 0X01;}
    if (i==2) //turn on LED2 and turn off LED1 for 1sec.
    {P1OUT = 0X40;}
    if (i==2)
    {i=0;}
    }}

    //timer A0 interrupt service routine
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void Timer_A(void)
    {i++;}
  • I made another program that is more accurate and reliable than my previous programs using SMCLK since I don't have to worry about the crystal being faulty at times.

    Here is my program that will have an output of 2 LEDS blinking alternately every 1 sec.:
    #include <msp430g2553.h>
    volatile int i;
    void main(void){
    WDTCTL = WDTPW + WDTHOLD; //Stop Watchdog Timer
    P1DIR |= 0x41; //Setting P1.0 and P1.6 as output direction
    CCTL0 = CCIE; //Enable CCR0 interrupt
    CCR0 = 65535; //(65535*8)/1.1MHz=0.48s
    TACTL = TASSEL_2 | ID_3 | MC_1; // SMCLK/8, Up mode
    i=0;
    while(1){
    _BIS_SR(GIE); //enter LPM0 with interrupt
    if (i<2) //turn LED1 on and turn off LED2 for 1sec.
    {P1OUT = 0X01;}
    if (i>=2) //turn on LED2 and turn off LED1 for 1sec.
    {P1OUT = 0X40;}
    if (i==4)
    {i=0;}
    }}

    //timer A0 interrupt service routine
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void Timer_A(void)
    {i++;}
  • You did very well.

    My only comment is about one of your comments. You said: "_BIS_SR(GIE); //enter LPM0 with interrupt". The comment there is not correct.

    By the way there is another clock source, VLOCLK, which is reliable but the frequency varies wildly from chip to chip and there is a strong dependence on operating voltage and temperature. Here is a slightly modified version of your code.

    #include <msp430g2553.h>
    
    void main(void){
      BCSCTL3 = LFXT1S_2; //ACLK = VLO
      WDTCTL = WDTPW + WDTHOLD; //Stop Watchdog Timer
      P1DIR |= 0x41; //Setting P1.0 and P1.6 as output direction
      CCTL0 = CCIE; //Enable CCR0 interrupt
      CCR0 = 12000; //may need adjustments to get closer to 1 second
      TACTL = TASSEL_1 | MC_1; //ACLK/1, Up mode
      P1OUT = 0x40; //P1.6 on P1.0 off
      _BIS_SR(GIE|LPM3_bits); //enter LPM3 with interrupt
      while(1){
      }
    }
    
    //timer A0 interrupt service routine
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void Timer_A(void){
      P1OUT ^= 0x41; //flip both P1.6 and P1.0
    }

  • Thank you very much for correcting. Does VLOCLK also needs cystal oscillator to run?
  • No, it is entirely on the chip itself. See User's Guide slau144j.pdf

**Attention** This is a public forum