MSP430 - Alternate GPIO Interrupt

From Texas Instruments Wiki
Jump to: navigation, search

On MSP430 devices usually only P1 and P2 pins can be used to generate I/O interrupts. This wiki describes the possibilities to generate interrupts on pins of other ports.

Using Timer Capture Interrupt

If the pin can be assigned as Timer input capture, this can be used as an alternative to normal GPIO interrupt. Usually the pin assignment is fixed, however for example in the case of some MSP430x5xx/6xx devices which have Port Mapping Controller, the pin can be assigned per software to generate interrupt. What is exactly needed in this case is to give up one CCR (Capture Compare Register) - preferred not CCR0 to enable the Timer working in "Up Mode".

The following simple example show a simple example to enable interrupt on P3.0 of MSP430F6736 using pin mapped TA0.2 while Timer_A0 is used to generate PWM output at TA0.1 (P1.1). By selecting CMx bits of TAxCCTLn register, it is possible to select the interrupt edge.

#include <msp430f6736.h>
 
void main(void)
{
  // disable watchdog
  WDTCTL = WDTPW + WDTHOLD;
 
  // use Port Mapping Controller to map TA0.2 to P3.0
  PMAPPWD = PMAPKEY;       // Get write-access to port mapping regs
  P3MAP0 = PM_TA0_2;       // Map TA0.2 input to P3.0
  PMAPPWD = 0;             // Lock port mapping registers
  P3SEL = BIT0;
 
  // setup TA0.2 as compare input on rising edge
  TA0CCTL2 = CM_1 + CCIS_0 + SCS + CAP + CCIE;
 
  // setup P1.1 as TA0.1 and P1.0, P1.2 as output
  P1SEL = BIT1;
  P1DIR = BIT0 + BIT1 + BIT2;
 
  // setup Timer_A to generate PWM signal at TA0.1
  TA0CCR0 = 50000;
  TA0CCR1 = 25000;
  TA0CCTL1 = OUTMOD_3;
  TA0CTL = TASSEL__SMCLK + MC__UP + TACLR;
 
  // enable interrupt
  __enable_interrupt();
 
  while(1)
  {
    // P1.2 shall be connected with P3.0 to generate the interrupt
    P1OUT ^= BIT2;
 
    // delay around 0.5 seconds
    __delay_cycles(500000);
  }
}
 
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A0_CCRx_Isr(void)
{
  switch(__even_in_range(TA0IV,6))
  {
    case 0: break;                          // No interrupts
    case 2: break;                          // TA0CCR1
    case 4:                                 // TA0CCR2
    {
      // the simulated GPIO interrupt occur - do something
      P1OUT ^= BIT0;
      break;
    }
    case 6: break;                          // TA0CCR3
    default: break;
  }
}

Using Comparator

TBD