2
votes

below is a code for the MSP430G2 micro-controller. I am having trouble adding to this assignment so far to include using the Interrupt Service Routine to my code. This code is a two bit counter which counts up using the S2 button on the launchpad and then counts down using an externally attached switch connected to pins 1.7 and 2.4, which can be seen in the code. If anyone can help explain how to add the ISR to this code, I would highly appreciate the help!

#include <msp430.h>

#define LEDS (BIT6 + BIT0)

// Global variables to hold current state and # of pushes
char pushes;


// Initialization function
void init(void)
{
    WDTCTL = WDTPW + WDTHOLD;                         // Stop watchdog timer
    P1DIR |= LEDS;                                   // Set P1.0, P1.6 to output direction
    P1DIR &= ~ BIT3;                                // Turn P1.3 into input
    P1REN |= BIT3;                                 // Enable internal resistor
    P1OUT |= BIT3;                                // Enable as pullup resistor
    P1DIR |= BIT7;                               // Set BIT 7 to output
    P1OUT |= BIT7;                              // Set BIT 7 as VCC



    P2DIR &= ~ (BIT4);                       // Makes this an input
    P2REN |= (BIT4);                        // Turns on internal resistor
    P2OUT &= ~(BIT4);                      // Make internal resistor pulldown

    pushes = 0;                          // Initialize global variable
    P1OUT &= ~(LEDS);                   // Clear output LEDs
}

// Read input function
char readInput(void)
{
    char local = 0;

    if (!(BIT3 & P1IN))                        // Check for button push
    {
        local = 1;
        _delay_cycles(10000);                 // Wait for bouncing to end
    }
    if ((P2IN & BIT4))                       // Check for button push
    {
        local = 2;
        _delay_cycles(10000);              // Wait for bouncing to end
    }

    return local;
}

// Count up function
void countUp(void)
{
    pushes += 1;                          // increment pushes variable
    if (pushes & BIT0){
    P1OUT |= BIT6;
    }
    else{
        P1OUT &= ~BIT6;
        }
    if (pushes & BIT1){
        P1OUT |= BIT0;
        }
    else{
        P1OUT &= ~BIT0;
    }

}

// Count down function
void countDown(void)
{
    pushes -= 1;                          // decrement pushes variable
    if (pushes & BIT0){
        P1OUT |= BIT6;
        }
        else{
            P1OUT &= ~BIT6;
            }
        if (pushes & BIT1){
            P1OUT |= BIT0;
            }
        else{
            P1OUT &= ~BIT0;
        }
}


// Main function
int main(void)
{
  char enable = 0;                        // Holds status of the S2 button
  char previousState = 0;                 // Holds previous state of S2 button
  init();                                 // One time initialization function

  while (1)
  {

      enable = readInput();               // Check the buttons

      if(enable && !previousState){
                                          // If button is pressed, allow counter to increment/decrement once
         if(readInput()==1){
             countUp();

       }

         if(readInput()==2){
             countDown();

             }
        }
      previousState = enable;


  }
}
1
Didn't you learn what an interrupt is and how it works? Can't you model it on some on the many example programs that do use an ISR? At what step are you stuck?CL.

1 Answers

1
votes

To add an interrupt for a specific port and pin, you need to do several things. Let's take the P1.3 as the example; interrupt for P2.4 can be added in the analogous way.

  1. Set the "interrupt enable" bit of the microcontroller:

    P1IE |= BIT3; // P1.3 interrupt enable

    and configure whether the interrupt should happen on the rising or the falling edge:

    P1IES |= BIT3; // P1.3 interrupt on falling edge

  2. Define the interrupt service routine (ISR) for the port. Seeing that you use CCS, I believe #pragma vector=PORT1_VECTOR is the way to go.

  3. Clear the interrupt flag in the ISR to avoid repeated firing. Another caveat is that there can be only one ISR per port, and not all ports support interrupts. If you need to handle interrupts on multiple pins, you need to demultiplex that in the handler by looking the the interrupt flag status.

Code:

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
  if (P1IFG & BIT3) { // P1.3 interrupt?

    // TODO: add the application logic here

    P1IFG &= ~BIT3;   // clear the P1.3 interrupt flag
}
  1. Make sure that the global interrupt enable (GIE) bit of the status register is set. If there is a doubt, set it with, for example:

    __bis_SR_register(GIE);