GPIO usando StellarisWare con LM4F120H5QR LaunchPad. SW2 no funciona como se esperaba

1

Estoy tratando de averiguar cómo usar correctamente StellarisWare, las llamadas ROM incorporadas, para GPIO. El Stellaris LaunchPad tiene dos interruptores (SW1, SW2) y tres LED (ROJO, VERDE, AZUL).

Escribí un pequeño programa que lee los interruptores y enciende los LED relacionados cuando los presiono. Todo funciona como se esperaba:

  • SW1 enciende el LED verde;
  • SW2 enciende el LED azul;
  • SW1 & 2 encienden simultáneamente el LED rojo.

Este es el código:

#include "driverlib/gpio.c"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"

#include <stdint.h>

#define LED_RED   GPIO_PIN_1
#define LED_GREEN GPIO_PIN_3
#define LED_BLUE  GPIO_PIN_2

#define SW1 GPIO_PIN_4
#define SW2 GPIO_PIN_0

#define GPIO_PORTF_LOCK_R       (*((volatile unsigned long *)0x40025520))
#define GPIO_PORTF_CR_R         (*((volatile unsigned long *)0x40025524))
#define GPIO_PORTF_DEN_R        (*((volatile unsigned long *)0x4002551C))

int main() {

    // Enable GPIO port
    ROM_SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF );

    // Enable LED pins for output
    ROM_GPIOPinTypeGPIOOutput( GPIO_PORTF_BASE , LED_RED | LED_GREEN | LED_BLUE );

    // Enable switch pins for input
    ROM_GPIOPinTypeGPIOInput( GPIO_PORTF_BASE , SW1 | SW2 );

    // Enable switch pins pull up.
    ROM_GPIOPadConfigSet( GPIO_PORTF_BASE , SW1 | SW2 , GPIO_STRENGTH_2MA , GPIO_PIN_TYPE_STD_WPU );

// GPIO Lock (GPIOLOCK)
GPIO_PORTF_LOCK_R = 0x4C4F434BU; // unlock the lock register
// GPIO Commit (GPIOCR)
GPIO_PORTF_CR_R = 0xFF; // enable commit for PORT F
// GPIO Digital Enable (GPIODEN)
GPIO_PORTF_DEN_R = 0xFFU; // enable digital on all pins in PORTF

    while ( 1 ) {
        switch( ROM_GPIOPinRead( GPIO_PORTF_BASE , SW1 | SW2 ) ^ ( SW1 | SW2 ) ) {
            case SW1:
                ROM_GPIOPinWrite( GPIO_PORTF_BASE , LED_RED | LED_GREEN | LED_BLUE , LED_GREEN );
                break;
            case SW2:
                ROM_GPIOPinWrite( GPIO_PORTF_BASE , LED_RED | LED_GREEN | LED_BLUE , LED_BLUE  );
                break;
            case SW1 | SW2:
                ROM_GPIOPinWrite( GPIO_PORTF_BASE , LED_RED | LED_GREEN | LED_BLUE , LED_RED   );
                break;
            default:
                ROM_GPIOPinWrite( GPIO_PORTF_BASE , LED_RED | LED_GREEN | LED_BLUE , 0 );
                break;
        }
    }
}

Sin embargo, cuando omito las seis líneas que comienzan en // GPIO Lock (GPIOLOCK) , el programa comienza a actuar de una manera inesperada: SW2 siempre se lee bajo, ¡mientras SW1 funciona como se esperaba!

Espero que haya una llamada de ROM de StellarisWare que haga lo "difícil", pero parece que no puedo encontrar la llamada correcta. Entonces, la pregunta es: ¿Qué (StallarisWare ROM call) estoy pasando por alto aquí?

pregunta jippie

1 respuesta

2

En la mayoría de los pines GPIO, hay más de una función asociada. En el pin que tiene SW2, también hay un NMI (interrupción no enmascarable) adjunto. Esto hace que el pin se desbloquee primero y luego se puede usar como entrada GPIO.

Como sugiere el comentario en la línea 6, básicamente estás desbloqueando el pin SW2 para usarlo como GPIO. Todos los pines que tienen una función alternativa de NMI deben desbloquearse primero para poder ser utilizados.

Para más detalles sobre NMI, puede consultar enlace

    
respondido por el Saqib Ahmed

Lea otras preguntas en las etiquetas