Forum: Mikrocontroller und Digitale Elektronik port lesen wenn es als ausgang konfiguriert ist


von daniel (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

Du kannst den Port ganz normal als Register lesen.

MfG Spess

von AVRFan (Gast)


Lesenswert?

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?

von yalu (Gast)


Lesenswert?

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

von Detlev T. (detlevt)


Lesenswert?

Musst du nicht. Wenn du den tatsächlichen Zustand einlesen willst, musst 
du aber das Register PIND benutzen, nicht PORTD.

von Johannes M. (johnny-m)


Lesenswert?

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.

von daniel (Gast)


Lesenswert?

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

von mehrfacher STK500-Besitzer (Gast)


Lesenswert?

>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.

von Karl H. (kbuchegg)


Lesenswert?

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

von daniel (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

Fast. Wenn die Werte der als Ausgang definierten Pins in PortX und PinX 
nicht übereinstimmen, hast du ein massives Hardwareproblem.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

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.

von daniel (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

Ja.

MfG Spess

von Wolfram Q. (quehl)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von yalu (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von He Ro (Gast)


Lesenswert?

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

von Philipp B. (philipp_burch)


Lesenswert?

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
Noch kein Account? Hier anmelden.