MSP430 Los botones del Launchpad no se comportan correctamente y no pueden ver las variables

3

Acabo de recibir un MSP430F5529 Launchpad y he realizado un tutorial donde hago que el LED ubicado en P1.0 parpadee. Estoy utilizando Code Composer Studio como mi IDE

Ahora estoy intentando que el LED en P1.0 (rojo) y el de P4.7 (verde) se alternen dependiendo de si el botón ubicado en P2.1 está presionado.

No importa lo que haga, el botón no parece cambiar nada. Lo que es aún más extraño es que al presionar el botón se cambian varios bits en P2IN en lugar de solo P2.1.

He intentado usar el botón en P1.1 (en realidad lo intenté primero), y obtuve un comportamiento similar en el que el botón cambia varios bits y algunas veces no cambia nada. Pero la peor parte es que incluso si los bits cambian y comparan el bit de entrada con lo que debería ser pulsado, nunca se registra como pulsado.

Tampoco puedo ver mis variables, así que agregué una variable 'blah' y traté de configurarlo en 0x00 para forzarme en el bucle, ¡pero no hace nada! Es como si solo eliminara la variable blah.

Aquí está el código que estoy tratando de hacer funcionar:

#include <msp430f5529.h>

//defines
#define red_LED   BIT0 //red LED @ P1.0
#define grn_LED   BIT7 //green LED @ P4.7
#define BTN       BIT1 //button is located a P2.1
#define BTN_PRESSED      0x00

//prototypes
void delay(int n);

//main
void main(void) {
    WDTCTL = WDTPW + WDTHOLD; //disable watchdog timer

    unsigned int flash; //variable to store LED flash flag

    P1OUT = 0; //set output as low
    P1DIR |= red_LED;  // set LED pins to outputs

    P4OUT = 0; //set output low
    P4DIR |= grn_LED; //set green LED as output

    /* Setting up Switch */
    P2OUT = 0;                                   //set output as low
    P2DIR &= ~BTN;                               // Set the switch pin to input
    P2REN |= BTN;                                // Use an internal resistor
    P2OUT |= BTN;                                // The internal resistor is pullup

    for (;;) {//inf loop

        for (flash=0; flash<7; flash++) {
            P1OUT |= red_LED;    // red LED on
            delay(60000);             // call delay function
            P1OUT &= ~red_LED;   // red LED off
            delay(60000);             // delay again
        }

        while ((P2IN & BTN) == BTN);  // wait for button press, loop forever while P1IN is high (button unpressed)

        for (flash=0; flash<7; flash++) {
            P4OUT |= grn_LED;    // green LED on
            delay(60000);            // call delay function
            P4OUT &= ~grn_LED;   // green LED off
            delay(60000);            // delay again
        }

        while ((P1IN & BTN) == BTN);  // wait for button press, loop forever while P1IN is high (button unpressed)

    }//end inf loop
} // main


//functions
void delay(int n) {
    //delays for a count of 60000 ticks
    unsigned int count;
    for (count=0; count<n; count++);
} // delay

y aquí está el código de prueba que estoy intentando depurar en vano (el botón funciona si me meto en el bucle de retraso (), ¡pero nunca puedo entrar en él!

#include <msp430f5529.h>

//defines
#define red_LED   BIT0
#define grn_LED   BIT7
#define BTN       BIT1
#define BTN_PRESSED      0x00

//prototypes
void delay(int n);

//main
void main(void) {
    WDTCTL = WDTPW + WDTHOLD; //disable watchdog timer

    unsigned int flash; //variable to store LED flash flag

    P1OUT = 0; //set output as low
    P1DIR |= red_LED;  // set LED pins to outputs

    P4OUT = 0; //set output low
    P4DIR |= grn_LED; //set green LED as output

    /* Setting up Switch */
    P2OUT = 0;                                   //set output as low
    P2DIR &= ~BTN;                               // Set the switch pin to input
    P2REN |= BTN;                                // Use an internal resistor
    P2OUT |= BTN;                                // The internal resistor is pullup

    int blah = 0;

    for(;;){
        if((blah) == BTN_PRESSED){
            delay(5);             // call delay function
        }
    }

//functions
void delay(int n) {
    //delays for a count of 60000 ticks
    unsigned int count;
    for (count=0; count<n; count++);
} // delay

¡Debo estar haciendo algo fundamentalmente incorrecto porque bla nunca aparece en la lista de variables de mis depuradores y el retraso (5) nunca se ejecuta!

    
pregunta user2237160

1 respuesta

3

El compilador ve que el bucle delay() está vacío, por lo que concluye inteligentemente que la función puede calcular el resultado mismo mucho más rápido al omitir el bucle por completo.

La variable blah tiene el mismo problema: el compilador ve que su valor nunca cambia dentro del programa, por lo que es una constante y no necesita ser almacenado en ningún lugar. (Y if((blah) == BTN_PRESSED) no puede nunca suceder, por lo que se puede omitir.)

Para decirle al compilador que realmente debería acceder a alguna variable, debe declarar esa variable como volatile :

volatile int blah = 0;        // allows changes with the debugger
...
volatile unsigned int count;  // force the compiler to actually count up, even
                              // if the compiler does not see any effect

Tenga en cuenta que todos los registros como P2IN se declaran como volatile porque podrían cambiar sin una asignación vista por el compilador.

Tenga en cuenta también que el compilador no sabe que los manejadores de interrupciones pueden interrumpir otras funciones, por lo que podría no molestarse en volver a leer alguna variable que la interrupción pudo haber cambiado. Por lo tanto, las variables que se comparten entre un controlador de interrupciones y el programa principal también deben declararse volatile .

Por defecto, todos los pines GPIO están configurados como entradas. Estas entradas se implementan con MOSFET, y su compuerta es tan pequeña que puede captar una carga aleatoria de cualquier señal cercana, o incluso a través del aire, si no activa una entrada alta o baja. Esto se denomina "entrada flotante".

Peor aún, una entrada que está cargada con mitad cambia las conexiones "1" y "0" a la mitad, y fluirá una corriente desde la fuente de alimentación a tierra.

La Guía del usuario dice en la sección 12.2.8:

  

Configuración de pines de puerto no utilizados

     

Los pines de E / S no utilizados deben configurarse como función de E / S, dirección de salida y dejados desconectados en la placa de circuito impreso, para evitar una entrada flotante y reducir el consumo de energía. El valor del bit PxOUT no es importante, porque el pin no está conectado. Alternativamente, la resistencia de extracción / extracción integrada se puede habilitar configurando el bit PxREN del pin no utilizado para evitar la entrada flotante.

    
respondido por el CL.

Lea otras preguntas en las etiquetas