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.

Comparator Interrupt

Other Parts Discussed in Thread: MSP430G2553

Hi,

I am using the MSP430G2553 launchpad and am trying to write a code that continuously checks the comparator input CA1 with the reference (0.5 VCC). If the CA1 is higher than the reference the on board Green LED (P1.6) turns on for 2400 cycles (200ms as I am using the VLO). 

It looks like there is some issue with the 'if' condition in the pragma vector block. It looks like the interrupt is detected every time the voltage on Pin 1.1 crosses the reference,and the value of the CAOUT in the CACTL2 register also changes correctly. However, the green LED stays on once turned on regardless of the input at CA1. I would appreciate any feedback on this.

Here is the code:   

#include <msp430g2553.h>

#ifndef TIMER0_A1_VECTOR
#define TIME0_A1_VECTOR TIMERA1_VECTOR
#define TIMER0_A0_VECTOR TIMER0_VECTOR
#endif

void registerFault(void);
void clockConfig(void);
void configPins(void);
void comparatorSetup(void);

/*
* main.c
*/
void main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
clockConfig();
configPins();
comparatorSetup();

while(1)
{
_bis_SR_register(LPM3_bits + GIE);
}
}

void registerFault(void)
{
P1OUT = BIT0;
while(1);
}
void clockConfig(void)
{
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
registerFault(); // If calibration data is erased
// run FaultRoutine()
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO select VLO as low freq clock
IFG1 &= ~OFIFG; // Clear OSCFault flag
BCSCTL2 |= SELM_0 + DIVM_3 + DIVS_3; // MCLK = DCO/8, SMCLK = DCO/8
TACTL = TASSEL_1 + MC_2; //Configure timer A for ACLK and continuous mode
}

void configPins(void)
{
P1DIR = ~BIT1;
P1OUT = 0;
}

void comparatorSetup(void)
{
CACTL1 = CAREF_2 + CARSEL + CAIE;
CACTL2 = P2CA4 + CAF;
CAPD = CAPD1;
CACTL1 |=CAON;
}

#pragma vector = COMPARATORA_VECTOR
__interrupt void COMPA_ISR(void)
{
if((CACTL2 & CAOUT)==0x01)
{
P1OUT=BIT6;
_delay_cycles(2400);
}
else
{
P1OUT=0;
}
}

  • Anyone have any ideas about how to proceed on debugging this one?

  • hi,

    when you post code, plz use insert code icon present in editor. It will make it easy for others to review your code.

  • IIRC, the comparator ISR is only called when the voltage exceeds the threshold for the first time. It is NOT called when the input goes back below the threshold. And it needs to go below so another interrupt is triggered in case it goes up again.
    So your ISR is called each time the voltage rises above the threshold. Then it switches the LED on and wastes 2400 clock cycles and exits. Since it is never called when the voltage drops, the LED is never switched off.
    Quick hack:
    - switch the LED off after the delay. You’ll likely see it shortly blinking once as soon as your input rises above the threshold, and then again only when you lower the input and raise it again.
    - invert the LED state on every interrupt. So each time you go below and again above the threshold, the LED will change state.

    The final solution would be to change the edge detection in the ISR - once you have detected a rising edge, in the ISR change the comparator configuration to detect the falling edge and vice versa.

**Attention** This is a public forum