www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT91SAM7X256 bzw. -EK


Autor: Constantin C.v.f. (cvf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Forum,

ich experimentiere derzeit an einem ATMEL Eval.-Board für den SAM7X µC 
herum.

Leider ist das Datenblatt, Befehlssatz(Registerlister usw) und die 
Kommentierung der Beispielprogramme von Atmel sehr (!), sehr bescheiden 
so dass ich nicht über einfache Modifikation des LED-Blink-Demoprogramm 
hinaus komme.
So möchte ich nun mal zum Beispiel/ zur Übung nur das Statusregister 
PIO_OSR von PortB und deren Pins (LED_MASK) auslesen. Zur Info im 
Demoprogramm wird dieses auf 1 gesetzt

(AT91F_PIO_CfgOutput( AT91C_BASE_PIOB, AT91B_LED_MASK ) ;)

damit die Lämpchen schön leuchten können. Das Register PIO_OSR sollte 
daher auf 1 stehen. Nun hab ich mir aus meinen bescheidenen C 
Kenntnissen ne if-Abfrage gebastelt...

if((AT91F_PIO_GetOutputStatus(AT91C_BASE_PIOB) == 0))
    {
    AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, AT91B_LED1) ;   //LED1 an 
wait();
    AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91B_LED1 ) ;    //LED1 aus
    }
    else
    {
    AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, AT91B_LED2) ;   //Led2 an
    wait();
    AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91B_LED2 ) ;    //led2 aus
    }

...nur leider funktioniert diese Abfrage nicht. Die if-schleife selbst 
geht nur mach ich wohl bei der Abfrage des Statusregisters was falsch.

Diese kleine Abfrage soll mir nur als Einstieg in die 
Programmmier-Denkweise von diesen Atmel µC dienen; durch die vielen 
Pointer und header-files bin ich nicht durch gestiegen was ich und wie 
ich Register setzen bzw. programmiern muss. Mit dieser kleinen Abfrage 
könnt ich halt nach prüfen ob auch wirklich gesetzt ist was ich setzen 
wollt.

gruß
constantin


Autor: Micro Mann (micromann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich tippe mal du fragst das falsche Register ab.
Versuche es mal mit dem Pindaten Statusregister
bzw.  AT91F_PIO_GetOutputDataStatus

Außerdem muss der Pheripheral-Clock des PIO an sein, damit du den Pin 
einlesen kannst.
AT91F_PIOB_CfgPMC

Autor: Micro Mann (micromann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens kannst du Register direkt setzen mit

(*(volatile unsigned int*)Adresse)=Wert;

bzw. auslesen mit
Wert = (*(volatile unsigned int*)Adresse);

ohne die API zu benutzen.

Gruß,
Andreas

Autor: Constantin C.v.f. (cvf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle antwort; nach so einem hinweis hab ich lange 
gesucht. muss ja zugeben dass ich etwas unerfahrn bin und mich 
leichtsinnigerweise gleich an einen solchen controller wage. aber an 
herausforderungen wächst oder scheitert man... mal abwarten lach

werds gleich ausprobiern,
gruß
constantin

Autor: Micro Mann (micromann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Viel Erfolg !

Sag an, obs geklappt hat.

Autor: Micro Mann (micromann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> if((AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOB) == 0))

Übrigens fragst du hiermit den kompletten PIO-Controller ab. Wenn also 
einer der nicht für LEDs genutzten Pins high ist (und das ist garantiert 
der Fall) wird die Bedingung nie erfüllt.

Besser ist :
if(((AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOB))& AT91B_LED_MASK) 
== 0)

Bedeutet : Wenn alle zu den LEDs gehörigen Pins auf low sind

Autor: Constantin C.v.f. (cvf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habs mit der variante
if(((AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOB))& AT91B_LED_MASK)
== 0)
probiert. ähnlich (mit anderer adresse) werden ja auch die schalter 
sw1-5 im demoprogramm abgefragt; leider klappts nicht. Keil kompaliert 
ohne mucken aber keine led leuchtet. daher mein ich das das 
getoutputdatastatus register undefiniert ist (weder 0 noch 1) -> keine 
Led leuchtet.


ich hab  auch noch eine frage zu der "direkten" auslesung des registers; 
so hab ichs geschrieben:

int p;
p=(*(volatile unsigned 
int*)AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOB));
if(p==0)
{

}

auch hier selbiger effekt wie oben beschrieben; keine led leuchtet. nur 
wollt ich wissen ob ich es richtig geschrieben hab.

gebe ich p eine 1 bzw 0, so funktioniert die schleife und led brennen.

Autor: Constantin C.v.f. (cvf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
denkfehler meinerseits...

wenn ich

if(((AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOB))& AT91B_LED_MASK)
== 0)

verwende, so verbinde ich zwei hex-werte (immer ungleich 0 oder 1), die 
ich zudem mit einem dezimal wert vergleiche. das kann nicht gehn.

Autor: Dirk Dörr (dirkd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hex und dezimal sind nur Zahlendarstellungen und haben nichts mit den 
Werten im Register zu tun.

Das

p=(*(volatile unsigned
int*)AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOB));
if(p==0)

wird nicht funktionieren.

AT91F_PIO_GetOutputDataStatus liefert einen Wert. Diesen interpretierst 
Du als Zeiger auf unsigned int und dereferenzierst ihn anschließend.

Das ist nicht das was Du willst. Sollten alle PINS von  PIOB auf low 
sein würdest Du sogar einen NULLPOINTER dereferenzieren => Exception.

Der Vorschlag
> if(((AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOB))& AT91B_LED_MASK)
> == 0)

war eigentlich richtig.

Autor: Micro Mann (micromann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Constantin,

ich bin mir noch nicht sicher, was du machen möchtest.

Hier mal ein Beispiel für eine LED-Ausgabe und Pin einlesen mit 
Benutzung der API:


Also :


// Ne Variable
unsigned int piob_pinwert;

// 1. benutze PIOs einschalten:
AT91F_PIO_Enable(AT91C_BASE_PIOB , AT91B_LED_MASK);

// 2. Setze LED1 und LED 3 :
AT91F_PIO_SetOutput(AT91C_BASE_PIOB , AT91B_LED1 | AT91B_LED3);

// 3. Lösche LED2 und LED 4:
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB , AT91B_LED2 | AT91B_LED4);

// 4. Aktiviere den Output der PIOs (damit kommt das Signal erst an die 
Pins)
AT91F_PIO_OutputEnable(AT91C_BASE_PIOB , AT91B_LED_MASK);

// Jetzt sollten 2 der 4 LEDs leuchten.

// 5. Aktivieren des Peripheralclocks

AT91F_PIOB_CfgPMC();

// 6. Pins einlesen (Hier habe ich auch die API falsch benutzt ;-)
piob_pinwert AT91F_PIO_GetInput (AT91C_BASE_PIOB);

// Jetzt steht der Wert in der Variablen. Wenn du ihn an Bitposition 0-3
// haben möchtest, mußt du die Bits noch maskieren und schieben :

piob_pinwert = piob_pinwert >>19; // LED1 = PIO PB19 also steht an
// Stelle 19
piob_pinwert = piob_pinwert & 0x0000000F;

Dann kannst du mit den dezimal-Werten 1-4 arbeiten für die LEDs

Hoffe das hilft weiter ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.