Forum: Mikrocontroller und Digitale Elektronik arm cortex m0 einsteigerfrage


von Alex (Gast)


Lesenswert?

Hallo Leute,

ich arbeite mich grade in die ARM contrller ein. Hab mir das LPCxpresso 
LPC1114 Board von nxp zum einarbeiten gekauft.

Auf Seite 34 ist der Schaltplan.
http://www.nxp.com/documents/other/LPCXpresso_Getting_Started_Guide.pdf

Ich wollte die LED zum blinken bringen.
Beim suchen nach Beispielen hab ich hier folgendes gefunden. 
Beitrag "Re: Einsteigerfrage zu Cortex M0 mit LPCXpresso"
1
#ifdef __USE_CMSIS
2
#include "LPC11xx.h"
3
#endif
4
5
#include <cr_section_macros.h>
6
#include <NXP/crp.h>
7
8
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
9
10
#define PinNummer 7
11
12
int main(void)
13
{
14
  SystemInit();
15
16
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
17
18
  //  Pin als Ausgang konfigurieren
19
  LPC_GPIO0->DIR  |=  (1<<PinNummer);
20
21
  int i,j;
22
  while(1)
23
  {
24
    // Pin auf 1 setzen
25
    LPC_GPIO0->MASKED_ACCESS[1<<PinNummer]= (1 << 7);
26
    for (i=0; i<=1000; i++)
27
    {
28
      for (j=0; j<=1000; j++)
29
      {
30
      }
31
    }
32
    // Pin auf 0 setzen
33
    LPC_GPIO0->MASKED_ACCESS[1<<PinNummer]= (0 << 7);
34
    for (i=0; i<=1000; i++)
35
    {
36
      for (j=0; j<=1000; j++)
37
      {
38
      }
39
    }
40
  }
41
  return 0 ;
42
}
Den Code verstehe ich zum größten Teil aber es bleiben zwei Fragen.
Was macht
1
SystemInit();
 und muss man bei
1
LPC_GPIO0->MASKED_ACCESS[1<<PinNummer]
 den Pin angeben also in meinem Fall PIN23 oder die  PIO 
Bezeichnung(Pio0_7) also 7?

Im Usermanual finde ich zwar etwas zu GPIO versteh es aber nicht ganz 
und zu SystemInit(); gibt’s überhaupt keine Aussage.
Wenn ich den LPC1114 damit programmiere passiert nichts.
Habs auch schon mit dem Oszie kontrolliert die Led leuchtet durchgehend.
Was übersehe ich?

von auch neu (Gast)


Lesenswert?

Hallo Alex,

ich bin auch neu in die Welt der AMR eingetaucht.
in einem meiner BSP programme wird das so gelöst:

/* Macros */
#define LED1_PIN  (1<<11) (Pin Nummer des GPIO1 Ports)
#define LED1INIT LPC_GPIO1->DIR  |= (LED1_PIN)
#define LED1OFF  LPC_GPIO1->DATA |=  LED1_PIN
#define LED1ON   LPC_GPIO1->DATA &= ~LED1_PIN
#define LED1TOG  LPC_GPIO1->DATA ^=  LED1_PIN

Zur SystemInit Funktion.
Das ist bestandteil des CMSIS.
Diese Funkton steht in system_LPC11xx.c und stellt hauptsächlich den 
Systemclock ein. (CLK, PLL, Startup, usw.)
ev. findest du noch mehr wenn du nach CMSIS und SystemInit suchst.

von Alex (Gast)


Lesenswert?

Hallo auch neu,
kannst du bitte da vollständige Beispiel posten oder den link dazu.

Danke

von auch neu (Gast)


Lesenswert?

Hi Alex,

ich verwende ein anderes Board und einen anderen Controller als du.

Jedoch findest du div. Beispiele zu deinem LPCexpresso Board unter:
http://ics.nxp.com/support/lpcxpresso/

Was ist an meinem Macro unverständlich? Bzw. was brauchst du noch mehr 
an Code?

von Alex (Gast)


Lesenswert?

