3 votos

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

Acabo de recibir un MSP430F5529 Launchpad y he hecho un tutorial en el que hago parpadear el LED situado en P1.0. Estoy usando code composer studio como mi IDE

Ahora estoy intentando que el LED de P1.0 (rojo) y el de P4.7 (verde) se alternen en función de si se pulsa el botón situado en P2.1.

No importa lo que haga el botón no parece cambiar nada. Lo que es aún más impar es que presionando el botón cambia múltiples bits en P2IN en lugar de sólo P2.1.

He tratado de 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 a veces no cambia ninguno. Pero lo peor es que aunque los bits cambien y se compare el bit de entrada con lo que debería ser para pulsado, nunca se registra como pulsado.

¡¡¡¡También no puedo ver mis variables, así que añadí una variable 'blah' y traté de ponerla a 0x00 para forzarme a entrar en el bucle, pero no hace nada!!!! Es como si simplemente borrara la variable blah.

Este es 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 tratando de depurar en vano (el botón funciona si entro en el bucle delay(), 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 mal porque blah nunca aparece en mi lista de variables del depurador y el delay(5) nunca se ejecuta.

3voto

Chenghua Yang Puntos 51

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

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

Para indicarle al compilador que debe acceder realmente a alguna variable, hay que 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 que el compilador viera una asignación.

Tenga en cuenta también que el compilador no sabe que los manejadores de interrupción pueden interrumpir otras funciones, por lo que podría no molestarse en releer alguna variable que pudiera haber sido modificada por la interrupción. Así que las variables que se comparten entre algún manejador de interrupción y el programa principal también deben ser declaradas volatile .


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

Peor aún, una entrada que resulta ser medio cargada enciende tanto la conexión "1" como la "0" a medias, y fluye 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 los pines de los puertos no utilizados

Los pines de E/S no utilizados deben configurarse como función de E/S, dirección de salida, y dejarse sin conectar en la placa de PC, para evitar una entrada flotante y reducir el consumo de energía. El valor del bit PxOUT es don't care, porque el pin está desconectado. Alternativamente, la resistencia pullup/pulldown integrada puede habilitarse estableciendo el bit PxREN del pin no utilizado para evitar la entrada flotante.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X