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.

MSP430F2132: Interrupção

Part Number: MSP430F2132
Other Parts Discussed in Thread: MSP430G2553
Hi!
So I locked it up again in the codes, I already researched a lot, but there is always something missing. Again I will need helps; )
 This code below works reasonably well, (there are times when I press the button, be it S1 or S2 and I get no response), but I do not want to worry about this now.
 The action is very simple, it starts with the LEDs on, pressing one of the buttons the LED turns off (corresponding to that button), here is the code:
     #include <msp430G2553.h>
 
         void main(void)
         {
         volatile unsigned int i;
         WDTCTL = WDTPW+WDTHOLD;        // Desliga Watchdog Timer
         P1DIR  |= BIT0 + BIT6;                       // P1.0 e P1.6 como Saída, os demais entradas
         P1OUT  &= ~BIT0 + BIT6;                  // P1.0 e P1.6  como Desligado
         P1REN  |= BIT1 + BIT3;                    // Habilita Pull-up no botão P1.3 e P1.1
 
          while(1)                                       // Loop Infinito
             {
               if ((P1IN & BIT3)==0)                 // Se  botão S1 está em 0
    
                P1OUT &= ~BIT0;              //Apaga Led 1 (Vermelho)
                     else 
      
                 P1OUT |= BIT0;                   //Acende Led 1 (Vermelho)
                 for(i=60000;i>0;i--);             // Dar um tempo
   
                   if ((P1IN & BIT1)==0)         // Se  botão S2 está em 0
        
                    P1OUT &= ~BIT6;          //Apaga Led 2 (Verde) 
                    else 
      
                  P1OUT |= BIT6;        //Acende Led 2 (Verde) 
                    for(i=60000;i>0;i--);      // Dar um tempo
                     }
             }
Now I would like to do the same thing from the above code using Low Power Mode and Interrupts, with 1 Led and 1 button I got in the result:
         #include <msp430G2553.h>
 
         void main(void)
         {
         
         WDTCTL = WDTPW+WDTHOLD;        // Desliga Watchdog Timer
         P1DIR  |= BIT0                                   // P1.0 como Saída, os demais entradas
         P1REN |= BIT3;                                 // Habilita Pull-up no botão P1.3
         P1OUT =  BIT3;                                 // Inicia o Botão em nível lógico 1
         P1IES |= BIT3;                                  //  Seleciona a borda de interrupção  Hi/Low (neste caso quando for para 0) , não entendi bem esta parte..
         P1IFG &= ~BIT3;                              // Inicia o estado da flag como abaixada (0)
         P1IE |= BIT3;                                    //  Habilita a função de Interrupção onde está o botão
          while(1)                                       // Loop Infinito
 
 
       _BIS_SR(LPM4_bits + GIE);               // Função Intrínseca que entra em modo  de LP com o General Interrupt Enable Ativo
        #pragma vector=PORT1_VECTOR     // Começa aqui a rotina de interrupção na Porta 1 (Com o LPM4 todos os clocks estão desligados)    
         __interrupt void Port_1_ISR(void)
           
            while(1)                                      // Loop Infinito
              {
               if ((P1IN & BIT3)==0)                 // Se  botão S1 está em 0
    
                P1OUT |= BIT0;                      //Acende Led 1 (Vermelho)
                     else 
      
                 P1OUT &= ~BIT0;                  //Apaga Led 1 (Vermelho)
                 P1IFG &= ~BIT3;                   // Reseta a flag(0)
                
                }
             }
 
This worked fine, no bug .. but when I adapt to 2 leds and 2 buttons, it does not work .. it does not happen ..
 The only change I made was to add in the registers 1 led (where it is output), plus 1 button on the input.
 Why did not it work?
Thank you, Caio.
  • Hi Caio,

    thanks for your questions.

    Let me quickly clarify some open items to help identify the problem:

    "The only change I made was to add in the registers 1 led (where it is output), plus 1 button on the input."

    To me it looks like the interrupt is not being triggered (as you say nothings happening). So did you also enable the interrupt for the pin that is connected to your button? Plus then resetting the according interrupt flag?

    I also saw that the P1IES |= BIT3 stayed a bit unclear so let me try to shed some light on it: the PxIES register allows you to select the edge of the input signal, i.e. rising or falling edge, to trigger an interrupt. You'll use this because you could have buttons that are connected to Ground or Vcc and a push results in different edges then. Hope this helps.

    Also, you said that sometimes using the code to always poll for an interrupt you won't get a response. Depending on the scenerio that you observe this behaviour it might be due to a missing debounce time interval (essentially that the device cannot be interrupted due to an interrupt before). Please share details when you experience response-issues on your button so that I can further help you solve this.

    Best regards,

    Britta

  • You have a few things that need attention:
    * Your ISR logic is wrong: You should never ever have a "while(1)" loop in any ISR.
    * The way you check for which pin triggered the interrupt is wrong: Do not use "P1IN" (if you think if debouncing you will know why). Instead you should use "P1IFG" to check for the triggering pin (this is the purpose of the IFG register).
    * You should handle debouncing with either firmware or hardware whenever you have button input.

    So, I would rewrite the ISR as follows:

    #pragma vector = PORT1_VECTOR
    __interrupt void port_1_ISR(void){
    if(P1IFG & BIT3){
    LED1 = ON/OFF; //turn ON or OFF the LED as needed
    P1IFG &= ~BIT3; //clear the flag
    }

    //assuming your 2nd button is on BIT4 of PORT1
    if(P1IFG & BIT4){
    LED2 = ON/OFF; //turn ON or OFF the LED as needed
    P1IFG &= ~BIT4; //clear the flag
    }

    }

  • There was a small mistake in the "if statements" that was corrected in the example I provided above. The current one should work.

**Attention** This is a public forum