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.

CCS/MSP430FR6989: How do I get the MSP430 to take the ouput from 1 pin as input to another pin to trigger an interrupt service routine?

Part Number: MSP430FR6989

Tool/software: Code Composer Studio

I am trying to get my MSP430 to use the output of 1 pin as the input to another pin. However, I can't seem to make the code work. My very simple program is below. Not shown is a simple delay loop, for debouncing purposes, and the external circuit, which is just a button connecting P8.4 to P2.1. When I press it, since 8.4 is high, 2.1 becomes high. I then have an ISR which should trigger when 2.1 goes high (or, strictly speaking, goes from high to low, since I selected falling edge interrupts). This ISR should toggle the onboard LED. However, the LED does not turn on. I am unsure if I am using the input functionality for pins correctly, or if there is a mistake elsewhere.

void main(void)

{

WDTCTL = WDTPW | WITHOLD;

P1DIR |= BIT0;

P1OUT = 0x00;//no output until called

    P2DIR   |= BIT6 | BIT7;      // P2.6 and P2.7 set as output
    P2OUT = 0x00;//ensure no ouput from them until desired.
    P3OUT = 0x00;
    P8OUT = 0x00;

    P8DIR |= BIT4 | BIT5 | BIT6 | BIT7;
    P8REN |= BIT4 | BIT5 | BIT6 | BIT7;
    P8OUT |= BIT4 | BIT5 | BIT6 | BIT7;

    P2DIR &= ~(BIT1 | BIT2 | BIT3 | BIT4);
    P2REN |= BIT1 | BIT2 | BIT3 | BIT4;
    P2IN &= ~(BIT1 | BIT2 | BIT3 | BIT4);//
    P2IE |= BIT1 | BIT2 | BIT3 | BIT4;//interrupts on 1-4
    P2IES |= BIT1 | BIT2 | BIT3 | BIT4;//falling edge
    P2IFG &= 0x00f;//clear interrupt flags

PM5CTL0 &= ~LOCKLPM5;

while (1){}//go forever

}

#pragma vector = PORT2_VECTOR      // associate funct. w/ interrupt vector
__interrupt void Port_2(void)      // name of ISR
{
    switch(__even_in_range(P2IV,P2IV_P2IFG7))
    {
    //I'm using P2.1-2.4 as inputs.
    case P2IV_NONE:   break;   // Vector  0: no interrupt
    case P2IV_P2IFG0: break;   // Vector  2: P2.0

    case P2IV_P2IFG1:
        P1OUT ^= BIT0;//toggle led
        P2IFG &= ~BIT1;//clear flag
        P2IE &= ~(BIT1 | BIT2 | BIT3 | BIT4);//disable interrupts
        delay();
        P2IE |= BIT1 | BIT2 | BIT3 | BIT4;//enable interrupts
        break;

    case P2IV_P2IFG2:
        break;

    case P2IV_P2IFG3:
        break;

    case P2IV_P2IFG4:
        break;

    case P2IV_P2IFG5: break;   // Vector 12: P2.5
    case P2IV_P2IFG6: break;   // Vector 14: P2.6
    case P2IV_P2IFG7: break;   // Vector 16: P2.7
    default: break;
    }
}

  • Attempting to write a value to P2IN is a mugs game since it is read only.

    Anding 0x0f with P2IFG clears the upper 4 bits. Perhaps you meant ~0x0f.

    Fiddling with the port interrupt settings should be done after clearing LOCKLPM5 and IES should be set before IE. (See user guide.)

    I don't see where you set GIE to enable global interrupts.

  • The 0x0f is a typo from when I copied the code to the site. I also use __enable_interrupt() in main, right before the while loop, but I failed to copy it over. The rest of the code is, as far as I can tell, as I wrote it originally.

    Since P2IN is read only, how can I use the input pins to trigger interrupts at all? I think I may be misunderstanding something about how the pins and registers work in this context, and so far the family user guide has not provided anything that clears up what's going on. Let me explain, and maybe you can set me right:

    1. Input mode is meant to take inputs. Inputs come from places outside the pin. E.g., I could use an 3.3V exterior source and switch it on/off to create an input signal for the input pin (a pin configured as an input).

    2. Interrupts detect rising/falling edges.

    3. So if I connect a voltage source at logical "1" to the input pin, and the input pin was previously at logical "0", that contains a rising edge and should be detectable.

    4. You're saying that the P2 input registers are read only, and that this means they cannot detect changing voltage on the pins that are connected as inputs? Am I interpreting you correctly?

    Which leads to my question: How can I use an input pin to trigger an interrupt at all? The family user guide strongly suggests that any IO pin, in either Input or Output mode, should be capable of triggering interrupts. So I don't understand what I need to do to trigger interrupts when inputs change on an input pin.

    For example, if I switched my outputs to P2 and my inputs to P8, then would flipping the switch to connect P2 and P8 be able to trigger an interrupt? (And yes, I will just flip my code around and try this, but I suppose it's worth asking anyway).

  • Hiding bits of code doesn't help.

    4) P2IN is read only so writing to does nothing. What you read there always reflects the state of the pin. Connect something to it and twiddleit and P2IN will change.

    Not all ports support interrupts and I see vectors only for ports 1-4 in the linker script.

    You didn't say anything about my comments on LOCKLPM5 and the timing of port initialization. The user guide says that the PxIFG registers cannot be changed with LOCKLMP5 set but don't make a similar statement that I can find about PxIE. But enabling port interrupts with PxIE is the last step in the recommended flow so it wouldn't surprise me. Edit your initialization code so that it matches the recommended sequence.

  • Thanks, I didn't say anything about the LOCKLPM5 because the point was well-made, and I didn't have questions about it. I'm going to take what you've said and fiddle with the things. Thanks for your help.

**Attention** This is a public forum