Forum: Mikrocontroller und Digitale Elektronik AT91SAM7X256 bzw. -EK


von Constantin C. (cvf)


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


von Micro M. (micromann)


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

von Micro M. (micromann)


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

von Constantin C. (cvf)


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

von Micro M. (micromann)


Lesenswert?

Viel Erfolg !

Sag an, obs geklappt hat.

von Micro M. (micromann)


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

von Constantin C. (cvf)


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.

von Constantin C. (cvf)


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.

von Dirk D. (dirkd)


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.

von Micro M. (micromann)


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 ;-)

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.