Moin,
Gibt es eine Möglichkeit von mehr als zwei Tastern einen Interrupt
auslösen zu lassen? Es gibt ja da zwei externe Interrupts, aber ich
brauche drei Taster, die drei verschiedene Interrupts auslösen. Das
müssen Interrupts sein, über eine Abfrage in einer Schleife geht das
nicht.
(PS:Wer meine letzte Frage hier in dem Forum gelesen hat, ich habe einen
neuen 78S05 gekauft, hält zwei Ampere aus und jetzt funktioniert alles
einwandfrei. Liegt aber nicht am Strom, irgendwie war der alte 7805
kaputt. Weiß nur nicht, ob der von Anfang an kaputt war, oder ob das
meine Dummheit war.)
Du könntest die beiden über Dioden an einen Externen Interrupt-Eingang
hängen. Dann könntest du zumindest den Controller wecken.
Allgemein fragt man Taster in regelmässigen Abständen (zig
Millisekunden) ab und entprellt sie auch auf diese Weise...
Tschuldigung, schon wieder den Typ vergessen. Ist ein ATMega8.
Wie soll das mit den Dioden gehen? Die Interrupts werden bei laufendem
Controller ausgeführt, dienen nicht dazu den Controller wieder aus dem
Ruhezustand zurückzuholen
>Das müssen Interrupts sein, über eine Abfrage in einer Schleife geht das>nicht.
Warum geht das nicht? Eigentlich geht das immer.
Ansonsten: Jede Taste auf den externen Interrupt, sowie auf einen
eigenen Portpin parallelschalten, und den Port in der ISR auswerten.
Soviel Zeit muß sein.
Oliver
Dussel wrote:
> Gibt es eine Möglichkeit von mehr als zwei Tastern einen Interrupt> auslösen zu lassen? Es gibt ja da zwei externe Interrupts, aber ich> brauche drei Taster, die drei verschiedene Interrupts auslösen. Das> müssen Interrupts sein, über eine Abfrage in einer Schleife geht das> nicht.
Und wo ist das Problem ?
Wenn die MC-Entwickler der Meinung währen, externe Interrupts sind gut
geeignet um Tasten zu entprellen, dann hätten sie auch mehr davon
eingebaut.
Anders gesagt, sie sind es nicht.
Nimm besser nen Timerinterrupt für egal wieviel Tasten.
Schau einfach mal in die Codesammlung.
Peter
Taster sollten den µC über Interrupt wecken bzw. die Interrupt-Routine
starten. Dass man danach mit Timern entprellen kann/muss, ist klar.
Es gibt viele Anwendungen, in denen der µC schläft und nur auf eine
Taste (oder was anderes) wartet. Da wird man doch nicht polling machen.
Beispiel Taschenrechner - da macht jede Taste einen Interrupt.
Klar - polling geht immer. Man kann auch Timing mit
Verzögerungsschleifen machen. Aber dafür sind die Interrupts ja da.
Eigentlich ist unser ganzes Leben interruptgesteuert (=externe
Ereignisse). Wir gucken ja auch nicht alle 30 Sekunden an der Tür, ob da
jemand ist...
So jetzt könnt ihr darüber ablästern.
@ Peter Dannegger:
Selbstverständlich sind INTs zum erkennen von Tastendrücken (?) da! Die
Entwickler haben sich dabei schon was gedacht, nämlich dass beliebig
viele Tasten (Kontakte) den INT auslösen können, wie oben schon gesagt:
Diodenentkoppelt. Die Auswertung der Tasten (Kontakte) und die
Entprellung macht man nach ausgelöstem INT per Timer-INT und gesperrtem
Tasten-INT. Das ermöglicht einen Sleep-Mode des µC und kostet keine
Polling-Zeit.
Tom wrote:
> Es gibt viele Anwendungen, in denen der µC schläft und nur auf eine> Taste (oder was anderes) wartet. Da wird man doch nicht polling machen.> Beispiel Taschenrechner - da macht jede Taste einen Interrupt.
Nö.
Nur die Einschalttaste hängt mit am Interrupt, alle anderen nicht.
Gäbe auch keinen Sinn, solange Du nichts drückst, hat er doch nichts zu
tun.
> Klar - polling geht immer.
Bei Matrixanordnung geht sogar nur Polling, anders ließen sich
Tastenkombinationen (Ctrl+Alt+Del) nicht erkennen.
Peter
Power wrote:
> Selbstverständlich sind INTs zum erkennen von Tastendrücken (?) da! Die> Entwickler haben sich dabei schon was gedacht, nämlich dass beliebig> viele Tasten (Kontakte) den INT auslösen können, wie oben schon gesagt:> Diodenentkoppelt.
Komisch, ich habe zwar schon oft Tasten an MCs gesehen, aber noch nie
mit Dioden.
Bei Fernbedienungen nimmt man den Pin-Change-Interrupt nur zum Aufwecken
und danach pollt man die Matrix.
Peter
Hi,
also ich mache das auch immmer mit Dioden. Ich frage z.B. ein kompletten
Port mit einem einzigen Interrupt ab. 8 Schalter an ein Port und jeden
einzelen Port dann noch mal über eine Diode auf EINEN Interrupt. In der
Inerruptroutine frage ich dann erst ab welcher Pin sich geändert hat.
Für Zeitunktische Anwendungen geht das ohne Probleme!!
Grüße,
Marcel
Wenn Du alle 8 Taster mit einem Pin an den Interruptpin hängst, diesen
mit einem Pullup auf Vcc ziehst und alle anderen Tasterpins an einen
Port hängst, dann brauchst Du keine Dioden. Die einzelnen Portpins
werden nacheinander auf Low-Level geschaltet. Die sieben anderen sind
dabei hochohmig (Eingang ohne PullUp). Der Interrupt kommt, wenn ein
Taster den Low-Level an den Interrupt-Pin weiterleitet. Da der
Controller weiß, welcher Portpin gerade Low-Level hat, weiß er auch in
der ISR auch gleich, welche Taste gedrückt war. Wenn man den Interrupt
nur zum Wechen braucht, schaltet man vor dem "sleep" alle
Tasten-Portpins auf Low. Dann können alle Tasten den "Weck-Interrupt"
auslösen. Anschließend schaltet man auf Timergestütztes Polling um,
wobei das Entprellen auch gleich miterledigt wird. Außer den Tastern
braucht man keine externen Bauelemente.
Es gibt mit ein paar Tricks auch mehr als zwei externe interupts am
Mega8
Nur können diese den AVR nicht aus jedem Schlafzustand herrausholen.
Ich nehme zum Beispiel gerne den Analog Comparator Interrupt gerne als
dritten Interrupt beim Mega8. Der Eingangspin hierfür wäre dann
AIN1(PD7)
Für die Referenzspannung kann man die Bandgap Reference nehmen.
Wenn das noch nicht reichen sollte, dann kan man auch den Input Capture
Pin (PB0) als vierten externen Interrupt nehmen.
Ist zwar alles nicht so wie sich die Chip designer sich das vorgestellt
haben, aber was solls.
Aus meiner Erfahrung kann ich sagen, daß es funktioniert.
cu
Hauke
>Bei Fernbedienungen nimmt man den Pin-Change-Interrupt nur zum Aufwecken>und danach pollt man die Matrix.
Polling ist zyklischen Abfragen der Taster im Hauptprogramm ohne
Interrupt.
Bei der Fernbedienung wird nach dem Interrupt jede Taste einmal
abgecheckt, das ist nicht polling.
>Die TasterAnInterrupt-Fraktion stirbt einfach nicht aus...
Schreib mal ein Programm, welches mehrere Taster pollt, und noch eine
Delayschleife benutzt. Dann vielleicht noch beim ADC und UART
vorbeigucken, und dann soll das Timing noch präzise sein?
Die GOTO-Fraktion ist auch schon tot.
> und noch eine Delayschleife benutzt.
Delay-Schleifen benutzt man ja auch nicht! Du gehörst anscheinend zur
"AllesMitDelaySchleifenMachenWollen"-Fraktion...
> Die GOTO-Fraktion ist auch schon tot.
Leider nein. Siehe Beitrag "Hilfe beim Sleep-Mode"
Tom wrote:
> Polling ist zyklischen Abfragen der Taster im Hauptprogramm ohne> Interrupt.
Wer hat denn festgelegt, daß Polling nur im Main erlaubt ist ?
Ich polle meistens im Timerinterrupt.
Das ist sogar richtiges "zyklisches Abfragen" und nicht rein zufällig
von der Main-Durchlaufzeit abhängig.
Peter
>Polling ist zyklischen Abfragen der Taster im Hauptprogramm ohne>Interrupt.
Son Quatsch.
Natürlich darf man in einer Timer-ISR den Zustand der Eingänge abfragen.
Damit benutzt man einen Interrupt und Polling...
>Bei der Fernbedienung wird nach dem Interrupt jede Taste einmal>abgecheckt, das ist nicht polling.
Ist es wohl. Ob man es "abchecken" oder "abfragen" nennt ist dabei egal.
Polling bedeutet, dass der Zustand vom Programm (also der Software)
abgefragt wird. Bei einem Interrupt liefert die Hardware eine Adresse zu
der das Programm verzweigt wird (sofern der Interrupt zugelassen wird).
>Schreib mal ein Programm, welches mehrere Taster pollt, und noch eine>Delayschleife benutzt. Dann vielleicht noch beim ADC und UART>vorbeigucken, und dann soll das Timing noch präzise sein?
Wer eine Delayschleife zur Entprellung benutzt, benutzt vermutlich auch
GOTO...
Guck dir die Tastenentprellung von Peter Dannegger in der Codesammlung
an. Da wirst du sehen, dass man weder ein externen Interrupt, noch eine
Delayschleife braucht.
@Hannes: ... Windmühlen...
>> Bei der Fernbedienung wird nach dem Interrupt jede Taste einmal>> abgecheckt, das ist nicht polling.> Ist es wohl. Ob man es "abchecken" oder "abfragen" nennt ist dabei egal.> Polling bedeutet, dass der Zustand vom Programm (also der Software)> abgefragt wird.
Kann ich nur zustimmen. Polling bedeutet einfach nur eine softwaremäßige
Abfrage, sonst nix. Polling muss nicht zyklisch sein. Es bedeutet
lediglich (im Unterschied zur Interrupt-gesteuerten Verarbeitung), dass
das Programm selber nachsehen muss, was da abgeht und nicht von der
Hardware darauf aufmerksam gemacht wird.
> Guck dir die Tastenentprellung von Peter Dannegger in der Codesammlung> an. Da wirst du sehen, dass man weder ein externen Interrupt, noch eine> Delayschleife braucht.
Das ist ja das Problem. Peters Code (nicht nur der, auch die anderen)
ist meist so hochkomplex, dass man als Anfänger kaum eine Chance hat,
ihn zu verstehen. Und es soll Leute geben, die alles, was sie nicht
verstehen, als Quatsch abtun.
Ehe wieder Kontra kommt: Ich meide in meinen Programmen auch Code, den
ich (noch) nicht verstehe, mache ihn aber nicht öffentlich nieder.
...
Wer keine Lust auf Timerinterrupts mit dortiger Abfrage(Polling?) der
Tasten und auch keine alternativen Dioden mag, der moege seinen Mega8
einfach wegschmeissen und sich einen Mega48/88/168 zulegen. Bei dem ist
auf so ziemlich jedem Pin ein Pin-Change Interrupt moeglich.
cu Tarzanwiejane
Zitat "Dussel":
"Das müssen Interrupts sein, über eine Abfrage in einer Schleife geht
das nicht."
Ohne genaue Vorlage des Projekts ist natürlich davon auszugehen das es
sich um Tastenentprellung handelt.
Nur gibt's da auch andere Dinge, wie z.B. extern getriggerte Counter
o.ä.
Allerdings wenn eine solche Anwendung z.B. nur einige kHz Abtastfrequenz
benötigt reicht Timer-Overflow polling mehr als aus.
Und wie schon erwähnt reicht ein IRQ aus um mehrere Ereignisse
abzufragen, es muß halt nur in der ISR geguckt werden welcher Wert sich
geändert hat.
So lassen sich sogar acht Werte "gleichzeitig" erfassen ;-)
Man lese auch die zweite Zeile des Eröffnungsbeitrags. Da ist eindeutig
von Tastern die Rede. Somit sind Deine (ansonsten berechtigte)
Bedenken bezüglich schnellerer Signale (mehrere kHz) gegenstandslos. ;-)
...
> Kann ich nur zustimmen. Polling bedeutet einfach nur eine softwaremäßige> Abfrage, sonst nix. Polling muss nicht zyklisch sein.
Hier scheint ein bisschen Unklarheit zu herrschen, was Polling ist:
Polling bezeichnet in der Informatik die Methode, den Status von
bestimmter Hard- oder Software mittels zyklischem Abfragen zu ermitteln.
aus: http://de.wikipedia.org/wiki/Polling_%28Informatik%29
Man beachte das Wort "zyklisch".
Hmm.. mir scheint, die 'Taster-MUSS-man-per-Pollig-Abfragen' - Lobby hat
sich hier wieder formiert!
Leute, akzeptiert es doch endlich dass es auch anders geht! Ist doch
jedem selber überlassen wie er da realisieren will, oder?
Ich mache das mittlerweile mal so und mal so, manchmal auch kombiniert.
Einige hier haben eine andere Bedeutung von 'Polling' im Kopf, nämlich
das zyklische Abfragen in der 'main'. Das war auch mal DAFÜR die
Bezeichnung. Das 'Abscannen' einer Matrix in einem INT würde ich nicht
als Polling bezeichnen, da es kein endloses Abfragen ist, was mit Pollig
eigentlich mal gemeint war.
Power wrote:
> Das 'Abscannen' einer Matrix in einem INT würde ich nicht> als Polling bezeichnen, da es kein endloses Abfragen ist, was mit Pollig> eigentlich mal gemeint war.
Deshalb vermeide ich auch den Begriff Polling und rede von zyklischem
Abfragen. Ob dies im Timer-Interrupt passiert oder in einem Job der
Mainloop, der vom Timer (oder einem anderen taktgebenden, also zyklisch
auftretenden Ereignis wie dem Servoimpuls einer RC-Fernsteuerung alle 20
ms) synchronisiert wird, steht dabei auf einem anderen Blatt.
Zumindest frage ich einen Taster nicht in einer Warteschleife ab, die
nur den Eingang prüft und erst verlassen wird, wenn der Taster betätigt
wird. Das würde ich nämlich auch unter Polling verstehen (so wie Polling
eines Busy-Flags). Die Abfrage erfolgt immer so, dass sie "nebenbei"
erfolgt, der Controller dabei niemals warten muss.
Das Erkennen von Tastendrücken mittels Pin-Interrupt (egal ob intX oder
pcintX) erfordert zur Störunterdrückung eine Entprellung. Dazu wird gern
eine "Warteschleife" eingefügt (in die ISR natürlich). Diese Art
Programme mögen ja halbwegs funktionieren, sind aber nicht mein Stil.
Ganz Schlaue starten dann vielleicht einen Timer (für diesen einen
Entprellvorgang), da wird meist die Soße teurer als der Braten.
Dagegen bringt die Abfrage der Taster (meist sind es ja mehrere) im
(sowiso vorhandenen) Timer-Interrupt nur Vorteile. Die eigentliche
Routine braucht nur wenige Takte, als Ergebnis stehen für jeden Taster
mehrere Bits zur Verfügung, die das Hauptprogramm in aller Ruhe (bei
Gelegenheit) auswerten kann:
- Key_state zeigt den entprellten Zustand des Tasters an
- Key_press zeigt an, dass der Taster neu gedrückt wurde
- Key_lost (falls implementiert) zeigt an, dass der Taster losgelassen
wurde
- mit Key_repeat_count und drei Konstanten (Maske auf Repeat-Tasten,
Zeitdauer bis zur ersten Wiederholung, Wiederholtempo) lässt sich der
Dauerdruck ausgewählter Taster erkennen und darauf reagieren. Soll der
Dauerdruck dieselbe Aktion auslösen wie der Einzeldruck (nur immer
wieder hintereinander), dann setzt man damit Key_press erneut. Soll
der
Dauerdruck andere Aktionen auslösen, setzt man damit eben Bits in
einem
anderen Register, z.B. Key_repeat.
Die Routine braucht je nach Ausstattung 11 bis um die 20 Takte alle 4
bis 20 Millisekunden und liefert auch mit labrigen Tastern präzise
Ergebnisse. Dabei wird ein Tastendruck (eigentlich eine
Tastenveränderung, denn das Loslassen wird ja auch entprellt), also der
Pegel am Eingangspin, nur übernommen, wenn er bei vier aufeinander
folgenden "Abfragerunden" unverändert angelegen hat. Diese Sicherheit
bieten die Interrupt-Entprellungen nunmal nicht.
Ein Low-Level-Interrupt (oder PCI) kann sehr nützlich sein, um den
Controller aus dem stromsparenden Tiefschlaf zu wecken, aber das
eigentliche Entprellen der Taster würde ich damit nicht machen wollen,
das ist mit zyklischer Abfrage bedeutend billiger und komfortabler zu
haben.
Soviel zur 'Taster-MUSS-man-per-Pollig-Abfragen' - Lobby
...
>Trotzdem mache ich das auch per INT wenn es günstiger ist. Das muss von>Fall zu Fall abgewägt werden.
Mach wie du willst. Einfacher finde ich es, die Tasterentprellroutine
aus meiner Sammlung zu benutzen.
Da man zum Entprellen immer eine "Wartezeit" braucht, ist die
Timervariante für mich die einfachste...
>Da man zum Entprellen immer eine "Wartezeit" braucht, ist die Timervariante für
mich die einfachste...
Genau da kommt die Kombination zum Tragen.
Da der µC bei Tastendruck 'aufgeweckt' wird, wird die (hier schon so oft
gepriesene) Zeitbasis, z.B. ms-Timer-INT gestartet, bzw. benutzt, und
diese zum Entprellen verwendet.
Für Stromsparlösungen ist diese Methode auf jeden Fall vorzuziehen, als
ständig die Zeitbasis laufen zu lassen. Kostet zwar u.U. einen Timer,
der Zweck der Schaltung ist dafür erfüllt.
Mal nachgefragt: für was ist deiner Meinung nach der INT0 und INT1
vorgesehen? Scheinbar ist der nach euren Aussagen zu nichts zu
gebrauchen?! ;-)
Power wrote:
> Mal nachgefragt: für was ist deiner Meinung nach der INT0 und INT1> vorgesehen? Scheinbar ist der nach euren Aussagen zu nichts zu> gebrauchen?! ;-)
Nö, die sind sehr gut geeignet, um externe Peripherie-Chips
anzuschließen, z.B.:
SJA1000, LAN91C96, MCP2515, ENC28J60, PCF8574.
Gerade bei Peripherie mit I2C- oder SPI-Anbindung spart ein Interruptpin
Zeit.
Und z.B. CAN mit 1MBit ist gegenüber dem schneckenlahmen Menschen
Warp-schnell, da bringt ein Interrupt auch wirklich Punkte.
Peter
Eigentlich wollte ich mich nicht mehr dazu äußern, aber ich lasse mir
nicht gern das Wort im Munde herumdrehen. ;-)
Power wrote:
>>Da man zum Entprellen immer eine "Wartezeit" braucht, ist die Timervariante für
mich die einfachste...
>> Genau da kommt die Kombination zum Tragen.> Da der µC bei Tastendruck 'aufgeweckt' wird, wird die (hier schon so oft> gepriesene) Zeitbasis, z.B. ms-Timer-INT gestartet, bzw. benutzt, und> diese zum Entprellen verwendet.
Ja richtig, was Anderes habe ich ja nicht behauptet, zumindest nicht für
den Fall, dass der AVR aus dem (stromsparenden) "Tiefschlaf" geweckt
werden soll. Der Interrupt weckt auf, der Timer bekommt Takt und fängt
an zu klappern, die Timer-ISR entprellt die Taster und filtert damit
Störungen, die zum Aufwecken geführt haben könnten, aus.
> Für Stromsparlösungen ist diese Methode auf jeden Fall vorzuziehen, als> ständig die Zeitbasis laufen zu lassen.
Das habe ich nie bestritten! Aber nach dem Aufwecken ist die zyklische
Abfrage im Timer-Int immernoch die bessere Methode. Während des
"Tiefschlafs" klappert natürlich kein Timer, das wäre
Stromverschwendung.
> Kostet zwar u.U. einen Timer,
Aber keinen zusätzlichen. Der wird meist für viele andere Dinge als
Zeitbasis gebraucht, die Entprellung macht er ganz nebenbei.
> der Zweck der Schaltung ist dafür erfüllt.
Der Zweck ist das Aufwecken.
>> Mal nachgefragt: für was ist deiner Meinung nach der INT0 und INT1> vorgesehen?
Da gibt es viele Verwendungsmöglichkeiten, es sollten aber prellfreie
Signale sein. Z.B. elektronisch erzeugte Impulse. Mechanische
(prellende) Schaltelemente gehören aber nur im Notfall dazu, z.B. zu,
Aufwecken.
> Scheinbar ist der nach euren Aussagen zu nichts zu> gebrauchen?! ;-)
Doch, nur nicht zum Entprellen von Tastern und Schaltern, das geht
anders besser, komfortabler und billiger.
...
Wenn man mehr externe Interupt fähige Eingänge benötigt als der µC
hergibt, dann sollte man mal drüber nachdenken, ob man den richtigen µC
ausgewählt hat.
Man kann natürlich mit vielen Tricks das ganze irgendwie zum laufen
bringen, aber ist das der richtige Weg ?
Für die Bastler mag das der richtige Weg sein, "auf eigene Schulter
klopfen und wie gut ich doch wieder bin"
Nur Zielführend ist es nicht.
Der Weg muss sein :
1. Was will ich machen
2. Was muss ich haben, machen damit ich das Ziel von 1. erreichen kann
3. Welche Komponenten erfüllen meine Anforderungen aus 2.
4. und jetzt kann man mit der Implementierung anfangen.
Wer mit Punkt 4 anfängt macht viele Umwege.
Das gleiche ist es auch mit der Auswahl der Programmiersprache.
Da wo es notwendig ist, passt Assembler sehr gut.
( zb Spezeille Registerzugriffe bei einzelnene µC)
Für alle anderen Fälle steht der Aufwand der Assemblerprogrammierung in
keinem vernünftigen Verhältnis zum Ergebnis.
Ich will jetzt keinem der in Assembler programmiert sagen das er was
falschen macht. Ich hab hochachtung vor jemandem der ein komplexes
Programm in Assembler erstellen kann.
Aber wenn er dann mal einen anderen µC benutzen muss, kann er den Code
wegwerfen und von vorne beginnen.
Ist das ganze in C programmiert, nimmt man den passenden Compiler, muss
nur die Defines für Register, Ports,... ändern und der Code läuft.
Die Zeitersparnis ist gewaltig.
Von der Nachvollziehbarkeit nach einigen Monaten will ich da gar nicht
erst reden.
Zusammengefasst:
Erst das ganze Projekt durchdenken und dann die passende Hardware
aussuchen.
Power: Du solltest lieber ein wenig die Füße still halten. Es gibt
Leute, die immmer und ständig anderen Leuten Vorschriften machen müssen,
nur damit sie etwas vorzuweisen haben, womit sie andere beeindrucken
können. Hannes gehört nicht dazu - ich kenne ihn als sehr konstruktiven
und hilfsbereiten Mitstreiter hier im Forum. Wenn Du Dir die Mühe
machst, seine Projekte anzuschauen, dann merkst Du auch, daß er was vom
Programmieren versteht. Du mußt seine Vorschlage nicht annehmen und
kannst machen, was Du willst, aber mach ihn hier nicht ´runter!
@Hannes: Laß´ Dich nicht ärgern! Meine Zustimmung zu Deiner Variante
hast Du - ich weiß aus Erfahrung, daß es anders zwar auch geht, aber
viel anfälliger ist. Interrupt zum Wecken muß sein, zum Tastenabfragen
ist er jedoch viel zu sensibel und bringt das Programm durcheinander -
alles natürlich eine Sache des direkten Anwendugszwecks. In
zuverlässigen und komplexeren Anwendungen hat eine Taste, die direkt
einen Programmsprung verursacht, meiner Meinung nach, nur Nachteile.
Grüße nach MD!
@ Travel rec:
>Du mußt seine Vorschlage nicht annehmen und kannst machen, was Du willst, aber
mach ihn hier nicht ´runter!
Mache ich nicht. Ich appeliere lediglich an seine Toleranz, auch andere
Lösungswege zu akzeptieren.
Sein Fachwissen und seine Programmierfähigkeiten stelle ich keineswegs
in Frage, das hat er schon oft genug bewiesen.
Und um konstruktive Kritk auszuschalten solltest du anderen nicht
empfehlen die Füße still zu halten, das werde ich ganz sicher nicht tun!
Auch nicht dir gegenüber.
Naja - ich finde nur, daß Du ziemlich große Töne spuckst und trotzdem
auf "Lösungen" beharrst, die sich als unpraktikabel erwiesen haben. Wenn
jetzt Leute, die noch nicht so viel Erfahrung haben, auf die
Interrupt-Variante setzen und sich dann immer wundern, warum ihr
Programm ein Eigenleben entwickelt, ist doch auch keinem geholfen.
Interrupts sind - meines Erachtens - wirklich nur dazu gedacht, den
eigentlichen Programmablauf kurzzeitig unbedingt zu unterbrechen, um
zeitkritische Signale zu erfassen und abzulegen, damit eine spätere
Abarbeitung im Hauptprogramm die notwendigen Änderungen ausführen kann.
Ich möchte nicht, daß mein Programm unvermittelt 5-20 mal von einem
einzigen Tastendruck unterbochen und in seiner Arbeit behindert wird,
obgleich selbige Funktionalität nebenbei erledigt werden könnte und
keinerlei merkliche Timingvariationen entstehen würden, egal ob nun
(wild) an den Tasten gespielt wird, oder nicht. In Systemen, die den
Controller anderweitig beschäftigen, hat er für so popelige
Tastenabfragen, die ihn von der Arbeit abhalten, auch gar keine Zeit.
>Ich appeliere lediglich an seine Toleranz, auch andere>Lösungswege zu akzeptieren.
Warum sollte er den Lösungsweg nicht akzeptieren, wenn es auf das
Gleiche hinausläuft:
Einen Taster (oder anderen mechanischen Schaltkontakt) hägnt man an
einen Interrupt-Pin, wenn man den Controller aus dem Tiefschalf wecken
will.
Wenn man den Controller gar nicht schlafen schickt, braucht man auch
keinen Interrupt-Pin, um ihn zu wecken. Einen Timer zum Entprellen aber
schon...(sogar deine Aussage).
PeDa hat ja schon sinnvolle Anwendungen für externe Ints aufgezeigt:
Elektronische Periferie!
Nunja, der INT sollte nach erkanntem Tastendruck ja auch gesperrt
werden, dann kommt die Entprellung (per Timer-INT) oder der Matrix-Scan.
Erst wenn wieder auf Tastendruck reagiert werden soll wird der INT
wieder freigegeben. Kommt natürlich immer auf die Schaltung und das
Programm an, ob das praktikabel ist oder nicht. Ich habe das in vielen
Schaltungen schon so realisiert und es läuft problemlos.
Wie gesagt: es führt nicht immer nur ein Weg ans Ziel, es sollte eben
der günstigste gewählt werden.
> Nunja, der INT sollte nach erkanntem Tastendruck ja auch gesperrt> werden, dann kommt die Entprellung (per Timer-INT) oder der Matrix-Scan.
Achnee, jetzt also doch?
Das ist ja genau das, wes ich die ganze Zeit empfehle.
> Erst wenn wieder auf Tastendruck reagiert werden soll wird der INT> wieder freigegeben.
Diese Kleinigkeit mach' ich etwas anders:
Erst wenn der Controller nix mehr zu tun hat, alle seine Arbeiten also
erledigt sind, der Benutzer also vorerst das "Gerät" nicht mehr braucht,
dann wird vom Sleep-Mode Idle auf den Sleep-Mode Power-Down umgeschaltet
und der Tasten-Int aktiviert, damit der Benutzer das Ding wieder
einschalten bzw. aufwecken kann.
Für das Erkennen weiterer Tastendrücke bei "laufendem Gerät" schalte ich
den externen Int für Taste nicht ein, der stört nur unnötig den
Programmablauf.
Und wenn das Gerät nicht batteriebetrieben ist, hat das Ganze überhaupt
keinen Sinn, es ist lediglich eine Stromsparmaßnahme.
> Wie gesagt: es führt nicht immer nur ein Weg ans Ziel, es sollte eben> der günstigste gewählt werden.
Eben, nur deshalb habe ich meine Meinung geäußert.
Übrigens: Die Art der Tastenabfrage, die ich nutze (und empfehle), ist
nicht "meine Erfindung", sondern beruht auf PeDas
Bulletproof-Entprellung (siehe Codesammlung). Und ich habe kein Problem
damit, in meinen Quelltexten auf den Urheber zu verweisen.
...
Boah, was habe ich hier für eine Diskussion losgetreten...
Habe nochmal nachgedacht und bin zu dem Schluss gekommen, dass ich es so
hinbiegen kann, dass ich einen Taster in einer Schleife abfrage und den
anderen durch ein Pedal ersetze. So dürfte es dannn keine Probleme mehr
geben, hoffe ich.
>es ist lediglich eine Stromsparmaßnahme
Nicht nur! Wenn ich per Tastendruck einen laufenden Prozess unterbrechen
will der viele Interrups bekommt kann es sein, dass noch einige INTs
unberechtigt abgearbeitet werden, da der Timer-INT eine niedrigere
Prioritaet hat. Bei STOP-Tasten kann das notwendig sein.
>ist nicht "meine Erfindung"
Schon klar, man wird hier nur sehr schnell gemassregelt und in die Ecke
gestellt wenn man mal einen Anderen Weg Zeigt und eine andere Meinung
hat!
(wieso habe ich auf einmal den Ami-Tastaturtreiber drin, liegt das an
der Seite?)
@Power
Sorry wenn ich dich korrigiere.
Aber der AVR besitzt keine Interrupt Prioritäten.
Es gilt einfach wer zuerst kommt malt zuerst.
Nur wenn Interrupts zum exakt gleichen Taktzyklus auftreten dann werden
diese nach der Reihenfolge der Interruptvektoren abgearbeitet.
Dies kann passieren, wenn während das I-Flag nicht gesetzt ist (cli oder
bei der Ausführung einer ISR) zwei neue Interruptereignisse (mit
unterschiedlichen Vektoren) eintreten. Nach dem Setzen des I-Flag (sei
oder reti) werden die ausstehenden Interrupts dann nach o.g. Reihenfolge
abgearbeitet.
cu
Hauke
Power wrote:
>>es ist lediglich eine Stromsparmaßnahme> Nicht nur! Wenn ich per Tastendruck einen laufenden Prozess unterbrechen> will der viele Interrups bekommt kann es sein, dass noch einige INTs> unberechtigt abgearbeitet werden,
Wenn das Szenario zutreffen sollte, dann hat man bei der Programmierung
verdammt viel falsch gemacht!
> da der Timer-INT eine niedrigere> Prioritaet hat. Bei STOP-Tasten kann das notwendig sein.
Siehe Hauke...
>>>ist nicht "meine Erfindung"> Schon klar, man wird hier nur sehr schnell gemassregelt und in die Ecke> gestellt wenn man mal einen Anderen Weg Zeigt und eine andere Meinung> hat!
Es ist nicht Deine andere Meinung, sondern Deine Intoleranz Anderen
gegenüber, die man mit etwas Bosheit als Selbstüberschätzung auslegen
könnte (was ich aber nicht tu'). Ich weiß weißgott auch nicht alles, bin
aber bereit, dazuzulernen.
>> (wieso habe ich auf einmal den Ami-Tastaturtreiber drin, liegt das an> der Seite?)
Ich war's!!! - Und jetzt ist Frieden...
;-)
...
@ Hauke:
>Es gilt einfach wer zuerst kommt malt zuerst.>Nur wenn Interrupts zum exakt gleichen Taktzyklus auftreten dann werden>diese nach der Reihenfolge der Interruptvektoren abgearbeitet.
Nein.
Wenn währen der Abarbeitung des INT0 (erster Vektor in der
INT-Vektorenliste) das INT0-Flag erneut gesetzt wird, wird diese Liste
erneut von oben abgearbeitet. Dadurch wird der zweite Vektor nicht
erreicht, erst wenn das INT0-Flag nicht mehr gesetzt ist wird der
nächste INT abgearbeitet.
klar ist das keine Priorität im althergebrachten Sinn, wirkt sich aber
ähnlich aus.
>bin aber bereit, dazuzulernen.
Ich auch. Habe auch schon von dir dazugelernt, so intolerant bin ich nu
auch wieder nicht. ;)
>Ich war's!!! - Und jetzt ist Frieden...
Wusst' ich's doch! ;-)
Du sagst es.
Es ist eine keine PRIORITÄT!!!
Es ist schlichtweg eine Reihenfolge der Abarbeitung.
Der AVR kennt was Interrupts angeht nur zwei Zustände. Entweder
Interrupts sind erlaubt (I-Flag gesetzt). Oder Interrupts sind NICHT
erlaubt (I-Flag gelöscht).
Interrupt-Prioretisierung (wird das wirklich so geschrieben???) meint,
daß ein Interrupt einer hohen Priorität die ISR eines Interrupts mit
niedrieger Priorität unterbrechen kann. (aber nicht umgekehrt)
Also:
Main wird von ISR(lp) unterbrochen.
ISR(lp) wird danach von ISR(HP) unterbrochen.
ISR(HP) wird abgearbeitet.
ISR(lp) wird ab der Stelle der Unterbrechung durch ISR(HP)
weitergeführt.
Main wird ab der Stelle der Unterbrechung ISR(lp) weitergeführt.
Um eine ISR im AVR unterbrechen zu lassen, müßte man das I-Flag wieder
setzen.
Jedoch finde ich, daß SEI in einer ISR nichts zu suchen hat.
Sowas führt schnell zu einem Stacküberlauf.
Eine andere Sache ist natürlich wenn deine ISR den Grund des Interrupts
nicht behebt. Dann ist üblicherweise etwas im Programmdesign
grundsätzlich falsch. (Dein AVR wird die ISR nicht wieder verlassen
können)
Es ist auch dann etwas faul, wenn der Interrupt schneller und öfter
kommt als deine ISR ihn abarbeiten kann.
Dein AVR bleibt in der ISR und kann sein eigendliches Hauptprogramm und
andere Interrupts nicht mehr abarbeiten.
Besser ist es wenn man nach einem Interrupt "Taste wurde gedrückt" ein
Flag in einem Register setzt und den Interrupt-Trigger danach auf "Taste
wurde losgelassen" stellt.
cu
Hauke
Ja,
mit deiner 'Interrupt-Prioretisierung' hast du natürlich Recht.
Wenn das 'I'-Flag in der ISR wieder gesetzt wird sollte man genau wissen
was man macht, ist aber wirklich nicht zu empfehlen sowas zu machen.
Ich hatte das Problem des Prellens mal mit einem Thermostatprüfgerät
(Visualisierung, einfacher wechsler). Der Thermostat hat so besch..
Kontakte gehabt und hat so langsam geschaltet dass er sekundenlang
geprellt hat. In dem Fall kamen die Impulse im µs-Bereich, da hätte es
definitiv Probleme gegeben.
Darum lösche ich das entsprechende INT-Flag bevor ich ihn wieder
'scharf' schalte.