Hallo. Ich bin gerade dabei, mit Hilfe mehrerer 2313er für unseren Bogensportverein eine Turnierampel zu bauen. Ich stehe aber momentan vor dem Problem, wie ich jetzt am günstigsten drei Taster an den Mikrocontroller kriege, die alle einen Interrupt 0 auslösen sollen. Das Entprellen habe ich bereits über Monoflops realisiert, aber ich weis jetzt einfach nicht, wie ich die beiden Taster, die an Pin PD0 und PD1 liegen, auch an den Interruptpin PD2 kriege, ohne daß ich bei einem Signal nur an PD2 auch eines an PD0 und PD1 kriege. Zur Entprellung: ich habe (mußte) sie per Hardware machen, da ich den Timer bereits für ein exaktes 1sek-Signal brauche. Falls jemand 'n Vorschlag hat, wäre ich sehr dankbar, ich habe im Moment irgendwie eine Denkblockade und mir fällt nix ein @_@ MfG, Maik Schmidt
Hallo, wenn die Eingänge mit Pullups belegt sind und die Taster/Treiber das einfach nur auf Masse ziehen, brauchst Du nur vom Int-Pin je eine Diode zu den Schaltern zu führen um diesen parallel mit auszulösen. So kommst Du also auf je einen Eingang pro Taster und einen gemeinsamen Interrupt-Eingang. Gruß, Arne
Bis jetzt liegen die Ausgänge der Monoflops (74LS123) direkt an den Portpins des 2313... aber auf die Idee mit den Dioden bin ich natürlich sinnigerweise wieder mal nicht gekommen. Dabei sind 5V - 0,7V immer noch TTL'ige 4,3V high. Was wäre ein Vorschlag für die Pullups? 1kOhm okay? Dankend, Maik Schmidt
Hallo Maik, es ist schade um die Monoflops. Der 2313 hat übrigens 2 Timer. Solltest Du aber den anderen Timer eingesetzt haben, spielt auch das keine Rolle. Sinnigerweise lässt Du den Timer 0 mit z.B. 10 ms laufen. Im Timer0-Interrupt läßt Du eine Registervariablen zaehlen. Von 100 - 0 ergibt dann 1000ms. Weiterhin kannst Du im Timer-Interrupt deine Tasten einlesen und entprellen. Das Sekundensignal, wird dadurch nicht ungenauer. Anmerkung: Genaue Zeiten lassen sich grundsätzlich mit diesen Timern nur realisieren, indem man den Timer durchlaufen lässt. Da das Aufrufen des Interrupt nicht immer gleich lange dauert, würde sonst der Reladwert eventuell 1 oder 2 Takte zu spät in das Timer-Register geschrieben. Bernhard
Okay, das iss natürlich auch 'ne Lösung, wenn ich noch zusätzliche eine Zählvariable nutze. Aber was genau iss jetzt mit "Timer durchlaufen lassen" gemeint? Ich fürchte, da fehlt es mir jetzt an Durchblick. Soll ich den immer GANZ durchlaufen lassen? Alle 256 Zählstufen und dann auf den Overflow reagieren?... Da kann ich doch ebenso gut 'n Reload in den Interrupt packen und als erstes aufrufen. Ich denke mal, bei maximal 999Sekunden Laufzeit der Uhr und 4MHz Takt sollte man da doch noch nichts merken. MfG, Maik
Hallo Maik, es ist richtig, bei 1000 Sekunden ist es nicht wichtig, da Du ja nicht die Relativitätstheorie beweisen willst. Mit "Durchlaufen lassen" meine ich "nicht reloaden". Im Interrupt muss du als erstes, die zu nutzenden Register retten. Spielt aber keine Rolle für das Problem. Wenn ein Interrupt aufgerufen werden soll, wird erst noch der letzte Befehl abgearbeitet. Dieser kann aber mehr als einen Zyklus dauern. Dadurch ist es nicht vorhersehbar wann Du wieder im Interrupt ankommst. Bei 4 MHz sind das ggf. 2x250ns. Als kommt dieser Interrupt mit einer Verspätung von immerhin 5%. Außerdem können sich bei diesem Controller Interrupts nicht gegenseitig unterbrechen. Folge: Dein externer Interrupt kann den Timer-Interrupt-Aufruf erheblich verzoegern. Bernhard
Warum nicht Timer 1 im Clear-On-Compare-Match Mode mit entsprechendem Interrupt nutzen, dann ist der Interrupt-Zyklus in jedem Fall genau.
Hallo, kennt denn der Timer vom 2313er keinen Auto-Reload? Wenn es manuell machen muß, ist die unberechenbare Zeitverzögerung ja klar. Entschuldigt die Frage, aber ich kenn bislang nur MCs-51er und die haben das Problem einfach nicht. Aber man will sich ja weiterbilden... ;-) Gruß, Arne
Also, wie ja schon richtig gesagt wirde, kann ein Timer alles machen, man braucht nicht für jeden Scheiß einen eigenen. Mann muß nur einen kleinsten gemeinsamen Takt haben, aus dem man dann mit Registern alle benötigten Vielfachen erzeugt. Wenns genau sein soll, gibt es prinzipiell 3 Möglichkeiten: - Timer ohne Reload (Überlauf bei 255 bzw. 65535) - Timer mit Clear-On-Compare-Match (T1) - Timer mit Software Reload Beim Software-Reload ist nur zu beachten, daß man es mit einer Addition macht, um die variierende Interrupt-Aufruf-Zeit zu berücksichtigen (Timer läuft ja weiter), z.B.: in ia, tcnt0 subi ia, timer_reload out tcnt0, ia @Arne, auch beim 8051 braucht man Software-Reload, wenn man einen 16-Bit Timer haben will und kein T2 da ist: push psw clr ea ;no additional delay by other interrupts clr tr0 ;no overflow during addition xch a, tl0 add a, #low(8-T0_reload) ;stop for 8 cycle xch a, tl0 xch a, th0 addc a, #high(8-T0_reload) xch a, th0 setb ea ;other interrupts enabled after next instr. setb tr0 pop psw Peter
@Bernhard Auch beim AVR ist es möglich, dass weitere Interrupts innerhalb einer Interrupt-Routine ausgeführt werden können. Dafür gibt es ja den SEI Befehl.
Und hier die Entprellung mit Timer: http://www.mikrocontroller.net/forum/read-4-20435.html Das exakte Software-Reload funktioniert aber nur, wenn man keinen oder einen sehr großen Vorteiler nimmt. Ohne Vorteiler muß man beim Reload 1 abziehen. Mit Vorteiler muß er so groß sein, daß er nie während des Reloads überlaufen kann, d.h. größer als die Ausführungszeit der anderen Interrupts oder einer Interruptsperre. Peter
@Peter Nicht verfügbarer Timer2 ist der Punkt! Dennoch würde ich kein Reload wie Du machen, wenn ich die 16Bit des Timers nicht auswerten muß, sondern einfach eine weiter Variable nehmen und dann mit "DJNZ HilfsByte, TimerEnd" arbeiten. Ebenso läßt sich im Event ZERO das Hilfsbyte auch wunschgemäß setzen, sowie alg. der Reload-Wert des Timers bis zu einem gewissen Minimum besser anpassen. Geht schneller und ist genauer. Gruß, Arne
@Arne "Geht schneller und ist genauer." Weder noch. Du hast ja im 8-Bit-Mode bis zu 256 mal häufigere Interrupts. D.h. 256 * DJNZ ist auf alle Fälle langsamer als 1 * 16-Bit Addition. Genauer ist die 16-Bit-Addition außerdem. Bei Deiner Variante kann es nämlich zu Problemen kommen, wenn das Reload des Low-Byte einen Uberlauf bewirken kann. D.h. nur bei meiner Routine kann man den Reloadwert bequem per EQU-Anweisung auf wirklich jeden Wert zwischen 256...65535 exakt einstellen. Ich benutze sehr oft den AT89C4051 und der hat keinen T2. Peter
@mikki merten, die Behauptung Bedarf aber einer genaueren Erläuterung. Der SEI-Befehl setzt das Global-Interrupt-Flag und ermöglicht es alle Interrupts ein- bzw. abzuschalten. Damit kann ich noch lange keinen Interrupt unterbrechen!! Bernhard
@bernhard Wenn du innerhalb einer Interrupt-Routine nach dem Retten des SREG mittels SEI die Interrupts wieder freigibst, kann die gerade abzuarbeitende Interrupt-Routine von einem weiteren Interrupt unterbrochen werden. In der Praxis bedeutet dies zum Beispiel ein Timer-Interrupt, der z.B. jede ms einmal aufgerufen wird und zu Bearbeitung etwa 30 µs benötigt, kann jederzeit von einem RX/TX Interrupt der z.B. bei 250 kBit alle 40/44 µs auftritt aber zur Bearbeitung nur 3-5 µs benötigt unterbrochen werden.
@mikki Warum soll im Interrupt das Global Interrupt Flag geloescht sein? Der aktuellen Interrupt wäre dann gar nicht ausgelöst worden!! Ausserdem habe ich mir gerade die beiden Befehle sei und cli noch einmal genauer angeschaut. Ich sehe dort keinen Hinweis der in die Richtung geht. Wo hast Du diese Information her??? Bernhard
@mikki Du könntest recht haben, da der Interrupt-Einsprung das I-Bit loescht. Wäre interessant. Werde mich morgen noch einmal melden
@Bernhard Wenn die AVR keine verschachtelten Interrupts unterstützen würde, hätte ich diese wohl schon lange entsorgt. Aber schau mal in den Datenblättern unter dem Abschnitt "Reset and Interrupt Handling". Dort findest du eine recht gute Beschreibung.
@mikki Asche auf mein Haupt. Du hast recht und das ist auch gut so. Ich habe bisher in den unkritischen Interrupt immer fast nichts ( oft eigentlich zu wenig ) getan, um die wichtigen nicht zu verzögern. Danke für den Hinweis. Bernhard
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.