Forum: Mikrocontroller und Digitale Elektronik Fragen zu normaler Schalter an µC-Input-Pin


von Markus K. (mako)


Lesenswert?

Hi,

ich möchte einen Schalter und keinen Taster an einem Input-Pin eines 
atmega anschließen.
Verwende dazu den internen Pullup.
Und das funktioniert auch soweit mit den Interrupts während des 
Betriebs.

Wenn der Schalter aber während des Boots geschlossen ist, bekomme ich 
nicht sofort den richtigen Wert beim auslesen des Port-Pins. Wie bekommt 
man das hin?

Außerdem ist in diesem Fall ja eigentlich die Initialisierung nicht 
sauber.
Vielleicht liegt obiges auch daran.
Was ich meine... Beim Boot ist der Pin ja zunächst default als Input 
ohne Pullup konfiguriert. Der Schalter aber schon geschlossen. Also 
eigentlich nicht ideal.
Der Pullup wird dann kurz darauf mit den ersten Befehlen aktiviert.
Aber in der Zwischenzeit...? Kann da der Pin kaputt gehen?
Das Problem besteht eigentlich auch bei einem Taster, wenn dieser 
während des Boots gedrückt gehalten wird.

Wie handhabt man sowas?
Braucht es da zwingend einen externen Pullup oder mache ich bei der 
Konfiguration des Pin etwas falsch?

Danke

von lirum (Gast)


Lesenswert?

Markus K. schrieb:
> Wenn der Schalter aber während des Boots geschlossen ist, bekomme ich

Schaltung? Weil was bedeutet geschlossen? High oder Low?

> nicht sofort den richtigen Wert beim auslesen des Port-Pins. Wie bekommt
> man das hin?

Was soll denn dann der "richtige" Wert sein? Wie man das hin bekommt - 
Statt sofort, etwas warten bis man ausliest.

von c-hater (Gast)


Lesenswert?

Markus K. schrieb:

> ich möchte einen Schalter und keinen Taster an einem Input-Pin eines
> atmega anschließen.

Ob Schalter oder Taster ist komplett irrelevant, beides sind mechanische 
Kontakte und sie sehen aus der Sicht des µC völlig gleich aus.

> Verwende dazu den internen Pullup.

Warum auch nicht, dazu gibt's den ja.

> Und das funktioniert auch soweit mit den Interrupts während des
> Betriebs.

Was haben Interrupts damit zu schaffen?

> Wenn der Schalter aber während des Boots geschlossen ist, bekomme ich
> nicht sofort den richtigen Wert beim auslesen des Port-Pins.

Da steckt der Fehler. Du mußt natürlich nach einem Reset als erstes den 
Pullup einschalten, dann (mindestens) einen Takt warten und erst dann 
liefert der Input den korrekten Wert. Das hat allerdings mit der 
Problematik "Taster vs. Schalter" genausowenig zu schaffen wie mit 
"Interrupt vs. Polling". Es liegt einfach daran, dass die Eingänge mit 
dem Systemtakt synchronisiert werden, und dass deswegen der gelesene 
Eingabewert der physischen Realität immer mindestens einen Tick 
hinterhängt.

Steht übrigens so auch in jedem verschissenen AVR8-Datenblatt. Man muß 
einfach mal nur wenigstens eins davon richtig lesen...

von Wolfgang (Gast)


Lesenswert?

Markus K. schrieb:
> Wenn der Schalter aber während des Boots geschlossen ist, bekomme ich
> nicht sofort den richtigen Wert beim auslesen des Port-Pins. Wie bekommt
> man das hin?

Das wird entweder an deiner Beschaltung, an deinem Programmablauf oder 
an Störungen liegen. Da kann man ohne weitere Informationen nur raten.
Der Maßstab für "sofort" kann abhängig vom Zeitgefühl sehr 
unterschiedlich sein. Ein Mensch beurteilt das sicher anders, als ein µC 
mit 16MHz Taktfrequenz oder gar ein FPGA.

von Markus K. (mako)


Lesenswert?

c-hater schrieb:
>> Und das funktioniert auch soweit mit den Interrupts während des
>> Betriebs.
>
> Was haben Interrupts damit zu schaffen?

Beim Umschalten löst der Pin einen Interrupt aus.

>
>> Wenn der Schalter aber während des Boots geschlossen ist, bekomme ich
>> nicht sofort den richtigen Wert beim auslesen des Port-Pins.
>
> Da steckt der Fehler. Du mußt natürlich nach einem Reset als erstes den
> Pullup einschalten, dann (mindestens) einen Takt warten und erst dann
> liefert der Input den korrekten Wert. Das hat allerdings mit der
> Problematik "Taster vs. Schalter" genausowenig zu schaffen wie mit
> "Interrupt vs. Polling". Es liegt einfach daran, dass die Eingänge mit
> dem Systemtakt synchronisiert werden, und dass deswegen der gelesene
> Eingabewert der physischen Realität immer mindestens einen Tick
> hinterhängt.