Danke für den Hinweis,
war davor auch schon drauf. Muss mir aber was falschen runter geladen 
haben da die Beispiele nicht so gut waren. Hab jetzt ein anderes Packet, 
auf den ersten Blick scheint es besser zu passen.

von Juergen (Gast)


Lesenswert?

>     LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = (1 << 7);
>     LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = (0 << 7);

Da sollte man besser rechts statt 7 auch PinNummer schreiben.

> Was macht
1
SystemInit();

Beim 1114 wahrscheinlich die Taktfrequenz einstellen,
das hängt aber vom Einzelfall ab.
Ggf. mußt du die Datei mit dem Code finden und dort nachsehen.
Bei größeren Systemen wird dort z.B. auch externer Speicher 
konfiguriert.

Am besten läßt du das erstmal in Ruhe oder kommentierst es aus.

>
1
LPC_GPIO0->MASKED_ACCESS[1<<PinNummer]
 den Pin angeben also in
> meinem Fall PIN23 oder die  PIO Bezeichnung(Pio0_7) also 7?

Für P0_7 sollte das so richtig sein.
Dort wird über die Adresse eine Teilmenge der Pins bestimmt,
auf die zugegriffen wird (im Beispiel genau einer).

> Im Usermanual finde ich zwar etwas zu GPIO versteh es aber nicht ganz

Das Diagram auf Seite 188 unter 12.4.1 Write/read data operation ist 
doch ganz hübsch.

Alternativ kann man auch ganz konventionell über
1
LPC_GPIO0->DATA
 auf den Port zugreifen:
1
LPC_GPIO0->DATA |= 1 << 7;
2
3
LPC_GPIO0->DATA &= ~(1 << 7);

Beide Methoden funktionieren hier mit einem LPC1114FN28.

Jürgen

von (prx) A. K. (prx)


Lesenswert?

Ich würde empfehlen, sich bei ARMs solche GPIO-Bitoperationen wie
  port |= mask;
nicht erst anzugewöhnen. Dann muss man sich das nämlich später nicht 
erst wieder abgewöhnen.

Alle aktuellen ARMs besitzen irgendwelche Möglichkeiten, GPIO-Bits 
gezielt zu setzen oder zu löschen, ohne erst den vorigen Stand zu lesen. 
Das können getrennte Register für setzen/löschen sein, oder wie bei den 
LPC1100 eine Bitmaske als Teil der Adresse. Ebendies ist der Hintergrund 
von sowas wie
  LPC_GPIO0->MASKED_ACCESS[1<<PinNummer] = ~0; //setzen
  LPC_GPIO0->MASKED_ACCESS[1<<PinNummer] = 0;  //löschen

Das ist nicht nur effizienter, sondern ist auch mit Interrupts 
verträglich. Zur Begründung siehe "Hintergrund" in ARM Bitbanding. 
Wohlgemerkt, es geht mir nur um die Begründung dafür, weshalb man auf 
"port |= mask;" verzichten sollte, nicht um die dort beschriebe Methode.

von (prx) A. K. (prx)


Lesenswert?

>>     LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = (1 << 7);
>>     LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = (0 << 7);
>
> Da sollte man besser rechts statt 7 auch PinNummer schreiben.

Das wirkt auf mich übermässig kompliziert und führt aufgrund der 
Umständlichkeit nur dazu, dass man es nicht verwendet. Wenn in der Maske 
bereits festgelegt wird, dass nur Bit 7 beeinflusst wird, dann kann man 
ebensogut aber kürzer und lesbarer auch gleich
       LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = ~0;
und
       LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = 0;
schreiben. Wer mag, der baut sich Konstanten SET/CLR für ~0/0:
       #define CLR 0
       #define SET (~0)
       LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = SET;
       LPC_GPIO0->MASKED_ACCESS[1 << PinNummer] = CLR;

von Alex (Gast)


Lesenswert?

Danke euch allen für die Hilfe,
ich selbst bin kein Fan von Bitmasken aber das ist Geschmackssache...

Nach Betrachtung der Beispiele,des UM und des Schaltplannes muss dieser 
Code doch funktionieren. Die LED müsste im Takt blinken.

Tut sie aber nicht. Habs mit Oszi Kontrolliert.

