Hallo Forum, ich versuche eine "Statemachine" zu realisieren. in Register r24 wird der aktuelle Status gehalten und mitteles eines Tasters weitergeschaltet. In Status 1 und 2 läuft ein Timer der dann bei einem bestimmten Stand abschaltet. So der Gedanke!!!! Es klappt soweit das der Timer nach Betätigung des Tasters anläuft. Auf wundersame Art und Weise ändert sich der Status von alleine und der Timer stopt. Was um Gottes Willen ändert den Inhalt von r24????? Ich habe den Quellcode (Assembler) als zip angehängt. Es wäre schön, wenn jemand sich das mal anschaut und mir einen Tip gibt Gruß hubupet
Kleiner Tip: Wenn du möglichst viele Leute ermuntern willst, deinen Code zu studieren, dann mach es ihnen einfach das zu tun. Ein 2 Seiten Assembler File in einem Zip-File zu verpacken, ist für die Helfenden mit zusätzlicher Arbeit verbunden. Also lass es. Häng dein Assembler File als Attachment an und jeder kann es ohne zusätzliche Schritte, wie entpacken, lesen. In diesem Sinne: neues Attachment
Hallo Karl Heinz Danke für den Tip und die Änderung Gruß Peter (hubipet)
hubipet schrieb: > Auf wundersame Art und Weise ändert sich der Status von alleine und der > Timer stopt. Was um Gottes Willen ändert den Inhalt von r24????? Was heißt 'der Status ändert sich von alleine'. Dir ist schon klar, dass du deinen Taster gar nicht so schnell wieder loslassen kannst, dass dir dein Status nicht durch die Tastenbetätigung alleine bis zum State 4 durchrauscht? Zusätzlich solltest du in deiner iSR auf jeden Fall noch das SREG sichern. Und deine Zeitweiterschaltung stimmt IMHO auch nicht. Hauptproblem denke ich, ist aber die Tastenabfrage. Alles in allem finde ich deinen Code ziemlich unübersichtlich durch die vielen Hin und Her Sprünge.
hubipet schrieb: > Test4: > cpi State, 4 > rcall State4 > rjmp loop ; Zurueck nach Loop Fehlt hier nicht was hinter cpi und vor rcall? Aber: .DEF State = r24 ... rcall State4 ... State4: clr State State4 wird immer angesprungen wenn die vorherigen Abfragen ins leere laufen.
In State3 sicherst du r28 (alias "secs") nicht, bevor du es überlädst. Weiß aber nicht ob das für dein Problem verantwortlich ist.
Ich denke, dass ich in der Button routine darauf warte, dass der Taster wieder losgelassen wird und ich auf die steigende Flanke reagiere. Ich gebe dir natürlich Recht: Das ist alles unübersichtlich und lässt sich besser machen. Ist halt nur ein erster Ansatz "Quick and dirty" Peter
Die SREG Geschichte in der ISR leuchtet ein. Interrupts sind ja asynchron und man weiss nie genau wann sie zuschlagen Gruß Peter
hubipet schrieb: > Ich denke, dass ich in der Button routine darauf warte, dass der Taster > wieder losgelassen wird und ich auf die steigende Flanke reagiere. Ich bins noch mal durchgegangen. Ich denke du hast recht hast aber trotzdem etwas übersehen: Tasten prellen. Entprellung Auch wenn du nur einmal die Taste niederdrückst und wieder loslässt, heißt das nicht, dass du nur 1-nen 1-0 und einen 0-1 Übergang am Pin kriegst. Zudem, wenn ich mich nicht noch einmal vertan habe, musst du die Taste genau in dem Moment loslassen, in dem sich das Programm in rcall delay50us befindet. Diw Wahrscheinlichkeit dafür ist recht hoch, weil der Rest nicht allzuviel Zeit beansprucht, aber sie ist nicht 100%, d.h. es kann sein, dass dein Programm ein paar Tastenloslasser übersieht.
Hallo Karl Heinz ich benutze eine Hardwareentprellung (RC-Glied -> Schmitt-Trigger). Habe das mit einem Logikanalyser überprüft (IKALOGIC). Sieht da gut aus. Das Problem ist: Wenn der Timer nicht läuft bleibt das Teil stundenlang im gleichen Status. Betätige ich den Taster läuft der Timer los. Auch noch OK. Aber nach einer nicht reproduzierbarer Zeit ändert sich r24 und der Timer bleibt stehen. Habe das Prog. geändert und sichere das SREG auf den Stack. Problem bleibt!!!!!!!!!!!!!!! Gruß Peter
hubipet schrieb: > im gleichen Status. Betätige ich den Taster läuft der Timer los. Auch > noch OK. > Aber nach einer nicht reproduzierbarer Zeit OK, davon war bisher noch nicht die Rede. Das bewegt isch also im Sekundenbereich, ohne dass auf der Taste etwas passiert, weder Drücken noch Loslassen?
Wenn du innerhalb der ISR r16 selbst nicht benutzt, r16 aber zum Sichern des SREG benutzen willst, dann kannst du das nicht so machen
1 | onCompA: |
2 | in r16, SREG |
3 | push r16 |
der push ist hier sinnlos, da du innerhalb der ISR r16 sowieso nicht angreifst. Aber: r16 ist nach Aufruf der ISR zerstört worden. Wenn schon, dann so rum
1 | onCompA: |
2 | push r16 ; r16 frei machen |
3 | in r16, SREG ; r16 zum sichern vom SREG benutzen |
und natürlich beim Pop auch anders rum.
Das verstehe ich jetzt nicht ganz!? Ich lade das SREG in r16. Schiebe r16(SREG) auf den Stack um den Inhalt des SREG zu sichern. Am Ende der ISR hole ich r16 vom Stack zurück und bringe das SREG auf den Zustand zurück den es zu Begin der ISR hatte. Danach "reti". Vielleicht umständlich da ich mir push und pop sparen könnte und SREG nur in r16 sichere weil ich das Register in der ISR nicht benutze aber sicher ist sicher - oder nicht - ? Peter
Hi Damit veränderst du aber r16. Und das sollte nach der ISR unverändert sein. MfG Spess
Hallo, Bei ISR-Routinen gilt für Assembler: ALLE benutzten Register, die auch im Hauptprogramm verwendet werden, müssen zu Anfang der ISR gesichert werden (PUSH) und am Ende wieder hergestellt werden (POP); es sei denn, sie werden als Übergabe-Register zum Hauptprogramm gebraucht. Mit deinem R16 wäre das dann: Start: push r16 ; Inhalt von R16 auf Stack sichern in r16, SREG ; SREG über R16 auf Stack sichern push r16 Ende: pop r16 ; SREG über R16 vom Stack holen und zurückspeichern out SREG, r16 pop r16 ; alten Inhalt von R16 vom Stack zurückspeichern reti Dann wird kein Register des Hauptprogrammes beeinflusst. Oder du benutzt in der ISR ein noch nicht verwendetes Register; dann muss auch nichts gesichert und wiederhergestellt werden (ausser das Status-Register; das sollte man immer auf dem Stack zwischenspeichern, wenn man SREG-beeinflussende Befehle verwendet).
OK. Sichere jetzt r16 auf dem Stack -> lade SREG in r16 -> r16 auf den Stack -> ISR -> r16 vom Stack -> zurück in SREG -> r16 vom Stack ->reti. Das geht!!! Läuft seit 15 min. Hab ich jetzt so nach Forum blind so programmiert. Da muss ich aber mein Prog noch mal genau duchforsten wo die Macke versteckt war - sprich r16 vom Interrupt nicht verändert werden darf -. Danke an alle !!!!!!!!!! Gruß Peter
Hi >Da muss ich aber mein Prog noch mal genau duchforsten wo die Macke >versteckt war - sprich r16 vom Interrupt nicht verändert werden darf -. Die Macke war deine ISR! MfG Spess
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.