Der Pull-Up ist aktiviert bevor ich am Pin lese. Hast du falsch 
verstanden.
Auch am Takt liegt es nicht, weil zwischen Pull-up aktivieren und Pin 
lesen einiges anderes noch passiert. Verschiedene Funktions-Aufrufe.
Daran dürfte es also nicht liegen.

von Ulrich F. (Gast)


Lesenswert?

Markus K. schrieb:
> Daran dürfte es also nicht liegen.
Dann liegts an was anderem.

Deiner Beschreibung nach, machst du alles richtig.
Also läuft was schief, was nicht in deiner Prosa auftaucht.

Aber da sowohl Code, als auch Schaltung geheim sind....
Tuts auch meine Glaskugel nicht.
(die ist sowieso gerade recht trübe)

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Wenn man natürlich:

1. Interrupts aktiviert
2. Port-Pins initialisiert

dann passiert sowas.

Überlege mal was man an der Reihenfolge ändern könnte damit dein Problem 
beseitigt ist.

von Wolfgang (Gast)


Lesenswert?

Markus K. schrieb:
> Beim Umschalten löst der Pin einen Interrupt aus.

Und was hast du zum Entprellen des Schalters unternommen?

von lirum (Gast)


Lesenswert?

Markus K. schrieb:
> Daran dürfte es also nicht liegen.

Dann ist alles klar. Vor aktivieren der Interrupts das entsprechende 
Interrupt Flag manuell löschen.

von c-hater (Gast)


Lesenswert?

Markus K. schrieb:

> Der Pull-Up ist aktiviert bevor ich am Pin lese.

Wie lange davor? Einen Takt oder zwei? Genau das ist der springende 
Punkt.

Aber du hast offensichtlich nichtmal das verstanden, weswegen ich dich 
hier unmittelbar als hoffnungslosen Fall eine vollständig Merkbefreiten 
abschreibe.

von Markus K. (mako)


Lesenswert?

Vielleicht nochmal von vorne...

1. Ich schließe den Pin an GND an.
2. Der µC bekommt Saft.
3. Ich habe einen Active-Low-Input-Pin mit aktiviertem internen Pullup.
4. Ich lese den Pin: High (warum?)
5. Ich entferne die Pin Verbindung zu GND.
6. Ich lese den Pin: High
7. Ich verbinde Pin wieder mit GND.
8. Ich lese den Pin: Low

Bei 4. bekomm ich beim Pin auslesen immer High, egal ob Pin an GND oder 
nicht.

von Ich (Gast)


Lesenswert?

Zeig doch mal deinen Code, dann kann man das was zu erzählst auch 
überprüfen.

von Markus K. (mako)


Lesenswert?

Markus M. schrieb:
> Wenn man natürlich:
>
> 1. Interrupts aktiviert
> 2. Port-Pins initialisiert
>
> dann passiert sowas.
>
> Überlege mal was man an der Reihenfolge ändern könnte damit dein Problem
> beseitigt ist.

Also folgendes wird aufgerufen...

#define PINE_MASK ((1<<PINE2)|(1<<PINE3))

DDRE = 0x00;
PORTE |= PINE_MASK;
PCMSK0 = PINE_MASK;
PCMSK1 = PINB_MASK;
EIFR = (1<<PCIF0)|(1<<PCIF1);
EIMSK = (1<<PCIE0)|(1<<PCIE1);

PORTE |= (1 << PINE5);
DDRE &= ~(1 << DDE5);
PCMSK0 |= (1 << PINE5);


Geht das nicht, dass ich anschließend den PINE5 nachträglich 
"hinzufüge"?
Muss ich da EIMSK nochmal nullen?

von Markus K. (mako)


Lesenswert?

Ok. Sorry. War doch ein kleiner Logik-Bug.

von Peter D. (peda)


Lesenswert?

Markus K. schrieb:
> Wie handhabt man sowas?

Man nimmt einfach keinen externen Interrupt.
Obwohl gleich wieder die Nörgler kommen werden, auch Schalter zu 
entprellen ist kein Unsinn. Bei offenem Schalter können Störungen 
einstrahlen bzw. beim Betätigen vom externen Interrupt mehrmals ein/aus 
erkannt werden.

Ein Entprellen im Timerinterrupt kostet kaum Ressourcen und kann mehrere 
Pins zugleich behandeln. Ob man dann die Flanke oder den Zustand 
auswertet, hängt von der gewünschten Funktion ab.

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.