Forum: Mikrocontroller und Digitale Elektronik Input nicht lesbar, wenn keine 1 im Datenregister liegt


von Baran (ligabeast)


Angehängte Dateien:

Lesenswert?

Programmiersprache : C

MC : Arduiono 328p

Guten Tag,

ich habe ein Programm geschrieben das lediglich ein Input einließt und 
dazu eine LED anschalten soll. Ich hatte lange das Problem das ich kein 
Input einlesen konnte. Habe mein Programm angehangen, als Screenshot.


Ich frage mich wieso ich "PORTD = 0x0C" brauche. Ohne funktioniert mein 
Input nicht. Mir ist klar, dass ich damit den Datenregister für die 
Inputs 1 setze, aber ich frage mich wieso ich das muss. Wenn ich die 
Taste nicht drücke, sind doch meine Datenbits sowieso 1 oder (Active 
Low)?

von S. Landolt (Gast)


Lesenswert?

Es scheint, als sei der Taster gegen Masse geschaltet und der externe 
Pullup-Widerstand fehlt. Mit dem 'PORTD = 0x0C' wird der interne 
eingeschaltet:
'If PORTxn is written logic one when the pin is configured as an input 
pin, the pull-up resistor is activated.'

von Ralf G. (ralg)


Lesenswert?

https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

Abschnitt 13.2.1 ... 13.2.6

Wenn du das verstanden hast, wirst du auch merken, dass noch ein paar 
Fehler in deinem Programm sind, die dir bei eventuellen Erweiterungen 
auf die Füße fallen.

von S. Landolt (Gast)


Lesenswert?

> Wenn ich die Taste nicht drücke, sind doch
> meine Datenbits sowieso 1

Keineswegs - ein Controllereingang ist, ohne weitere Beschaltung, 
hochohmig, er befindet sich auf dem Potential, das er sich gerade 
zufällig über irgendwelche Störungen einfängt.

von Genauigkeitsfanatiker (Gast)


Lesenswert?

S. Landolt schrieb:
> ein Controllereingang ist, ohne weitere Beschaltung,
> hochohmig,

Präziser: ohne weitere Beschaltung und Konfiguration
Wenn der Pullup eingeschaltet wird, ist der offene Eingang 1.

von HildeK (Gast)


Lesenswert?

Nehmen wir das mal auseinander:

- DDRB = 0b00000011; Hast du zwei LEDs? Es wird hier Pin 0 und 1 als 
Ausgang definiert. Eigentlich solltest du alle als Ausgang definieren, 
denn dann floaten sie nicht - egal was du auf PortB schreibst. Sie 
bewegen sich dann aber alle.

- PORTD = 0x0C; Da der Port im Defaultzustand auf Input steht, 
aktivierst du den Pullup an den beiden Pins. Die anderen Pins des PORTD 
sind wieder offene Eingänge. Besser dann alle mit Pullup versehen, also 
PORTD = 0xFF;

- PORTB = 0xFF; Schaltet PB0 und PB1 auf HIGH und an PB2...PB7 wird der 
PU aktiviert. Bis hierher o.k. wobei du vermutlich nur eine LED schalten 
willst. Zumindest verhindert dieser Befehl, dass in der Phase die 
restlichen Pins des PortB floaten.

- PORTB = 0x00;  Ja, schaltet die PB0 und PB1 auf LOW, die anderen Pins 
des PORTB jedoch auf hochohmig, denn es sind ja Eingänge, die du mit dem 
DDRB definiert hast. Und bei denen schaltest du jedes Mal den PU an bzw. 
aus.

Angenommen du hast nur eine LED und die hängt an PB0, dann wäre es 
besser, wenn du stattdessen die Einzelbitbefehle nehmen würdest:
- PORTB |= (1<<PB0);  zum Einschalten und
- PORTB &= ~(1<<PB0); zum Ausschalten der LED.
alternativ (es ist dasselbe):
- PORTB |= 0b00000001; bzw.
- PORTB &= ~0b00000001;
und falls doch an beiden Pins LEDs hängen, dann wird eben aus
(1<<PB0) stattdessen ((1<<PB0) | (1<<PB1)) bzw. binär 0b00000011, 
jeweils mit oder ohne die Tilde.

Deine Frage implizierte, dass du Anfänger bist. Deshalb meine 
Ausführlichkeit. Der Teil ist eines der ersten, die du dir sicher 
aneignen solltest.
Dazu gibt es auch ein schönes Kapitel im 
AVR-GCC-Tutorial: Zugriff auf IO-Ports, was ich dir wärmstens 
empfehle!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Baran schrieb:
> Wenn ich die Taste nicht drücke, sind doch meine Datenbits sowieso 1
> oder (Active Low)?
Nimm einfach mal ein Messgerät/Multimeter und miss die Spannung direkt 
am Pin. Das ist nämlich dann der Pegel, den dein Programm einlesen wird.

