Forum: Mikrocontroller und Digitale Elektronik Wie Register setzen lpc1768


von jo (Gast)


Lesenswert?

Hallo,
ich versuche mich gerade in ein LPC 1768 einzuarbeiten.
Leider verstehe ich nicht ganz wie ich in ein Register schreibe
um ein PIN auf z.b. auf High zusetzen.

Bei den AVR's war es irgendwie einfach zu verstehen und 
nachvollzuziehen.
z.B:

DDRD  = 0x00; /* alle Pins von Port D als Eingang */
PORTD = 0xff; /* interne Pull-Ups an allen Port-Pins aktivieren */

aber bei denn ARM verstehe ich es irgendwie nicht.

von Lutz (Gast)


Lesenswert?

Eigentlich genauso, nur das es nicht DDRD usw. heißt. Kommt auf die 
Headerdatei drauf an.
Lade dir mal 
http://www.lpcware.com/content/nxpfile/lpcopen-software-development-platform-lpc17xx-packages 
herunter. Und schau mal generell nach LPCOpen.

von Oliver S. (oliverso)


Lesenswert?

Es geht genauso wie beim AVR auch:

Datenblatt lesen. Zu den LPC's gibt es die in sehr ausführlich...

Oliver

von jo (Gast)


Lesenswert?

Ich hab das Datenblatt mir angeschaut.
Aber irgendwie scheint das doch anders zu sein mit dem beschreiben.
Wenn ich es so  z.b. versuche:


  FIO2DIR=0x0001;
  FIO2SET=0x0001;

bekomme ich ein Fehler.

ich hab jetzt ein  Beispiel aus dem Internet versucht was zwar 
funktioniert ich es aber nicht nachvollziehen kann.

#define LED (1 << 18)
…
int main (void)
{
…
LPC_GPIO1->FIODIR |= LED; //aktiviere LED-Ausgang
…
}

von Oliver S. (oliverso)


Lesenswert?

Schau dir zunächst mal die prozessorspezifischen Header an. Warum die 
das so machen, wie sie es machen, ist zwar eine berechtigte Frage, aber 
die Antwort lautet halt: Ist einfach so.

Was von dem, was du nicht dann immer noch nicht nachvollziehen kannst, 
steht nicht in deinem C-Buch?

Oliver

von Onkel Dittmeyer (Gast)


Lesenswert?

Im Standard-Header lpc17xx.h ist der Zugriff auf die Register über 
structs realisiert. Wahrscheinlich ist dir das nicht geläufig. Man macht 
sich dabei die Tatsache zu Nutze, dass die Register für die jeweiligen 
Hardware-Blöcke im Controller (z.B. GPIO oder UART) unmittelbar 
nacheinander im Adressraum liegen, eben wie Variablen einer struct. Das 
hat den Vorteil, dass man beispielsweise für die 4 GPIO-Ports nicht 
jedes Register einzeln mit Adresse definieren muss. Stattdessen 
definiert man bloß ein einziges mal das "Layout" der Register für einen 
GPIO-Block allgemein als struct und braucht dann nur noch die 
"Startadressen" der 4 Blöcke zu hinterlegen.

Mal ein Beispiel aus dem Header für die drei I2C-Blöcke des μC:
1
// Als erstes die allgemeine Definition der struct für einen I2C-Block
2
typedef struct
3
{
4
  __IO uint32_t I2CONSET;
5
  __I  uint32_t I2STAT;
6
  __IO uint32_t I2DAT;
7
8
  // usw...
9
10
} LPC_I2C_TypeDef;
11
12
// ...
13
// Jetzt kommen die Startadressen der drei Blöcke
14
#define LPC_I2C0_BASE         (LPC_APB0_BASE + 0x1C000)
15
#define LPC_I2C1_BASE         (LPC_APB0_BASE + 0x5C000)
16
#define LPC_I2C2_BASE         (LPC_APB1_BASE + 0x20000)
17
18
// ...
19
// Und anschließend die "Verknüpfung" - Hier steht im Prinzip: 
20
// Interpretiere die Speicherstellen LPC_I2C0_BASE bis LPC_I2C2_BASE
21
// als Zeiger auf structs vom Typ LPC_I2C_TypeDef 
22
#define LPC_I2C0              ((LPC_I2C_TypeDef       *) LPC_I2C0_BASE     )
23
#define LPC_I2C1              ((LPC_I2C_TypeDef       *) LPC_I2C1_BASE     )
24
#define LPC_I2C2              ((LPC_I2C_TypeDef       *) LPC_I2C2_BASE     )

