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.

MSP430g2553 Port2 Interrupt is missing

Other Parts Discussed in Thread: MSP430G2553

I am using MSP430g2553 chip. and I wrote the following small code to initialize and enable the port 2 interrupt. I have attached a 100HZ 1.25 volt square wave with 30 duty cycle to P2.0 and P2.1. I place break point in my interrupt handler. When I run the code my break point is never hit, it looks like some how the interrupt vector is not a correct ? .I also checked that against the msp430g2553.h.A response is highly appreciated.

void main(void) {

    static struct timeT timeFlash_FanCheck;
    //static struct timeT timeFanCheck;
    static int ADC_proc;

    //initialize peripheral and other
    WDTCTL=WDTPW+WDTHOLD;      //stop watchdog timer
    low_level_init();
     timera_init();
      //port 2 setup interrupt configuration


    P2SEL &= ~(BIT0+BIT1+BIT2+BIT3);
    P2DIR &=~(BIT0+BIT1+BIT2+BIT3);
    P2IFG=0x00;
    P2IES &=~(BIT0+BIT1+BIT2+BIT3);
    P2IE |=BIT0+BIT1+BIT2+BIT3;

_
    while(1)
    {

       //every 1 second call

         readFanSpeed();  //will use TachCount to measure the fan speed

}

// Fan Tach PORT2 Interrupt Service Routine
#pragma vector = PORT2_VECTOR
__interrupt void isrPORT2(void)
{
    _NOP();
    //configure port2 pins0,1,2,3 IE in low_level_init()
    if (P2IFG & TACH_FAN_1)        // Tachometer pulse detected ?
    {
        Fans[0].TachCount++;        // Increment tach counter
        P2IFG &= ~TACH_FAN_1;        // Clear interrupt flag
    }

    if (P2IFG & TACH_FAN_2)        // Tachometer pulse detected ?
    {
        Fans[1].TachCount++;        // Increment tach counter
        P2IFG &= ~TACH_FAN_2;        // Clear interrupt flag
    }

#if 0
    if (P2IFG & TACH_FAN_3)        // Tachometer pulse detected ?
    {
        Fans[2].TachCount++;        // Increment tach counter
        P2IFG &= ~TACH_FAN_3;        // Clear interrupt flag
    }

    if (P2IFG & TACH_FAN_4)        // Tachometer pulse detected ?
    {
        Fans[3].TachCount++;        // Increment tach counter
        P2IFG &= ~TACH_FAN_4;        // Clear interrupt flag
    }

#endif
}
 

   I will never get to the interrupt routine above to increment the tach signal.

  • Hi Hamid !

    In the example   "  MSP430G2xx3 Demo - Software Port Interrupt Service on P1.4 from LPM4 "

    there is a special line

      _BIS_SR(LPM4_bits + GIE);                 // Enter LPM4 w/interrupt

    Please, try that -- seems you need the GIE (general interrupt enable) in any case ...

    Have fun, Uli

  • hi,

     by the quick look at the code,,, it looks fine. there are few improvements can be done and as the other poster suggested you have forgot to enable interrupts before entering ion to infinite while loop.

    Hamid Khalessi said:
     P2SEL &= ~(BIT0+BIT1+BIT2+BIT3);
        P2DIR &=~(BIT0+BIT1+BIT2+BIT3);
        P2IFG=0x00;
        P2IES &=~(BIT0+BIT1+BIT2+BIT3);
        P2IE |=BIT0+BIT1+BIT2+BIT3;

    By default all ports in msp430 work in port configuration mode not in secondary functionality.  So no need to  configure P2SEL regs.

    By default all ports are inputs in msp so u only need to configure ports if they are outputs -----------P2DIR

    add this intrensic function before while loop and after P2IE configuration _enable_interrupts();        . I think u can c ISR being executed this time. If u dont c it, my advice would be pull any of pins 0,1,2,3 low and c weather ISR is entered.

    Regards,

    Sri.

  • Hi Sri,

    IT did not help. I could not get into the ISR for PORT2. I even pulled pin 2.0 low and hooked it to ground as you recommended but still my interrupt does not get hit.

    Regards,

  • Dr. Ulrich Kaiser said:
      _BIS_SR(LPM4_bits + GIE);                 // Enter LPM4 w/interrupt

    Well, GIE is right. IF GEI is not set, all interrupts are globally disabled, independent of their individual IE bits.
    However, setting LPM_bits too will stop the execution of the main thread until an ISR awakens it again. Which doesn't happen.

    _bis_SR_register(GIE) or _BIS_SR(GIE) or simply _EINT() or _enable_interrupt() (all do the same) is required before entering the while(1) loop.

    sri-sri said:
    there are few improvements can be done

    Indeed. One of them is to use the same nomenclature throughout the code.

    If (P2IFG& TACH_FAN_1) is use inside the ISR, then  P1SEL |= TACH_FAN_1 should be used for the configuration too (and not "BIT0"). Else if the definition of TACH_FAN_1 ever changes, the initialization will not change and cause a problem that is difficult to detect.

    However, there are more severe problems: inside the ISR currently the IFG bits for TACH_FAN_3+4 are not deleted. If such an interrupt occurs, the ISR will be called, do nothing, exit and then it will be immediately called again for all eternity (or until next reset/power off). Main will stop executing.
    If part of the ISR is deactivated, then part of the initialization (set appropriate IE bits9 should be deactivated too.

    Also, before setting the P2IE bits, P2IFG should be cleared. because there might be already some interrupts pending due to previous events or by changing the edge setting.

    Then,. with GIE set, it should work.

  • Hi,

    Thanks for ur reply.

    I have modified the code to include some of your earlier comments. But still,my break point inside the PORT 2 interrupt does not get hit.Thanks for your help and comments.

    The new code :

    #define TACH_FAN_1        BIT0
    #define TACH_FAN_2        BIT1

    #define TACH_FAN_INTS (BIT0+BIT1)

    void main(void) {

        static struct timeT timeFlash_FanCheck;
        //static struct timeT timeFanCheck;
        static int ADC_proc;

        //initialize peripheral and other
        WDTCTL=WDTPW+WDTHOLD;      //stop watchdog timer
        low_level_init();
        // Initialize UARTS
        usart0_init();
        timera_init();
        //adc_init();
        initFans();
        P3OUT |= BIT2;    //set to 1
        __bis_SR_register(GIE);
        P1DIR &= ~(BIT6+BIT7);                                // LED Column 0 and 1 off
        P2OUT |= BIT5;                                        // Row 0 off*, RS485 Status Red
        P2DIR |= BIT5;                                        // Row 0 set to output
        P3DIR &= ~(BIT2+BIT3);                                // Rows 2&3 high=off
        P3DIR |= BIT7;                                        // Column 2 Enable output
        P3OUT |= BIT7;                                        // LED Column 2 on
        P2DIR |= BIT4;
        P2OUT &= ~BIT4;                                        // Row 1*, RS485 Status Green
        timeFlash_FanCheck = getTime();
        ADC_proc=VICOR_TEMP;
        //port 2 setup interrupt configuration
        P2IFG=0x00;
        P2IES |= TACH_FAN_INTS;
        P2IE |=TACH_FAN_INTS;
        _enable_interrupts();

        _NOP();
        while(1)
        {

              if (timer(timeFlash_FanCheck,1000))
                {
                    timeFlash_FanCheck = getTime();
                    readFanSpeed();   //will process TACH variable incremented by port 2 interrupt
                    P2OUT ^= BIT4;                            // Row 1*, RS485 Status Green, toggle
                }

    }

    // Fan Tach PORT2 Interrupt Service Routine
    #pragma vector = PORT2_VECTOR
    __interrupt void isrPORT2(void)
    {
        _NOP();  //Deug only

        //configure port2 pins0,1,2,3 IE in low_level_init()
        if (P2IFG & TACH_FAN_1)        // Tachometer pulse detected ?
        {
            Fans[0].TachCount++;        // Increment tach counter
            P2IFG &= ~TACH_FAN_1;        // Clear interrupt flag
        }

        if (P2IFG & TACH_FAN_2)        // Tachometer pulse detected ?
        {
            Fans[1].TachCount++;        // Increment tach counter
            P2IFG &= ~TACH_FAN_2;        // Clear interrupt flag
        }
    }

  • Please, insert   a command before the NOP in order to toggle the LED.

    Can you see any changes at the LED ?

    rgds, Uli

  • HI,

    Hamid Khalessi said:
       _enable_interrupts();

    its _enable_interrupt();

             I have tested the port 2 interrupt part of ur code and it is working .when there is +3.3 v on any of P2.1 or p2.2 pin. It looks like default state of port2 pins in I/p is low.

    Regards,

    Sri.

  • I should read teh error description more carefully:

    Hamid Khalessi said:
    I have attached a 100HZ 1.25 volt square wave

    What is your supply voltage? The high-going input threshold voltage is between 0.45 and 0.75* VCC. So for VCC>=2.8V, your 1.25V input signal is considered low even for the best case. Worst case,1.25V are considered low even for VCC= 1.8V.

**Attention** This is a public forum