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
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
Ü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
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
> 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
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.