Hallo, ähnlich wie hier: Beitrag "mega32 interrupt zählt doppelt" habe ich das Problem, dass ein prellender Taster unter bascom eine doppelte Ausführung meiner ISR verursacht. Wie kann ich in Bascom am Ende der ISR es so einstellen, dass alle noch wartenden Interrupts gelöscht werden? Hier mal mein quick&dirty sourcecode: $regfile = "m48def.dat" 'compile for mega48 $crystal = 10000000 'make sure it uses the external 10 MHz crystal oscillator 'dont forget to set fusebits Config Portc = Output Config Portd = Input Config Portb = Input Portc = 0 'no signal at output Portb = 255 Portd = 255 'Pullups Declare Sub Inter On Int0 Inter On Int1 Inter Enable Int0 'enables the TIMER1 interrupt Enable Int1 Config Int0 = Falling 'trigger on falling edge Config Int1 = Falling Enable Interrupts 'allow interrupts to be set Dim C As Byte 'set counter variable Do 'main loop is empty Loop End Inter: 'interrupt routine Disable Int0 'prevent double triggering For C = 1 To 10 '100 images Portc.0 = 1 'set camera pin high Waitms 49 'wait a moment Portc.0 = 0 'set low Waitus 1000 'allow readout Next C Enable Int0 're-enable trigger Return
$regfile = "m48def.dat" 'compile for mega48 $crystal = 10000000 Config Portc = Output Config Portd = Input Config Portb = Input Portc = 0 Portb = 255 Portd = 255 'Pullups Declare Sub Inter On Int0 Inter On Int1 Inter Enable Int0 'enables the TIMER1 interrupt Enable Int1 Config Int0 = Falling 'trigger on falling edge Config Int1 = Falling Enable Interrupts 'allow interrupts to be set Dim C As Byte 'set counter variable Do 'main loop is empty Loop End Inter: 'interrupt routine Disable Int0 'prevent double triggering For C = 1 To 10 '100 images Portc.0 = 1 'set camera pin high Waitms 49 'wait a moment Portc.0 = 0 'set low Waitus 1000 'allow readout Next C
Bark schrieb: > habe ich das Problem, dass ein prellender Taster unter bascom eine > doppelte Ausführung meiner ISR verursacht. Das ist völlig normal, wenn man nen externen Interrupt nimmt, d.h. Bascom ist daran unschuldig. Die beste Methode ist, keinen externen Interrupt zu nehmen. Die quick& wirklich sehr sehr dirty Methode ist, im Interrupt erstmal elendig lange kostbare CPU-Zeit zu verwarten und am Ende das Interrupt-Pending-Flag zu löschen, indem man es setzt. Peter
Danke für die Antwort, aber ich brauche unbedingt einen externen Interrupt, und der darf auf keinen Fall doppelt getriggert werden. Zeit verwarten ist gar kein Problem, solange das reproduzierbar ist, ist es egal. Kannst Du mir sagen, wie ich das Interrupt Pending Flag setzen kann?
hallo bark, ich habe das in bascom bisher so gelöst: int auf falling, interner pullup am int-eingang einschalten 100nF vom inteingang nach masse in der isr frage ich dann nochmal den portpin direkt ab, ob er auf null liegt. wenn das so ist, setze ich das flag "taste gedrückt", welches dann in der hauptschleife verarbeitet wird. hat bisher ganz gut geklappt. natürlich gibt es auch die verschiedenen qualitäten von tastern zu bedenken. wenn das alles nicht hilft, müsstest du vielleicht zusätzliche hardware bemühen, um den taster zu entprellen. siehe z.b. http://www.labbookpages.co.uk/electronics/debounce.html gruss klaus
Hi nehm deine Routine aus dem Interrupt raus und mach es so wie Klaus schrieb. Also einfach in der Art: Interrupt auf Falling mit internem Pull-Up und Taster gegen Masse Do 'main loop is empty if Tasterflag=1 Then For C = 1 To 10 '100 images Portc.0 = 1 'set camera pin high Waitms 49 'wait a moment Portc.0 = 0 'set low Waitus 1000 'allow readout Next C Tasterflag=0 end if Loop End Inter: 'interrupt routine Tasterflag=1 Return Dann ist es egal wie oft dein Interrupt kommt. Solange das Tasterflag nicht zurückgesetzt wird, hat das keine Auswirkung auf den Ablauf des Programmes. Und wenn die Taster entprellen willst, dann einfach per Software und ohne INT0/1-Interrupt sondern mit Timerinterrupt. Aber dann hast du xx Millisekunden, bis du definiert sagen kannst ob der Taster wirklich gedrückt ist oder nur ein Störimpuls die Eingabe triggert.
Hmm, das wäre eine Möglichkeit, ich habe auch das hier probiert: GIFR.INTF0 = 1 Nur dann meckert Bacom "falscher Datentyp".Wieso? Kann ich das GIFR Register nicht beschreiben oder was? Set Intf0 Hingegen geht, scheint aber keinerlei Auswirkungen auf den versehentlichen doppelten Interrupt zu haben.
Du kannst auch am den anfang der ISR das Prellen abwarten: Inter: waitms 20 if int0=1 then reti 'weg hier falls es nur eine Nadel war ... return
Ich mach die Tasten mit einem timer. In einem vom timertick ausgeloesten Prozess schau ich ob eine Taste gedrueckt wurde. Eine Taste wir erst als gedrueckt/losgelassen akzeptiert wenn der Zustand zwei mal gleich ist.
Interruptroutinen die zuviel innerhalb der eigenen Routine machen, sollte man vermeiden, da sonst u.U. die Routine mehrfach aufgerufen werden kann was zu einem Stacküberlauf führen kann. Wenn z.B. in der Routine von "frag" während der Wartezeit von 20ms Interrupts kommen, wird die Routine mehrfach aufgerufen und Overflow ist da. Besser in den ISR-Routinen nur "Kleinkram" machen und die Zeitschleifen die du z.B. hast ins normale Hauptprogramm auslagern. Hier mal was zum Entprellen von bis zu acht Tastern an einem Port in BASCOM. Ist eine Portierung eines C-Quelltextes der hier im Forum gepostet wurde. Die Variable io_press zeigt bitweise dass ein Eingang ein Signal hat/hatte. Das liest man aus und löscht dann die Variable. Die Variable io_state gibt den aktuellen Zustand der Eingänge an. Die Variablen io_ct0 und io_ct1 bilden einen Zähler bis drei für jedes Bit des Eingangsport. Die Entprell-ISR-Routine ist wirklich tricky gemacht und funzt einwandfrei. Der Timerwert von hier 100 gibt an wie oft die Routine die Eingänge checkt.
1 | 'Variablen für die Entprell-Routine |
2 | Io_port Alias Porta |
3 | Io_pins Alias Pina |
4 | Config Io_port = Input |
5 | Io_port = 255 ' Pull-Ups setzen |
6 | Dim Iwr0 As Byte |
7 | Dim Io_ct0 As Byte |
8 | Dim Io_ct1 As Byte |
9 | Dim Io_state As Byte |
10 | Dim Io_press As Byte |
11 | |
12 | ' Init Eingänge |
13 | Io_ct0 = 0 |
14 | Io_ct1 = 0 |
15 | Decr Io_ct0 |
16 | Io_ct1 = Io_ct0 |
17 | Io_state = 0 |
18 | Io_press = 0 |
19 | |
20 | 'Timer2-Interrupt konfigurieren (Timer2 = 8bit) |
21 | Config Timer2 = Timer , Prescale = 1024 |
22 | On Timer2 Timer2_isr 'Interrupt Service Routine anspringen |
23 | Timer2 = 100 |
24 | Enable Timer2 |
25 | |
26 | ' Interrupts freigeben |
27 | Enable Interrupts |
28 | |
29 | '### MAINLOOP |
30 | Do |
31 | |
32 | ' Zum Keyboardcheck den Timer anhalten |
33 | Disable Timer2 |
34 | If io_press<>0 Then |
35 | if io_press.0=1 Then 'tu was |
36 | if io_press.1=1 Then 'tu was andres |
37 | io_press=0 |
38 | End If |
39 | Enable Timer2 ' und wieder starten |
40 | Loop |
41 | END |
42 | |
43 | '### Interrupt Routine für Timer2 (Eingänge pollen + entprellen) |
44 | Timer2_isr: |
45 | Timer2 = 100 |
46 | Iwr0 = Io_pins |
47 | Iwr0 = Not Iwr0 |
48 | Iwr0 = Iwr0 Xor Io_state |
49 | Io_ct0 = Io_ct0 And Iwr0 |
50 | Io_ct1 = Io_ct1 And Iwr0 |
51 | Io_ct0 = Not Io_ct0 |
52 | Io_ct1 = Io_ct1 Xor Io_ct0 |
53 | Iwr0 = Iwr0 And Io_ct0 |
54 | Iwr0 = Iwr0 And Io_ct1 |
55 | Io_state = Io_state Xor Iwr0 |
56 | Iwr0 = Iwr0 And Io_state |
57 | Io_press = Io_press Or Iwr0 |
58 | |
59 | Return |
Jepp, ok, jetzt läuft die Aufgabe in der Hauptroutine und es funktioniert super und ohne jedes Problem. Dankeschön!
Wäre es nicht auch möglich am Anfang der ISR die Interrupts komplett zu deaktivieren oder nur den einen Interrupt und dann am Ende wieder einzuschalten? Ich habe vor kurzem beim Kennenlernen der 8051er einen Counter mit dem Timer gebastelt, der das Ergebnis dann noch bearbeitet und auf 7 Segment Anzeigen ausgibt. Das ist relativ zeitaufwendig und es hat auch rumgesponnen wenn der Impuls zu oft kam. Ich habe dann einfach die Ints ausgemacht am Anfang der ISR und am Ende wieder an. So können zwar Ereignisse unterschlagen werden, aber wenn es darauf nicht ankommt, passt das auch.
krümeltee schrieb: > Wäre es nicht auch möglich am Anfang der ISR die Interrupts komplett zu > deaktivieren oder nur den einen Interrupt und dann am Ende wieder > einzuschalten? Du vertraust der Hardware wohl nicht? Da muß ich Dich enttäuschen, sie macht das automatisch, genau dem Datenblatt entsprechend. > Ich habe vor kurzem beim Kennenlernen der 8051er einen Counter mit dem > Timer gebastelt, der das Ergebnis dann noch bearbeitet und auf 7 Segment > Anzeigen ausgibt. Das ist relativ zeitaufwendig und es hat auch > rumgesponnen wenn der Impuls zu oft kam. Ich habe dann einfach die Ints > ausgemacht am Anfang der ISR und am Ende wieder an. Das ist Quatsch mit Soße. Die einzige Möglichkeit, daß beim 8051 ein Interrupt sich selber unterbricht, ist die, daß Du im Interrupthandler die eigene Priorität hochsetzt. Ansonsten kannst Du Dich auf den Kopf stellen, erst nach dem RETI kann der nächste Interrupt zuschlagen. Man sollte ruhig mal das Datenblatt lesen, bevor man völlig sinnlosen und wirkungslosen Code in den Interrupt packt. Wenn Du aber nem anderen Interrupt ne höhere Priorität zugewiesen hast und der stört, dann kann man die Interrupts global sperren. Dann fragt sich allerdings, warum man diesen überhaupt erst die höhere Priorität gegeben hat, um sie dann doch wieder auszuhebeln. Machs also lieber gleich richtig, d.h. nutze die Prioritäten erst dann, wenn Du Dir dabei auch was gedacht hast. Peter
Hallo, ja, der Beitrag ist schon sehr alt. Ich stand jetzt aber vor dem gleichem Problem einen weiteren Interrupt innerhalb der ISR zu sperren oder eine doppelte Auslösung zu verhindern. Vielleicht hilft es ja jemandem. User "Wah" hat eigentlich schon die richtige Lösung gepostet: "GIFR.INTF0 = 1" Keine Ahnung warum bei ihm eine Fehlermeldung kam... GIFR ist das "general interrupt flag register", sowas wie ein Zwischenspeicher der weitere Interrupts auch innerhalb der ISR speichert. Ist die ISR am Ende bei Return angekommen, wird zwar wieder in das Hauptprogramm gesprungen, aber der zwischengespeicherte Interrupt wieder sofort ausgelöst. Ein DISABLE der Interrupts innerhalb der ISR funktioniert leider nicht und scheint auch nicht nötig zu sein, da der AVR zwar weitere Interrupts sperrt, aber eben das FLAG für einen Interrupt im GIFR speichert. Ein weiteres Interrupt wird dann eben nur zeitversetzt ausgelöst, sobald man z.B. im Hauptprogramm wieder die Interrupts auf ENABLE setzt. Man muss also innerhalb der ISR den Interrupt Flag im GIFR Register löschen und zwar ganz am Ende vor Return. Das GIFR hat 8 Bits, relevant für INT0 & INT1 sind Bit6 und Bit7. Man setzt nun einfach das entsprechende Bit des Registers auf 1. Möchte man den Interrupt Flag für INT0 löschen: GIFR = 64 Möchte man den Interrupt Flag für INT1 löschen: GIFR = 128 Natürlich geht das auch mit binärer Schreibweise. Für INT0: GIFR = &b10000000 Für INT1: GIFR = &b01000000 So könnte das in Bascom aussehen: On_int: Portd = &B00000000 Sound Portd.7 , 200 , 1000 Wait 5 Gifr.int1 = 1 Return Alex
Hallo Alex, eine sehr, sehr hilfreiche Erklärung. Mit Interrupt’s hatte ich auch immer wieder Probleme. Seit dem ich am Anfang der Hauptschleife das GIFR- Register komplett lösche nicht mehr. War oft ein Problem für Stacküberlauf. Eins ist für mich noch unklar warum Interrupt in eine Art „Schieberegister“ sich die „Klicks" merken müssen. Ist es nicht so, INTx spring aus der Do in ISR. Nun eine Entscheidung treffen und wieder ab zu Do. Warum diesen „Klick“ merken und dummer Weise den letzten „Klick“ wieder an Anfang des Register stellen, wenn Überlauf? Mit freundlichen Grüßen
Fred R. schrieb: > Eins ist für mich noch unklar warum Interrupt in eine Art > „Schieberegister“ sich die „Klicks" merken müssen. Nicht nur das ist mir auch unklar. > Ist es nicht so, INTx spring aus der Do in ISR. Nun eine Entscheidung > treffen und wieder ab zu Do. > Warum diesen „Klick“ merken und dummer Weise den letzten „Klick“ wieder > an Anfang des Register stellen, wenn Überlauf? Jau. Entscheidung und ab ... Aber was sind die „Klicks" vom „Schieberegister“
Wenn ich Dich recht verstehe, dann fragst Du Dich warum der uC so funktioniert, daß ein Interrupt mehrfach ausgelöst werden kann; insbesondere warum er noch einmal ausgelöst werden kann, wenn der erste doch gerade behandelt wird bzw. eben behandelt wurde. Zu dem folgenden schaue Dir bitte mal parallel die Bilder und die Beschreibung im Datenblatt an: Das Verhalten ergibt sich zunächst einmal ganz natürlich, wenn man eine ganz einfache Schaltung dafür entwirft: Das externe Signal löst einen Interrupt dadurch aus, das ein Bit in einem Register gesetzt wird. Bei jedem Übergang von einem Befehl zum nächsten, beeinflusst diese Bit, wenn es gesetzt wurde, welcher Befehl als nächstes ausgeführt wird; effektiv in dem der Programmzähler auf einen, von dem Interrupt abhängigen Wert gesetzt wird. Das ist bei den AVRs eine Adresse in der Interrupt-Vektor-Tabelle. Gleichzeitig wird das oben erwähnte Bit, das anzeigt, dass ein Interrupt ausgelöst wurde, wieder zurückgesetzt. (Das könnte man auch zu einem anderen Zeitpunkt machen, aber das hängt von dem Hersteller ab, wie er sich da entscheidet). Tritt also das Ereignis, das diesen Interrupt auslöst, nach diesem Zeitpunkt noch einmal ein, so wird das Bit wieder gesetzt. Der Mechanismus, der nach jedem Befehl, das Interrupt-Bit berücksichtig, ist allerdings zu diesem Zeitpunkt ausser Kraft gesetzt, sonst würde eine gerade laufender ISR unterbrochen. (Bei manchen CPUs wird das auch nicht getan oder nur für den zuletzt ausgelösten Interrupt. Hängt wieder vom Hersteller ab und diese Varianten bieten auch gewisse Vorteile). Jedenfalls, da der Mechanismus ausser Kraft ist, wird die ISR nicht unterbrochen. Erst wenn man mit IRET die ISR verlässt, wird er wieder wirksam. Falls inzwischen wirklich der Interrupt erneut aufgetreten ist, so wird gleich wieder die entsprechende ISR ausgeführt. Wie gesagt, das Verhalten ergibt sich zwangsläufig aus einer ganz einfachen, man könnte sagen Straight-Forward oder As-Simple-As-Possible Implementierung dieses Ablaufs. Das ist insofern keine "Absicht". Diese, wie auch die anderen oben in Klammern erwähnten Varianten sind sinnvoll nutzbar. Man muss aber doch wissen, was bei einem gewissen Prozessor tatsächlich geschieht und das berücksichtigen. Bei Tastern nun, ist es so, dass die, wie Du schon weißt, prellen. Das aber bedeutet, dass ein Interrupt wahrscheinlich mehrfach ausgelöst wird. Es gibt nun zwei Auswege aus dieser Situation: A) Man betreibt prellende Taster gar nicht an einem Interrupt. Da spart man sich zusätzlichen Code um diesen Fall zu behandeln. B) Man fügt zusätzlichen Code hinzu, um den Fall zu behandeln - d.h. kurz hintereinander auftretende gleiche Interrupts als einen zu behandeln. Das führt aber das Problem ein, dass man ziemlich genau wissen muss, welche Interrupts durch die selbe Ursache (den einen und einzigen Tastendruck) ausgelöst wurden und welche nicht. Das ist nicht ganz einfach, denn die Taster verhalten sich verschieden, andererseits, kann ein Benutzer kaum in kürzeren Abständen, als etwa ein paar 100ms eine Taste drücken. Deswegen vermeidet man, und rät insbesondere Anfängern, Taster nicht mit Interrupts zu behandeln. Andererseits gibt es durchaus Interruptquellen, die so kurz hintereinander Interrupts auslösen, das die ISR noch nicht fertig werden konnte. Auch dafür gibt es einige Wege zu Behandlung, von denen eine ist, den oben beschriebenen Ablauf nicht als Problem, sondern als Lösung zu betrachten: Wenn nämlich ein weiterer Interrupt wiederum das Flag setzt, und man weiß, dass das so sein soll, dann kann man das nutzen. Da aber nur noch ein zusätzlicher Interrupt gespeichert werden kann, geht das nur mit Quellen, die während der Laufzeit der ISR höchstens einen weiteren Interrupt auslösen. Geht also auch nicht für alle Fälle. Da guckt man dann, danach die ISR zu verkürzen, damit man im Code auch alle Interrupts mitbekommt. Das ist ein komplexes Thema. Daher wird Anfängern zuerst dazu geraten: 1. ISR so kurz wie möglich zu halten. 2. Keine Quellen an Interrupts zu betreiben die unnötige weitere Interrupts auslösen - wie es eben bei Tastern der Fall ist. Ich hoffe das hilft Dir.
Staubfänger schrieb: > Wie gesagt, das Verhalten ergibt sich zwangsläufig aus einer ganz > einfachen, man könnte sagen Straight-Forward oder As-Simple-As-Possible > Implementierung dieses Ablaufs. Das ist insofern keine "Absicht". Das Verhalten ist sehr wohl volle Absicht! Jeder Interrupt ist zwangsläufig wichtig, sonst würde man ja keinen Interrupt verwenden. Oberste Prämisse ist daher, es darf kein Interrupt verloren gehen, auch wenn er gerade nicht behandelt werden kann. Z.B. ein Ethernet-Controller kann mehrere Interruptquellen haben und jede muß behandelt werden, sonst gehen Nachrichten verloren. Daß man Interrupts auch für schneckenlahme menschliche Eingaben mit prellenden Tastern verwendet, ist zwar prinzipiell erlaubt, aber nicht die Regel (sollte es nicht sein).
Peter D. schrieb: > Staubfänger schrieb: >> Wie gesagt, das Verhalten ergibt sich zwangsläufig aus einer ganz >> einfachen, man könnte sagen Straight-Forward oder As-Simple-As-Possible >> Implementierung dieses Ablaufs. Das ist insofern keine "Absicht". > > Das Verhalten ist sehr wohl volle Absicht! Da das von Dir, meinem Zitat folgende, beschriebene ohne Zweifel plausibel ist, hätte ich wohl besser gar keine Vermutung darüber äussern sollen, die sich wie eine definitive Aussage liest. Ich ziehe sie daher zurück. Was da wer und wann gedacht hat, bleibt vermutlich ohnehin auf immer im Dunklen. Es scheint mir im übrigen durchaus nicht unwahrscheinlich, dass derjenige, der das zum ersten Mal implementiert hat, dies auf die von mir beschriebene Weise getan hat und beim Testen erfreut festgestellt hat, dass er alleine durch das löschen des Interrupt-Flags, einen (nur einen) weiteren Interrupt erfassen kann, obwohl die ISR schon läuft. Aber ich will nicht darauf bestehen, das wäre albern. Andererseits ist der von Dir beschriebenen Maxime auch nicht vollständig entsprochen worden, denn spätestens der dritte Interrupt geht ja - in der beschriebenen Implementierung - fallweise doch verloren. Ist das nun, für sich genommen, ein Zeichen, dass er das gewollt hat? Oder hat er es hingenommen? Wenn ja, warum nicht auch die erste Eigenschaft? Er konnte allenfalls annehmen, das in der Praxis ein weiterer Interrupt reichen sollte. Das das oft nicht der Fall ist, zeigen aber meiner Meinung nach Mechanismen die mehrfach ausgelöst Interrupts zulassen (z.B. im Verein mit reentranten ISRs. Ich habe ja keinesfalls verneint, dass potentiell jeder Interrupt wichtig ist. Auch liest sich mein Text, meiner Meinung nach, keinesfalls so, als wenn ich mit der Beschreibung des Ablaufs sagen wollte, das dies der einzig sinnvolle ist, oder der, der alle denkbaren Anforderungen erfüllt. Sie zielte vielmehr auf den Fokus der Frage. Der war nicht, warum alle Interrupts erfasst werden (was ohnehin nicht der Fall ist; jedenfalls nicht unter gewissen weiteren Nebenbedingungen) sondern vielmehr, warum denn mehr als einer erfasst wird, in dem Kontext von Tastern, wo doch die nachfolgenden Interrupts (durch das prellen) so störend sind. Naja. Ich bemühe mich hier, klarzustellen, dass ich nicht völligen Unsinn erzählt habe. Ich weiß; Du bist in der Regel keiner der unbedingt Recht haben will. Ich bin da sensibler als Du. Aber was soll's? Es sollte dem TO helfen ein Verständnis zu entwickeln.
@ Peter D. Wenn ich mir das recht überlege, dann wäre es besser gewesen, als primäres Ziel zunächst das zu nennen, was Du, Peter, genannt hast: Nämlich das, möglichst viele, wenn nicht alle Interrupts erfasst werden sollen. Und dass das eben auch zur Folge hat, dass gerade bei Tastern unnötig viele Interrupts erfasst werden. Und dass das wiederum zu dem Ratschlag führt, Taster nicht mittels Interrupts zu erfassen. Also gut: Bark, bitte fasse meinen Beitrag in diesem Lichte auf. Ich hoffe ich habe Dich nicht allzusehr in die Irre geführt.
Hallo Fred, freut mich, dass Dir meine Erklärung gefällt. Ich suche selbst immer wieder nach möglichst einfachen Erklärungen mit expliten Anleitungen und kleinen Beispielen. Oft reichen MIR pauschale Aussagen wie "Flag löschen" nicht aus.Besonders immer dann, wenn ich ungeduldig mal etwas Neues ausprobieren möchte, und das Datenblatt irgendwie wieder viel zu lang und kryptisch ist. Diesmal habe ich mich eben durchgebissen und der kleine Artikel ist halt 7 Jahre nach Fragestellung entstanden :-) "Eins ist für mich noch unklar warum Interrupt in eine Art „Schieberegister“ sich die „Klicks" merken müssen." Eine Ausführliche Antwort hast Du ja mittlerweile erhalten :-) Hatte mir darüber noch keine Gedanken gemacht, aber war ein interessanter Ausflug noch ein Stück tiefer in die Hardware hinein. Mich als reinen Anwender der nur ganz simplen Code mit Bascom und ganz wenig in Assembler schreibt, hat dieses Verhalten des AVR`s eigentlich auch immer eher gestört. Aber: "it`s a feature, not a bug" Also klasse, dass Du mit Deiner Frage die Diskussion darüber ausgelöst hast. Vielen Dank auch an die nachfolgenden User für die interessanten Erklärungen. Alex
Staubfänger schrieb: > Andererseits ist der von Dir beschriebenen Maxime auch nicht vollständig > entsprochen worden, denn spätestens der dritte Interrupt geht ja - in > der beschriebenen Implementierung - fallweise doch verloren. Bei einem externen Peripheribaustein bleibt die Interruptleitung solange aktiv, bis alle Ereignisse abgearbeitet sind. Es geht also nichts verloren. Es kann aber passieren, daß keine neue Flanke erzeugt wird, da schon beim Eintritt in den Handler mehrere Ereignisse vorliegen. In dem Fall sollte man vor Verlassen des Handlers prüfen, ob die Leitung noch aktiv ist oder den zustandsgetriggerten Interrupt verwenden. Es gab allerdings auch MCs, die Interrupts ohne eigenes Pending-Flag hatten, z.B. der Scenix SX18. Da konnte dann nicht festgestellt werden, ob bei einem externen Interrupt auch gleichzeitig ein Timerinterrupt vorlag. Es konnten also Timerinterrupts verloren gehen. Ich hab dann beim Lesen des Datenblattes nur mit dem Kopf geschüttelt und die Eval-Samples samt Datenblatt in den Papierkorb befördert.
Hallo, nun auch noch mein Dank an Peter Dannegger und Staubfänger. Diese sachlichen Kommentare sind lesenswert. Nun weiß ich ein externer Interrupt ist nicht nur ein „Klick“ ,wie ich es lustigerweise bezeichne,um die Hauptschleife zu verlassen. Habe es immer nur als Art Aufruf eines Unterprogramm verstanden. Wichtiger Lerneffekt: Um Interrupt zu nutzen, sollten die Vor- Nachteile schon bei der Projektentwicklung hinterfragt werden. Mit freundlichen Grüßen
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.