Hallo zusammen! Ich hab kürtzlich ein Assembler-Programm geschrieben für einen ATINY12. Es geht hierbei um ein Zeitrelay, das ich mit einem BCD-Codierschalter in der Zeit variabel mache. Ich benötigte also, mit den 4 für den Schalter einen Eingang als Trigger (Int0) und ein Ausgang, alle Pins inclusive Reset-Pin. Ich programmierte also ein Programm was aus einem Init, einer Endlosschleife und 2 Interruptroutinen (INT0 und Timer) bestand. (Im Anhang) Ich wollte, dass ich nur Triggern kann, wenn der Ausgang nicht aktiv ist. Also hab ich (mit % markiert) entsprechende Befehle innerhalb der Intteruptroutinen verwendet. Resultat: Die Zeit läuft "meistens" doppelt so lange. Wahrscheinlich, setzt er den Timmer nicht zurück. und Ich kann während des aktiven Ausgans triggern, was ich wiederum auf die Interruptsroutinen zurückschliese. Nach langem probieren hab ich alles in ein Hauptprogramm geschrieben, welches auf die jeweiligen "kurzgeschriebenen" Interruptrourinen wartet. Jetzt gehts!!! Meine Frage hier also: Warum kann ich in einer Interruptroutine nur beschrängt Befehle verwenden und welche funktionieren?
Steven, Und den Stackpointer willst Du garnicht initialisieren? Dasd mal als erstes, ohne den Code genau angeschaut zu haben. Später vielleicht mehr... Jochen Müller
mhm ja den hab ich wohl vergessen... AVR-Studio konnte das aber ohne Probleme und Meldungen simulieren...
Vor Dein main: würde ich noch eine vernünftige ORG-Anweisung setzen, so liegt Dein Programmstart mitten in den (zwar ungenutzten) Int-Vektoren. Geht zwar, ist aber nicht sauber so. Natürlich gehen innerhalb einer Int-Routine ALLE Befehle. Jochen Müller
das problem ist, wenn in interrupt-routinen zu viele befehle stehen. da die interrupts nicht unterbrechbar sind gehen welche verloren solange eine isr läuft.
>Vor Dein main: würde ich noch eine vernünftige ORG-Anweisung setzen
Wie soll diese Anweisung in etwa aussehen?
Dankeschön!
MfG Ovular
Daniel, >>das problem ist, wenn in interrupt-routinen zu viele befehle stehen. da >>die interrupts nicht unterbrechbar sind gehen welche verloren solange >>eine isr läuft. Stimmt, ist jetzt aber etwas missverständlich ausgedrückt.... Nur zur Sicherheit: Es KÖNNEN interupts verloren gehen, Befehle nicht. Jedenfalls solange keine verschachtelten Interupts programmiert werden, was übrigens sehr wohl geht, aber mit Tücken behaftet ist. Jochen Müller
Jaja, ich hab das schon verstanden. Also ich gehe jetzt mal davon aus, dass das AVR-Studio nicht ganz so wie ein µC simuliert. Kurzum verwendet es keinen Stackpointer, sonst müsste ja auch hier Fehler geben. Wenn ich mal am Wochenende Zeit hab überleg ich mir mal, wie sich dieses fehlerhafte Programm genau verhält. Gruß Ovular
Steven W. wrote: > Also ich gehe jetzt mal davon aus, dass das AVR-Studio nicht ganz so wie > ein µC simuliert. Kurzum verwendet es keinen Stackpointer, sonst müsste > ja auch hier Fehler geben. Natürlich simuliert es auch den Stack-Pointer. Dass du keinen Fehler bekommst, obwohl du ihn nicht initialisierst, liegt daran, dass der ATtiny12 nur einen 3-Stufen Hardwarestack hat (weil er kein RAM hat). Und dieser Hardwarestack muss nicht initialisiert werden.
@Stefan Warum muss ich ihn dann initialisieren, wenn ich ihn nicht initialisieren muss? :-) Paradoxisch! Gruß Ovular
Steven W. wrote: > @Stefan > > Warum muss ich ihn dann initialisieren, wenn ich ihn nicht > initialisieren muss? :-) > > Paradoxisch! > > Gruß Ovular Du musst ihn nicht initialisieren, da er (mangels SRAM) in Hardware werkelt. Du musst nicht immer alles glauben, was Taschenbuch schreibt, schau lieber ins Datenblatt. ;-) ...
> Warum muss ich ihn dann initialisieren, wenn ich ihn nicht > initialisieren muss? :-) Jochen Müller ist in seinem ersten Beitrag einem Irrtum erlegen. Die Initialisierung braucht man bei allen neueren AVRs, da diese On-Chip-RAM haben und den Stack dort ablegen. Zu den alten RAM-losen Typen mit Hardware-Stack gehören außer dem Tiny12 noch der Tiny11 und der Tiny15. Alle anderen dürften mittlerweile vom Markt verschwunden sein.
yalu wrote: > Jochen Müller ist in seinem ersten Beitrag einem Irrtum erlegen. Die > Initialisierung braucht man bei allen neueren AVRs, da diese > On-Chip-RAM haben und den Stack dort ablegen. Zu den alten RAM-losen > Typen mit Hardware-Stack gehören außer dem Tiny12 noch der Tiny11 und > der Tiny15. Alle anderen dürften mittlerweile vom Markt verschwunden > sein. Stimmt auch nicht ganz: Bei den meisten ganz neuen AVRs kann man sich die Stack-Initialisierung ebenfalls wiederum sparen, weil der Stack Pointer bei einem Reset automatisch initialisiert wird (auf das Ende des RAM). Bei der Mega48/88/168-Reihe war das z.B. schon so.
Achja, zum eigentlichen Problem (ohne Deinen Quelltext jetzt gelesen zu haben), die Ursache könnte sein: Du hast in der ISR (ext-Int) eine "Zeitvernichtungsroutine". Du bleibst also in der ISR, bis die Zeit abgelaufen ist. Du hast am ext-Int einen mechanischen Taster. Taster prellen. Wenn während der Abarbeitung der ISR der nächste Prellimpuls kommt, wird über GIFR ein neuer Interrupt angemeldet, der sofort nach Ende der ISR aubgearbeitet wird. Dies erklärt die doppelte Zeit. Als Abhilfe könnte man als letzten Befehl der ISR das Interrupt-Flag in GIFR löschen, aber so richtig gut wird das auch nicht. Besser ist es, einre ordentliche Entprellung (im Timer-Interrupt) vorzusehen, diesen Timer-Interrupt auch als Basistakt für die Verzögerung zu benutzen und die Verzögerung in Software herunterzuzählen. ...
@Hannes Also Zeit vernichte ich in der INT0-Routine nicht. Aber ne Entprellung hab ich tatsächtlich nicht. Ich dachte eben, dass ich die nicht brauche, weil ich ja den Interrupt "deaktiviere"... Also gut, dann werde ich nochmal ein neues Programm schreiben, ohne Stackinitialisierung mit Entprellung und schön Sauber programmiert Ich stelle es dann hier in den Thread und will wissen, was ich bessermachen kann... Danke! Gruß Ovular
Hannes Lux wrote: > Du hast am ext-Int einen mechanischen Taster. Taster prellen. Wenn > während der Abarbeitung der ISR der nächste Prellimpuls kommt, wird über > GIFR ein neuer Interrupt angemeldet, der sofort nach Ende der ISR > aubgearbeitet wird. Dies erklärt die doppelte Zeit. Als Abhilfe könnte > man als letzten Befehl der ISR das Interrupt-Flag in GIFR löschen, aber > so richtig gut wird das auch nicht. Ich würd mal sagen, Du hast den Nagel auf den Kopf getroffen. Doppelte Zeit riecht penetrant nach fehlender Entprellung. Warum wird immer gedacht, Entprellung ist nur was für umfangreiche Programme? Peter
Mooooment!!! Ich glaub ich verstehe jetzt was ihr denkt... Aber Ihr solltet euch mal lieber das Programm ansehen. Doppelte Zeit kann hier eigendlich nicht zustande kommen... Ich warte ja schließlich außerhalb der Routinen. Wenn innerhalb von 50ms nochmal getriggert werden würde, würde der Zähler zwar wieder auf seinem Ausganswert stehen, so wie ich ihn eingestellt hab, aber doppelte Zeit?
Steven W. wrote: > Aber Ihr solltet euch mal lieber das Programm ansehen. Ist längst geschehen. > Doppelte Zeit kann hier eigendlich nicht zustande kommen... Kann sehr wohl. Du disablest den externen Interupt in sich selbst und enablest ihn erst wieder nach Ablauf der Zeit und erst dann kann er ja wieder auf das schon ewig gesetzte Pending-Flag hin interrupten. Peter P.S.: Man könnte das uralte Pending-Flag direkt vor der erneuten Freigabe setzen, um es zu löschen. Hilft in diesem konkreten Fall. Entprellen ist aber besser, hilft in jedem Fall und man muß nie wieder daran denken.
Achso ja jetzt! Sorry ich dachte der nächste Interrupt kommt schon nach der INT0-Routine zustande. Okok! Eigendlich ja logisch... Naja Also ich teste das nochmal Gruß Ovular
> Jochen Müller ist in seinem ersten Beitrag einem Irrtum erlegen. Oh je... Das stimmt. Wenn man wie ich, ständig mit den grossen AVR arbeitet, hält man sowas intuitiv für nicht vorstellbar, dass der keinen wirklichen Stack hat. Also: Immer schön das Datenblatt lesen! Jochen Müller
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.