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:
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?
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
Roger C.
Jippie