Langsam krieg ich die  Krise, beim AVR war das irgendwie einfacher.
1
#ifdef __USE_CMSIS
2
#include "LPC11xx.h"
3
#endif
4
5
#include <cr_section_macros.h>
6
#include <NXP/crp.h>
7
8
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
9
10
int main(void) {
11
  /* Enable AHB clock to the GPIO domain. */
12
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
13
14
  LPC_GPIO0->DIR |= (1<<7);   //Als Ausgang setzen
15
  
16
  while(1) {
17
    LPC_GPIO0->MASKED_ACCESS[1<<7] = (1<<7);
18
    LPC_GPIO0->MASKED_ACCESS[1<<7] = (0<<7);
19
  }
20
  return 0 ;
21
}

von Lothar (Gast)


Lesenswert?

Alex schrieb:
> LPC_GPIO0->MASKED_ACCESS[1<<7] = (1<<7);
> LPC_GPIO0->MASKED_ACCESS[1<<7] = (0<<7);

LPC_GPIO0->MASKED_ACCESS[1<<7] = (1<<7);
Delay(1000);
LPC_GPIO0->MASKED_ACCESS[1<<7] = (0<<7);
Delay(1000);

von Alex (Gast)


Lesenswert?

Hi,
das Delay ist mir egal. Hab ein Oszie mit dem ich es kontrollieren kann.
Mein Problem ist dass es auf dem Board nicht funktioniert. Ich hab an 
der LED nur Gleichspannung.

von Lothar (Gast)


Lesenswert?

Alex schrieb:
> Hab ein Oszie

mit 100MHz Abtastrate?

von Caradhras (Gast)


Lesenswert?

Lothar schrieb:
> Alex schrieb:
>> LPC_GPIO0->MASKED_ACCESS[1<<7] = (1<<7);
>> LPC_GPIO0->MASKED_ACCESS[1<<7] = (0<<7);
>
> LPC_GPIO0->MASKED_ACCESS[1<<7] = (1<<7);
> Delay(1000);
> LPC_GPIO0->MASKED_ACCESS[1<<7] = (0<<7);
> Delay(1000);

this

oder benutz gleich nen timer, um die LED zu toggeln. Vlt am Anfang 
einfach mit einer if/else.

zb. mit SysTick oder TMR32

von Caradhras (Gast)


Lesenswert?

Wo ist dein SystemInit()???

von Lothar (Gast)


Lesenswert?

Caradhras schrieb:
> Wo ist dein SystemInit()???

Ohne läuft der LPC1114 mit dem internen 12MHz Oszillator. Allerdings 
muss wohl dann der Pin auch komplett initialisiert werden:

SYSAHBCLKCTRL_bit.GPIO
SYSAHBCLKCTRL_bit.IOCON

IOCON_PIO0_7 (externer oder interner Pull)

von Caradhras (Gast)


Lesenswert?

Schau dir mal die Programmierbeispiele an, die NXP erstellt hat. Die 
sind zwar steinalt (uralte CMSIS-Version) und teilweise sollte man sich 
auch nicht drauf versteifen, da sie eben nicht versuchen den einfachsten 
Betriebsfall anzugeben, aber meist geben sie einen Einblick, was wie 
geht.

http://ics.nxp.com/support/lpcxpresso/

Du solltest auf jeden Fall direkt mit der CMSIS-Version 2.0 starten.

von Alex (Gast)


Lesenswert?

Mein Beispiel code ist richtig und es Funktioniert alles wie gewollt. 
Allerdings mit einem neuen Board da das erste Kaputt war.

Danke für die Hilfe.

von Jürgen S. (starblue) Benutzerseite


Lesenswert?

Lothar schrieb:
>
> Allerdings
> muss wohl dann der Pin auch komplett initialisiert werden:
>
> SYSAHBCLKCTRL_bit.GPIO
> SYSAHBCLKCTRL_bit.IOCON
>
> IOCON_PIO0_7 (externer oder interner Pull)

Die sind hier nach dem Reset schon richtig eingestellt
(GPIO-Takt ein, Pin mit GPIO-Funktion).

Im allgemeinen aber ein guter Hinweis.

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.