Dadurch kann man dann im Code über LPC_I2C0->I2STAT auf das 
Statusregister vom I2C-Block 0 zugreifen. Die Adresse wird dann vom 
Compiler indirekt berechnet (Startadresse des Blocks LPC_I2C0 + 4 Byte 
Offset). Ansonsten ist die Verwendung exakt so wie bei den 
Registerdefinitionen aus dem AVR-Bereich.

von jo (Gast)


Lesenswert?

ich verstehe diese Zeile nicht.

LPC_GPIO1->FIODIR |= LED;

von Grundschüler (Gast)


Lesenswert?

jo schrieb:
> LPC_GPIO1->FIODIR |= LED;
für den Port1 wird im DIR-Register der als LED definierte Pin gesetzt

das entspricht beim AVR
#define LED 1
DDRA |= LED;

Das ganze erschließt sich anhand der lpc17xx.h

in der veralteten lpc176x.h waren Register so definiert:
#define  FIO1DIR    (*(volatile uint32_t*)0x2009C020)
Da konnte man das Reguister tatsächlich mit
FIO1DIR=0x0001;
ändern.

Das war m.E. besser und einfacher. es geht aber auch bei den Stucturen
immer darum, in dem Register 0x2009C020 bestimmte Bits zu setzen.

von Max K. (makro)


Lesenswert?

Ich weiß noch, am Anfang bin ich auch drüber gestolpert.
Ist aber ganz einfach:

#define LED (1 << 18)

bedeutet ja, dass Bit 18 gesetzt ist, die anderen sind Null, man könnte 
statt LED auch schreiben:  0x00020000  (hab's jetzt hoffentl. nicht 
falsch gezählt).

LPC_GPIO1->FIODIR |= LED;
   ist also
LPC_GPIO1->FIODIR |= 0x00020000;
   oder anders geschrieben
LPC_GPIO1->FIODIR = LPC_GPIO1->FIODIR | 0x00020000;

Das Bit setzt im Richtungsregister FIODIR (Eingang/Ausgang) von 
GPIO-Port 1 eine '1'. Das Pin wird damit zum Ausgang.

von jo (Gast)


Lesenswert?

Mir ist mehr das Zeichen -> nicht ganz klar.
Also LPC_GPIO1->FIODIR.

von Max K. (makro)


Lesenswert?

In einem Buch hatte ich gelesen, ist schon ein paar Jahre her:
"Bei dem Thema Pointer gehen selbst hartgesottene Programmierer erst mal 
zum Tee-Automaten." - Fand ich ganz witzig.

Damit hat es zu tun.

Schau mal in die LPC17xx.h  ganz unten.
Dort ist  LPC_GPIO1  als Pointer deklariert, zB.

#define LPC_GPIO1             ((LPC_GPIO_TypeDef   *) LPC_GPIO1_BASE )

Von da aus kann man sich nach oben hangeln zu   LPC_GPIO1_BASE  und
zur Definition der Struktur   LPC_GPIO_TypeDef.
Da steht auch das FIODIR drin.

In C  gibt es die abgekürzte Schreibweise für Zugriffe auf 
Struktur-Elemente über  Pointer, das ist der Zeiger auf ein 
Struktur-Element '->'.

http://openbook.galileocomputing.de/c_von_a_bis_z/021_c_dyn_datenstrukturen_001.htm#ix0cd2389809be2a6e4c1b84329ffa8439

an dieser Stelle ist es zB. erklärt.
Geht aber nur bei Pointern.

Ein paar mal gemacht, und man denkt nicht mehr drüber nach.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.