www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Drei Taster auf einen Int0 Pin?


Autor: Maik Schmidt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Arne K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Maik Schmidt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Bernhard Koopmeiners (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Maik Schmidt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Bernhard Koopmeiners (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: mikki merten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum nicht Timer 1 im Clear-On-Compare-Match Mode mit entsprechendem 
Interrupt nutzen, dann ist der Interrupt-Zyklus in jedem Fall genau.

Autor: Arne K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: mikki merten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Arne K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Bernhard Koopmeiners (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: mikki merten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Bernhard Koopmeiners (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Bernhard Koopmeiners (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@mikki
Du könntest recht haben, da der Interrupt-Einsprung das I-Bit loescht. 
Wäre interessant. Werde mich morgen noch einmal melden

Autor: mikki merten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Bernhard Koopmeiners (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.