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.

issue with GPIO output

Other Parts Discussed in Thread: MSP430FG4618, MSP430F5438

Hello Sir,

I am using MSP430FG4618 experimental board for one application, which is using Timer and Comparator. I have turned on Timer in Comparator  ISR, but the duty cycle of the GPIO output is not stable. I am using 4MHz DCO clock. Should i have to modify code?

 A part of code is mentioned here:

#include <msp430.h>

int main(void)
{
unsigned char i;
WDTCTL = WDTPW+WDTHOLD; // Stop WDT
FLL_CTL0 |= (DCOPLUS + XCAP18PF);
SCFI0 |= FLLD_2 + FN_4;
SCFQCTL = 61;
do
{
IFG1 &= ~OFIFG;
for (i = 0x47FF; i > 0; i--);
} while ((IFG1 & OFIFG));

P3SEL |= 0x0F0; // P3 option select
P3DIR |= 0x0F0; // P3 outputs
P5DIR |= BIT1;
P5OUT |= BIT1;

TBCCR0 = 40000-1;
TBCCTL3 = OUTMOD_7; // CCR3 reset/set
TBCCR3 = 30000; // CCR3 PWM duty cycle
TBCCTL4 = OUTMOD_7; // CCR4 reset/set
TBCCR4 = 20000; // CCR4 PWM duty cycle
TBCCTL5 = OUTMOD_7; // CCR5 reset/set
TBCCR5 = 10000; // CCR5 PWM duty cycle
TBCCTL6 = OUTMOD_7; // CCR6 reset/set
TBCCR6 = 5000; // CCR6 PWM duty cycle

TBCTL |= TBSSEL_2;

CACTL1 = CAON | CAREF_2 | CARSEL; // enable comp, Vref = diode reference voltage
CACTL2 = P2CA0;
CACTL1 |= CAIE;

_EINT();
}

#pragma vector=COMPARATORA_VECTOR
__interrupt void Comp_A_ISR (void)
{
TBCTL |= MC_1;
P5OUT &= ~BIT1;
CACTL1 ^= CAIES;
}

Thanks.

  • First of all, after doing your init work, your main code returns into nowhere. Add a while(1) loop at the end, or enter LPM0, but never return from main. It is totally undefined (and compiler/linker dependent) what may happen then. There is no OS you could return to. Main wasn't called as a function from anywhere, so there isn't a return address on the stack. So anyhting might happen, and something different on a different compiler.

    That being said, I mus ttell you that I don't see the reason why you enable the timer in teh comparator ISR. Sure, you wait until the omparator triggers first time, but then the timer continues. YOu never deactivate it or such, even though you toggle comparator edge and an output LED (?) on each ISR call.

    Well, it would be interesting what you mean with "not stable"? Does it dance samba? Or does it jitter alittle bit?
    Note that the DCo uses modulation to achieve an average target frequency. So it switches between two different frequencies. Also, the FLL changes this modulation pattern on each reference tick (unless by coincidence you get an exact match, whcih is highly unlikely, especially since the DCO drifts with temperature).
    So a small jitter on the duty cycle is to be expected. Only if using a 4MHz crystal, you'lll get a virtually jitter-free clock.

  • Hello Sir,

    Thank you for the reply.

    Actually I want to make a triac controlled regulatory application, there is an A.C. pulse zero cross detection circuitry whose output triggers the comparator and for synchronizing i have triggered timer in comparator ISR, but the duty cycle of the GPIO output is varying.

    Code modification is shown here:

    #include <msp430.h>

    volatile unsigned char count_one_ms = 0;
    volatile unsigned char Zerocross_flag = 0;

    void timer_init(void)
    {
    TBCCR0 = 4000;
    TBCTL = TBSSEL_2;
    TBCCTL0 = CCIE;
    }

    void comp_init(void)
    {
    CACTL1 = CAON | CAREF_2 | CARSEL;
    CACTL2 = P2CA0;
    CACTL1 |= CAIE;
    }

    int main(void)
    {
    unsigned char i;
    WDTCTL = WDTPW+WDTHOLD; // Stop WDT
    FLL_CTL0 |= (DCOPLUS + XCAP18PF);
    SCFI0 |= FLLD_2 + FN_4;
    SCFQCTL = 61;
    do
    {
    IFG1 &= ~OFIFG;
    for (i = 0x47FF; i > 0; i--);
    } while ((IFG1 & OFIFG));

    P5DIR |= BIT1;
    P5OUT |= BIT1;

    timer_init();
    comp_init();
    _EINT();

    while(1)
    {
    if(Zerocross_flag)
    {
    Zerocross_flag = 0;
    }
    }
    }

    #pragma vector=TIMERB0_VECTOR
    __interrupt void RegulationTimer (void)
    {
    if(count_one_ms > 3)

    {
    P6OUT &= ~BIT0;

    }

    count_one_ms++;
    }

    #pragma vector=COMPARATORA_VECTOR
    __interrupt void Comp_A_ISR (void)
    {
    P6OUT |= BIT0;
    TBCCR0 = 4000;
    TBCTL = MC_1;
    Zerocross_flag = 1;
    }

  • Hello Sir,

    I have tried with 4MHz crystal, still there is some changes in duty cycle of GPIO pins, so that lamp regulation is not happening properly. I wants to know, there is same problem with MSP430F5438 or not?

  • Akshat Saraf said:
    TBCCR0 = 4000;

    Perhaps you mean 3999? In up mode, the overflow from CCR0 to 0 is another tick, so if you count form 0 to 4000, then the cycle length is 4001 timer ticks.

    Akshat Saraf said:
    if(count_one_ms > 3)

    I don't see you resetting count_one_ms anywhere. However, it will overflow after 256 timer interrupts. Effectively, it will not reset P6.0 for the first three timer interrupts, then on every timer interrupt until the counter overflows.
    While the comparator will set the bit on each comparator interrupt. Doesn't seem to make much sense this way.

    Akshat Saraf said:
    TBCTL = MC_1;

    THis sets the tiemr in cont mode (doN't see you setting it back to anythign else anywhere), bu talso clears all other bits in TBCTL register, such as the clock selection. So the timer is switched to (external) TBCLK and not running on SMCLK anymore. I'm surprised you'll get a timer interrupt at all.

    Apparently you want to start the timer when a comparator interrupt appears, and trigger the output. Then after three timer interrupts, reset the trigger.

    I suggest trying

    __interrupt void Comp_A_ISR (void)
    {
      P6OUT |= BIT0;
      TBCCR0 = 4000;  already set in init
      TBCTL |= MC_1 | TACLR; // switch timer to up mode and reset the current timer count
      Zerocross_flag = 1;
    count_one_ms = 0;
    }
    __interrupt void RegulationTimer (void)
    {
      if(count_one_ms > 3)
      {
        P6OUT &= ~BIT0;
        TBCTL &= (~MC_1); // stop the timer
      }
      else
        count_one_ms++;
    }


**Attention** This is a public forum