geht das bei einem Atmega16? ich hab hier DDRD = 0xFF; if(PORTD & (1<<6)) {...} ist das zulässig oder muss ich erst DDRD = 0x00; machen gruss, daniel
Hi Du kannst den Port ganz normal als Register lesen. MfG Spess
Was willst Du denn machen?
Selbstverständlich kannst Du vom aktuellen Zustand eines auf "Ausgang"
konfigurierten Ports Kenntnis erlangen, indem Du das zugehörige
PORT-Register liest.
>ist das zulässig oder muss ich erst DDRD = 0x00; machen
Natürlich ist es zulässig (es gibt keine Instruktionsfolge, durch die
ein µC Schaden nehmen könnte), aber der Port wäre ab dann als Eingang
geschaltet.
Nochmal: Was willst Du machen?
PORTD liefert einfach den Wert zurück, den du zuletzt hinein geschrieben hast. PIND liefert den Wert, der tatsächlich an den Portpins anliegt. Die beiden Werte sind normalerweise gleich, weswegen man besser PORTD abfragt. Unterschiede ergeben sich bspw. dann, wenn ein Ausgang gegen GND oder VCC kurzgschlossen wird (was anständige Leute aber nicht machen).
Musst du nicht. Wenn du den tatsächlichen Zustand einlesen willst, musst du aber das Register PIND benutzen, nicht PORTD.
Detlev T. wrote: > Musst du nicht. Wenn du den tatsächlichen Zustand einlesen willst, musst > du aber das Register PIND benutzen, nicht PORTD. Wenn der Pin Ausgang ist und PIND etwas anderes zurückliefert als PORTD, dann ist etwas kaputt... Oder Du hast etwas stark kapazitives am Ausgang, was erst verzögert den Pegel anpasst.
Danke für die zahlreichen Antworten! was ich machen will ... ich habe am Port D 2 Taster und 2 LEDs angeschlossen. #define TASTE1 2 #define TASTE2 3 #define LED1 5 #define LED2 6 dementsprechend habe ich auch DDRD = 0xFF; DDRD &= ~(1<<TASTE1); DDRD &= ~(1<<TASTE2); in while(1) Schleife will ich nun den Tastendruck abfangen und zwar mit if(PORTD & (1<<TASTE1)) { // Taste1 gedrückt } der Port als ganzes ist weder als Ausgang noch als Eingang konfiguruert. Ist es OK mit PORTD die Tasten, die als Eingang konfiguriert sind, auszulesen? Oder ist es eine Frage des guten Stils hier mit PIND auszulesen? ich bin kompleter Newbe in der uc-Welt (allerdings nicht in der Programmiererei an sich) grüsse, Daniel
>Ist es OK mit PORTD die Tasten, Nein, den Eingangs-Zustand des Ports liest man immer mit PIND ein. >der Port als ganzes ist weder als Ausgang noch als Eingang >konfiguruert Wie sich die einzelnen Pins verhalten, legt das DDRD fest. Du schaltest also immer zwischen Eingang und Ausgang um. Es sollte mit der PIND-Änderung aber funktionieren.
Ich denke die Verwirrung bei daniel legt sich, wenn er weiss, dass der Port auch 'mischkonfiguriert' werden kann. Es ist völlig ok, wenn du am Port die Pins 2 und 3 aus Ausgang konfigurierst und die Pins 5 und 6 als Eingang. Es ist nicht so, dass alle Portpins gleich konfiguriert werden muessen. Du willst 2 und 3 als Ausgang und 5 und 6 als Eingang. Ausgang heist an der entsprechenden Stelle ein 1-Bit, während Eingang eine 0 an der entsrechenden Bitposition erfordert. Da dann noch ein paar Bits übrig sind, deren Richtung erst mal nicht weiter ineterssiert, konfigurierst du die einfach mal als Eingang. Das DDRD muss also sein 7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | +---+---+---+---+---+---+---+---+ E E A A Hexadezimal ist das die Zahl 0x0C Wenn du also DDRD auf 0x0C setzt, dann kannst du ohne Neukonfiguration des Ports auf den Bits 2 und 3 mittels Zuweisung an PORTD einen Wert setzen, während du durch Lesen von PIND und entsprechende Bitmanipulationen zum herausholen der Bits, die Bits 6 und 5 lesen kannst. > Oder ist es eine Frage des guten Stils hier > mit PIND auszulesen? Das hat nichts mit Stil zu tun. Mit PORTX setzt man Werte, so dass eine an den Pin angehängte Elektronik die entsprechenden Spannungspegel sieht. Mit PINX holt man sich die Werte, die eine externe Elektronik an die entsprechenden Pins angelegt hat. Auch wenns für Assembler ist, lies es dir trotzdem durch. http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen
Ich versuch's mal zusammenzufassen Dem PORTD wird ein 8 bittiger Wert zugewiesen, aber nur die Pins können aussen etwas treiben(LED zB), die als Ausgang konfiguriert sind. Pins, die als Eingang konfiguriert werden, "sprechen nicht an den zugewiesenen Wert an". Wenn man dagegen mit PIND einen 8 bittigen Wert ausliest, dann könnte theoretisch in denen, als Ausgang konfigurierten Pins Müll drin stehen (Müll=kein sicherer Wert, mal 0, mal 1). Man dürfte dann nur Pins ausmaskieren und verwenden, die als Eingang konfiguriert waren. Ich hoffe diesmal ist es richtig :)
Hi Fast. Wenn die Werte der als Ausgang definierten Pins in PortX und PinX nicht übereinstimmen, hast du ein massives Hardwareproblem. MfG Spess
daniel wrote: > Ich versuch's mal zusammenzufassen > > Dem PORTD wird ein 8 bittiger Wert zugewiesen, aber > nur die Pins können aussen etwas treiben(LED zB), die als > Ausgang konfiguriert sind. Pins, die als Eingang > konfiguriert werden, "sprechen nicht an den zugewiesenen Wert an". Nicht wirklich. SIeh dir den Link an den ich dir gepostet habe. Am Ende der Seite ist eine Zusammenfassung. Ist ein Pin auf Eingang geschaltet, dann hat eine Zuweisung an die entsprechende Bitposition in einer PORTX Zuweisung eine Spezialfunktionalität: Es schaltet den zugehörigen Pull Up Widerstand ein. > > Wenn man dagegen mit PIND einen 8 bittigen Wert ausliest, dann > könnte theoretisch in denen, als Ausgang konfigurierten Pins Müll > drin stehen (Müll=kein sicherer Wert, mal 0, mal 1). Auch das stimmt so nicht. Du liest dan von den Bitpositionen den Wert ein, den du zuletzt mittels einer PORTX Zuweisung dort hingeschrieben hast. Es ist also nicht zufällig was da daherkommt. Sofern du nicht ein Hardwareproblem hast und extern den Ausgangspin auf einen Pegel zu ziehen versuchst. Aber davon gehen wir mal nicht aus. Der Ausgansgtreiber wird sich nun mal schwer tun einen Ausgangspin auf 1 zu ziehen, wenn du ihn extern mit GND verbunden hast. Du schreibst dann zwar mit einem PORT eine 1 raus, der PIN würde aber 0 liefern, weil ja der Ausgang tatsächlich 0 ist und der Ausgangstreiber ihn einfach nicht auf 1 kriegt. > Man dürfte dann nur Pins ausmaskieren und verwenden, > die als Eingang konfiguriert waren. Das sowieso.
Ok, danke. Wie sind die Pins mit den externen Interrupts in dieser Hinsicht zu behandeln? Soll ich sie als Eingänge konfigurieren? grüsse, daniel
wenn ich alle 8 bits des Ports auf Eingang schalte, kann ich dann den Ausgangsport als zusätzliches Register verwenden? Ob das sinnvoll ist, weiß ich noch nicht, habe ich mir noch keine Gedanken gemacht, darum ist das nur theoretisch, um mein Wissen zu vervollkommnen. mfg
Wolfram Quehl wrote: > wenn ich alle 8 bits des Ports auf Eingang schalte, kann ich dann den > Ausgangsport als zusätzliches Register verwenden? Nicht wirklich. Durch beschreiben des PORT Registers schlaltest du ja ständig die Pull Up Widerstände ein und aus. Gut. Wenn da jetzt nichts an diesen Pins elektrisch abgeschlossen ist, dann würde das gehen. > Ob das sinnvoll ist, Ganz ehrlich. Auf so eine Idee ist wohl noch niemand in diesem Forum gekommen. Das ist schon fast pervers :-)
Hi @ Karl Heinz >Ganz ehrlich. Auf so eine Idee ist wohl noch niemand in diesem >Forum gekommen. >Das ist schon fast pervers :-) Falsch. Die Antwort hast du dir schon selbst gegeben: >Durch beschreiben des PORT Registers schaltest du ja ständig >die Pull Up Widerstände ein und aus. Genau deshalb MUSS man den Port lesen und mit der Ausgabe verknüpfen wenn man die internen PullUps verwendet. Ein Port-Register ist de Facto ein Speicherplatz. Ihn als solchen zu benutzen ist nicht pervers, sondern zeugt vom Einfallsreichtum des Programmierers. Nur mal ein sinnvolles Beispiel: Du willst ein Pin toggeln in r16,PortX eor r16, PinMask out PotrX,t16 damit sparst du dir die Speicherung des Pinzustandes an anderer Stelle. MfG Spess
spess53 wrote:
> damit sparst du dir die Speicherung des Pinzustandes an anderer Stelle.
Ich habe die Fragestellung eher so aufgefasst, dass
der Port gar nicht als Port benutzt werden soll, sondern
einfach nur als ganz normales Register, indem zb. der
aktuelle Mehrwertsteuersatz gespeichert wird.
Ich finde diese Idee schon etwas pervers.
Hi @ Karl Heinz Wenn mit dem 'Missbrauch' eines IO-Registers als Speicher keine Nebeneffekte hervorruft (z.B total ungenutzter Port) hätte damit keine Probleme. MfG Spess
In der hardwarenahen Programmierung ist PP (perverse Programmierung) erlaubt, wenn sie zweckdienlich ist. Auf einem RAM-losen ATtiny ist man vielleicht manchmal froh, zusätzlich zu den 32 offiziellen Datenregistern noch ein paar ungenutzte Port-, Timer- oder sonstige I/O-Register zur Datenspeicherung nutzen zu können. PP gab's bspw. auch auf 68000-Prozessoren, wo manch einer die obersten 8 Bits der 32-Bit-Adressregister zur Datenspeicherung genutzt hat, da bei dem Prozessor nur 24 Adressleitungen herausgeführt sind. Pech halt, wenn die Software irgendwann auf einem 68020 mit vollem 32-Bit-Adressbus laufen sollte.
spess53 wrote: > Hi > > @ Karl Heinz > > Wenn mit dem 'Missbrauch' eines IO-Registers als Speicher keine > Nebeneffekte hervorruft (z.B total ungenutzter Port) hätte damit keine > Probleme. Oh. Probleme hab ich auch keine damit. Nur war die Idee für mich nicht so naheliegend, wie sie für euch (dich und yalu) zu sein scheint. OK. Nehme das pervers zurück.
Moin, Wenn der Port als Eingang geschaltet werden soll, kann man bei neueren AVRs (z.B. Tiny24/44/84) wohl auch das Port-globale PullUp-Disable-Bit setzen. Dann dürfte PORTx überhaupt keine Auswirkungen haben, also frei als Speicherregister verwendbar sein. (bevor das jemand ausprobiert, bitte nochmal genau im Datenblatt nachlesen - ich hab das nie gebraucht und bisher immer nur überflogen) MfG, Heiko
He Ro wrote: > Moin, > > Wenn der Port als Eingang geschaltet werden soll, kann man bei neueren > AVRs (z.B. Tiny24/44/84) wohl auch das Port-globale PullUp-Disable-Bit > setzen. Dann dürfte PORTx überhaupt keine Auswirkungen haben, also frei > als Speicherregister verwendbar sein. > > (bevor das jemand ausprobiert, bitte nochmal genau im Datenblatt > nachlesen - ich hab das nie gebraucht und bisher immer nur überflogen) Bei batteriebetriebenen Geräten ist das aber trotzdem nicht ganz unbedenklich. Wenn ein Pin als Eingang geschalten ist, nix dranhängt und der PullUp aus ist, dann beginnt das Ding zu floaten und der Controller zieht unter Umständen ein Vielfaches des vorgesehenen Stromes. Auszug aus dem Datenblatt vom ATmega48/88/168: Port Pins When entering a sleep mode, all port pins should be configured to use minimum power. The most important is then to ensure that no pins drive resistive loads. In sleep modes where both the I/O clock (clkI/O) and the ADC clock (clkADC) are stopped, the input buffers of the device will be disabled. This ensures that no power is consumed by the input logic when not needed. In some cases, the input logic is needed for detecting wake-up conditions, and it will then be enabled. Refer to the section “Digital Input Enable and Sleep Modes” on page 75 for details on which pins are enabled. If the input buffer is enabled and the input signal is left floating or have an analog signal level close to VCC/2, the input buffer will use excessive power. For analog input pins, the digital input buffer should be disabled at all times. An analog signal level close to VCC/2 on an input pin can cause significant current even in active mode. Digital input buffers can be disabled by writing to the Digital Input Disable Registers (DIDR1 and DIDR0). Refer to “DIDR1 – Digital Input Disable Register 1” on page 243 and “DIDR0 – Digital Input Disable Register 0” on page 259 for details.
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.