Wenn der Pegel weder 0V bzw 5V (oder 3V3) ist, dann passt irgendwas mit 
der Beschallung nicht und du wirst nichts Brauchbares auswerten können.

Und wenn das mit der Hardware samt den Pegeln an den Pins dann passt, 
dann kannst du dich um die Software kümmern.

: Bearbeitet durch Moderator
von W.S. (Gast)


Lesenswert?

Lothar M. schrieb:
> Nimm einfach mal ein Messgerät/Multimeter und miss die Spannung direkt
> am Pin. Das ist nämlich dann der Pegel, den dein Programm einlesen wird.

Sobald man mit einem heutigen Multimeter die Spannung an einem 
Eingangspin mißt, reicht der Innenwiderstand des Meßgerätes aus, um den 
Pegel auf 0 zu kriegen. Eben deshalb gehört VOR dem Benutzen irgend 
eines µC eigentlich das Erwerben von (wenigstens Basis-)Kenntnissen der 
Schaltungstechnik. Aber so etwas liegt gar vielen Leuten hier sehr fern. 
Man ist lieber reiner Programmierer.

W.S.

von Baran (ligabeast)


Lesenswert?

Zunächst danke ich dir vielmals für die Ausführliche Beschreibung.

Ich habe soweit alles umgesetzt und auch verstanden.

" DDRB = 0b00000011; Hast du zwei LEDs? Es wird hier Pin 0 und 1 als
Ausgang definiert. Eigentlich solltest du alle als Ausgang definieren,
denn dann floaten sie nicht - egal was du auf PortB schreibst. Sie
bewegen sich dann aber alle."

- Meine Beschreibung war falsch, du hast vollkommen recht ich hab zwei 
LEDs. Leider verstehe ich noch nicht ganz was du mit floaten meinst.

Zudem ist die verlinkte Seite echt Super.

Mit freundlichen Grüßen
Baran

von HildeK (Gast)


Lesenswert?

Baran schrieb:
> Leider verstehe ich noch nicht ganz was du mit floaten meinst.

'Floaten' ist 'denglisch', kommt von 'to float' und heißt schweben, 
schwimmen.
Die Eingänge von CMOS-Bausteine sind so hochohmig, dass bereits 
elektrische Felder, Störungen, ja bereits das Hand auflegen den Pegel 
beeinflussen kann. Er schwankt dann zwischen GND und VCC auf nicht 
vorhersehbare Weise, manchmal sogar verbunden mit dann deutlich erhöhter 
Stromaufnahme des Bausteins (je nach Eingangstyp).

Das muss man vermeiden und wird dadurch, dass man entweder extern einen 
Widerstand nach +VCC oder GND (Pull-Up [PU] oder Pull-Down [PD]) 
schaltet oder eben die im µC meist intern vorhandenen verwendet. PUs 
sind fast überall in µCs vorhanden, PDs seltener. Bei CMOS-Gattern fast 
nirgends, da muss man unbenutzte Eingänge immer irgendwo anbinden - 
entweder direkt an GND oder VCC oder über eine Widerstand.
Für deinen Taster reicht bei kurzen Leitungen und unauffälliger 
Störumgebung der interne PU, der so ca. 30k-50k hat.
Ich selber nehme lieber einen deutlich niederohmigeren externen 
Widerstand im Bereich 1k-5k, je nach Betriebsspannung und Forderung an 
die Betriebssicherheit - natürlich auf Kosten eines etwas höheren Stroms 
beim Drücken der Taste. Der tun einige wenige mA übrigens auch gut 😀.

Der relativ hochohmige interne Widerstand könnte bereits durch 
Schaltfunken wie beim Schalten von Lötkolben, Leuchtstofflampen, aber 
auch durch Dimmer oder Handy überstimmt werden und dadurch einen 
falschen Pegel (kurzzeitig) annehmen. Und die Schaltung spinnt dann ...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

HildeK schrieb:
> eines etwas höheren Stroms beim Drücken der Taste. Der tun einige
> wenige mA übrigens auch gut 😀.
Der Hintergrund dazu nennt sich "Frittspannung" bzw. "Frittstrom".

Baran schrieb:
> ich habe ein Programm geschrieben
Man hängt Sourcecode nicht als Bild an, weil sich dort richtig schlecht 
drin editieren oder etwas herauskopieren lässt. Verwende einfach die [c] 
Tags, wie über jeder Editbox gleich unter dem Hinweis *"Wichtige Regeln 
- erst lesen, dann posten!"* beschrieben ist.

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.