GPIO mit StellarisWare mit LM4F120H5QR LaunchPad. SW2 funktioniert nicht wie erwartet

Ich versuche herauszufinden, wie man StellarisWare, die eingebauten ROM-Aufrufe, für GPIO richtig verwendet. Das Stellaris LaunchPad hat zwei Schalter (SW1, SW2) und drei LEDs (ROT, GRÜN, BLAU).

Ich habe ein kleines Programm geschrieben, das die Schalter liest und die zugehörigen LEDs einschaltet, wenn ich sie drücke. Alles funktioniert wie erwartet:

  • SW1 leuchtet die grüne LED;
  • SW2 leuchtet die blaue LED;
  • SW1 & 2 leuchten gleichzeitig die rote LED.

Dies ist der Code:

#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;
        }
    }
}

Wenn ich jedoch die sechs Zeilen ab überspringe // GPIO Lock (GPIOLOCK), beginnt das Programm auf unerwartete Weise zu handeln: SW2 wird immer niedrig gelesen, während SW1 wie erwartet funktioniert!

Ich würde erwarten, dass es einen StellarisWare-ROM-Aufruf gibt, der "die schwierigen" Sachen macht, aber ich kann anscheinend nicht den richtigen Aufruf finden. Die Frage ist also: Was (StellarisWare-ROM-Aufruf) übersehe ich hier?

Eigentlich muss nur PF0 in Port F entsperrt werden, um als GPIO verwendet zu werden, deshalb macht das Überspringen der Entsperrung für PF4 keinen Unterschied.
@RogerC. Ich muss das Datenblatt zu diesen Registern diesbezüglich noch einmal überprüfen. Thnx für den Hinweis.

Antworten (1)

Auf den meisten GPIO-Pins ist mehr als eine Funktion zugeordnet. An dem Pin mit SW2 ist auch ein NMI (nicht maskierbarer Interrupt) angeschlossen. Dadurch wird der Pin zuerst entsperrt und kann dann als GPIO-Eingang verwendet werden.

Wie der Kommentar in Zeile 6 andeutet, entsperren Sie im Grunde den SW2-Pin, der als GPIO verwendet werden soll. Alle Stifte mit einer alternativen Funktion von NMI müssen zuerst entsperrt werden, um verwendet werden zu können.

Weitere Einzelheiten zu NMI finden Sie unter https://en.wikipedia.org/wiki/Non-maskable_interrupt