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
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.
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...
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.
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.
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)
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.
Markus K. schrieb: > Beim Umschalten löst der Pin einen Interrupt aus. Und was hast du zum Entprellen des Schalters unternommen?
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.
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.
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.
Zeig doch mal deinen Code, dann kann man das was zu erzählst auch überprüfen.
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.