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.

MSP430FR5969: Problem with GPIO

Part Number: MSP430FR5969


Hello TI Community,

Thanks for the support with your devices. I am programming a MSP430 and I want to configure P1.6 to read a digital input. I set up a voltage divider to give me 3V when a switch is on, and 0V when the switch is off. I configured P1.6 to be an input, with P1DIR register, P1OUT bit 6 to zero for pulldown selected and P1REN bit 6 to 1 to enable pulldown/up resistor. The problem is I always get a zero, despite the voltage I apply on the input. Is there a problem with my code? 

Best wishes,

Luiz Moreira

#include <msp430.h>

int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT

// Configure GPIO
P1DIR = 0b10001000;//|= BIT3 | BIT7; //output
P1REN = 0b01000000;
P1OUT = 0b00001000;//|= BIT3;

// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;

//CLock
CSCTL0_H = CSKEY >> 8; // Unlock CS registers
CSCTL1 = DCOFSEL_0; //DCO em 1 mhz
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; //SMCLK em 1 MHz
CSCTL3 = DIVS_0;


//Timer A
TA0CCTL0 = CCIE; // TACCR0 interrupt enabled
TA0CCR0 = 1000;
TA0CTL = TASSEL__SMCLK | MC__UP; // SMCLK, UP mode

// Configure ADC12
ADC12CTL0 = ADC12SHT0_2 | ADC12ON; // Sampling time, S&H=16, ADC12 on
ADC12CTL1 = ADC12SHP; // Use sampling timer
ADC12CTL2 |= ADC12RES_2; // 12-bit conversion results
ADC12MCTL0 |= ADC12INCH_1; // A1 ADC input select; Vref=AVCC
ADC12IER0 |= ADC12IE0; // Enable ADC conv complete interrupt

while (1)
{
if((P1IN & BIT6)==1){
P1OUT = 0b10000000;//|= BIT7;
}
else if((P1IN & BIT6)==0){
P1OUT = 0b00000000;//|= BIT7;
}
__delay_cycles(5000);
ADC12CTL0 |= ADC12ENC | ADC12SC; // Start sampling/conversion

__bis_SR_register(LPM0_bits + GIE);
__no_operation(); // For debugger
}

}

  • Hello Luiz,

    Are you using a debugger or just evaluating P1.7 output? Do you have an ADC ISR that exits LPM0? If not then you will never loop to re-evaluate P1IN.

    Regards,
    Ryan
  • What Ryan Brown1 said, plus:
    > if((P1IN & BIT6)==1){
    This condition is always false. Try:
    > if((P1IN & BIT6)==BIT6){
  • Thanks Mr Brown and Mr McKenney. I have an adc ISR which I will post beneath this post. This  ADC piece of my program is working just fine.  I am using the Code Composer standard debugger for my board. I've been having indeed this issue with this piece of code [__bis_SR_register(LPM0_bits + GIE);]. Sometimes my program gets stuck in this statement and I have to "reboot" my board. Could you give me more insight about this?

    About Bruce's point, I'll try at the lab and write back soon. I think you're right, because BIT6 is always zero. Am I wrong?

    // Timer0_A0 interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void Timer0_A0_ISR (void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {

    P1OUT ^= 0b00001000;
    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = ADC12_VECTOR
    __interrupt void ADC12_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch(__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
    {
    case ADC12IV_NONE: break; // Vector 0: No interrupt
    case ADC12IV_ADC12OVIFG: break; // Vector 2: ADC12MEMx Overflow
    case ADC12IV_ADC12TOVIFG: break; // Vector 4: Conversion time overflow
    case ADC12IV_ADC12HIIFG: break; // Vector 6: ADC12BHI
    case ADC12IV_ADC12LOIFG: break; // Vector 8: ADC12BLO
    case ADC12IV_ADC12INIFG: break; // Vector 10: ADC12BIN
    case ADC12IV_ADC12IFG0: // Vector 12: ADC12MEM0 Interrupt
    if (ADC12MEM0 >= 0x6B4) // ADC12MEM = A1 > 0.5V?
    P1OUT |= BIT0; // P1.0 = 1
    else
    P1OUT &= ~BIT0; // P1.0 = 0
    __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
    break; // Clear CPUOFF bit from 0(SR)

    case ADC12IV_ADC12IFG1: break; // Vector 14: ADC12MEM1
    case ADC12IV_ADC12IFG2: break; // Vector 16: ADC12MEM2
    case ADC12IV_ADC12IFG3: break; // Vector 18: ADC12MEM3
    case ADC12IV_ADC12IFG4: break; // Vector 20: ADC12MEM4
    case ADC12IV_ADC12IFG5: break; // Vector 22: ADC12MEM5
    case ADC12IV_ADC12IFG6: break; // Vector 24: ADC12MEM6
    case ADC12IV_ADC12IFG7: break; // Vector 26: ADC12MEM7
    case ADC12IV_ADC12IFG8: break; // Vector 28: ADC12MEM8
    case ADC12IV_ADC12IFG9: break; // Vector 30: ADC12MEM9
    case ADC12IV_ADC12IFG10: break; // Vector 32: ADC12MEM10
    case ADC12IV_ADC12IFG11: break; // Vector 34: ADC12MEM11
    case ADC12IV_ADC12IFG12: break; // Vector 36: ADC12MEM12
    case ADC12IV_ADC12IFG13: break; // Vector 38: ADC12MEM13
    case ADC12IV_ADC12IFG14: break; // Vector 40: ADC12MEM14
    case ADC12IV_ADC12IFG15: break; // Vector 42: ADC12MEM15
    case ADC12IV_ADC12IFG16: break; // Vector 44: ADC12MEM16
    case ADC12IV_ADC12IFG17: break; // Vector 46: ADC12MEM17
    case ADC12IV_ADC12IFG18: break; // Vector 48: ADC12MEM18
    case ADC12IV_ADC12IFG19: break; // Vector 50: ADC12MEM19
    case ADC12IV_ADC12IFG20: break; // Vector 52: ADC12MEM20
    case ADC12IV_ADC12IFG21: break; // Vector 54: ADC12MEM21
    case ADC12IV_ADC12IFG22: break; // Vector 56: ADC12MEM22
    case ADC12IV_ADC12IFG23: break; // Vector 58: ADC12MEM23
    case ADC12IV_ADC12IFG24: break; // Vector 60: ADC12MEM24
    case ADC12IV_ADC12IFG25: break; // Vector 62: ADC12MEM25
    case ADC12IV_ADC12IFG26: break; // Vector 64: ADC12MEM26
    case ADC12IV_ADC12IFG27: break; // Vector 66: ADC12MEM27
    case ADC12IV_ADC12IFG28: break; // Vector 68: ADC12MEM28
    case ADC12IV_ADC12IFG29: break; // Vector 70: ADC12MEM29
    case ADC12IV_ADC12IFG30: break; // Vector 72: ADC12MEM30
    case ADC12IV_ADC12IFG31: break; // Vector 74: ADC12MEM31
    case ADC12IV_ADC12RDYIFG: break; // Vector 76: ADC12RDY
    default: break;
    }

  • The condition is always false since BIT6 != 1.

    My guess is that you're losing a race between the LPM setting and the ADC12 interrupt: The conversion takes (16+14) MODOSC clocks, but that's only 6 MCLKs, so it's probably finishing before the LPM0. Try adding "__disable_interrupts();" before the line that sets ADC12SC.

**Attention** This is a public forum