Hallo Freunde,
mann - ich weiß gar nicht mehr wieviele TAGE ich mit diesem Problem
schon verbringe, bitte um Hilfe!? Ich habe schon ein großes Programm
(Infrarotumwandler) laufen, alles läuft super.
- ich starte einen Timer0 und dieser wird nach 2 Sekunden beendet > OK
- ich möchte den Wert "timerstatus" 1 zurückgeben, um es im
Hauptprogramm auszuwerten > geht nicht!
Codeschnipsel:
ldi temp1, (0<<TOIE0) ; TOIE0: Interrupt bei Timer Overflow
17
out TIMSK, temp1 ; Timer0 wieder ausschalten
18
19
sbi PORTB,1 ;portB bit1 setzen (1: led an 5v ist an)
20
rcall pause500ms
21
cbi PORTB,1 ;led aus
22
23
ldi temp1,1
24
sts timerstatus, temp1 ;timerstatus auf 1 setzen
25
26
end_OVF0:
27
28
pop temp1
29
out sreg,temp1 ; sreg wieder herstellen
30
pop temp1
31
reti ; das wars. Interrupt ist fertig
32
33
--------- HAUPTPROGRAMM
34
35
lds temp,timerstatus
36
cpi temp,0 ; Werte gleich?
37
breq merker_abfrage ; ja: springe zu ...
38
rjmp timer0ueberlauf ; nein: springe zu ...
Und hier liegt das Problem, das Programm springt nie zu "timerueberlauf
:-(. Habe meiner Meinung nach schon alle Variationen getestet (aktuell
im Beispiel mittels SRAM, ich hab aber schon alle möglich Register und
ähnliche getestet!!), "timerstatus" funktioniert nicht.
Bitte um Hilfe, wie macht man das richtig?
Grüße, Walter
> rjmp timer0ueberlauf ; nein: springe zu ...
Das Label timer0ueberlauf gibt es in deinem Codeschnippsel nicht;
viele andere (merker_abfrage) übrigens auch nicht.
Damit das rjmp ausgeführt wird muss timerstatus ungleich 0 werden.
Dazu muss die ISR OVF0_addr ausgeführt werden.
Ich sehe in HAUPTPROGRAMM nicht, wie das geschehen soll: Weit und breit
keine Initialisierung von Timer0 inkl. sei zu sehen.
Hi
Hänge mal dein komplettes Programm an. In dem Schnipsel kann ich auf den
ersten Blick, außer teilweise etwas umständlicher Programmierung keinen
wirklichen Fehler entdecken.
MfG Spess
danke an alle vorerst, ich hab mal etwas mehr Code angehängt (stark
gekürzt)! Der 2 Sekunden-Timer funktionierte immer, das sehe ich am
kurzen LED blinken am Start und nach 2 Sekunden.
Einige Zeilen hat mir vorhin leider das Texteinfügen hier im Beitrag
"verschandelt". @Krapao: ich check das gleich mal...
Danke
hmmm... hab noch keine Lösung gefunden, zweifle stark an mir selbst
;-)...
".equ rFlg=0 ; Flaggenregister zur Kommunikation"
gehört raus, das ist von früheren Versuchen !
Meine aktuelle Not-Idee: in der Interruptroutine einen Port setzen und
im Hauptprogramm abfragen??
Danke, Walter
Hi
>Ich kenn zwar kein Assembler, aber ich könnte mir gut vorstellen, dass>dir das Stichwort "volatile" weiterhelfen wird.
Nein. Das ist dem Assembler unbekannt.
MfG Spess
Mit dem Begriff "volatile" hab ich auch schon einen Abend verbracht,
aber es war nichts Vergleichbares für Assembler zu finden (die Register
irgendwie global zu definieren)...
Ich versteh's einfach nicht: wenn ich der ISR z.B. "status = 1"
definiere, warum ich im Hauptprogramm dann keinen Sprung daraus ableiten
kann???
Verändert das "reti" irgendwas an den Registern?
Walter
;läuft timer? in Sonderfällen stoppen >>>>> funktioniert
19
20
rcall timer0stoppen ;timer für Farbe läuft noch, Farbtaste abbrechen und neue auswerten
Du stoppst bei JEDEM Durchlauf von merker_abfrage den Timer0! Der Timer
läuft nur äußerst kurz!
Beim nächsten Einschalten läuft er nochmal ein Stückchen, weil TCNT0 nur
vom Überlauf selbst gelöscht wird. So hangelt sich der Timer sich immer
weiter vor.
ICh denke, es liegt ein Logikproblem vor und dazu muss man wissen, was
es mit den Kommandos merker, satgelb, command D4 und satgelblang auf
sich hat bzw. was wann passieren soll.
Zur leichteren Simulation und zum besseren Überblick habe ich die Source
leicht verändert und Angaben eingefügt, wo Breakpoints hin kommen können
(Anhang).
DANKE - ich hab selbst gelöst (nach geschätzten mehr als 20 Stunden
herumprobieren)!!!!
Besonderer Danke an Krapao, der sich wirklich hineingefühlt hat. Ich
glaub durch meinen Forumspost stieg meine Lust zum Denken wieder an ;-).
@Krapao: ok, das sah jetzt im Code so aus, aber in Wirklichkeit kam das
Programm nur an diese Stelle "rcall timer0stoppen", wenns auch gewünscht
war.
Mein Programm hat nämlich 2099 Textzeilen (schlecht programmiert, aber
funktioniert ;-) ), das wollte ich niemand zumuten.
Wo lag der Fehler?:
- ich hab als letzte Möglichkeit den Weg über Port setzen und abfragen
getestet > auch kein Erfolg.
- plötzlich kam nach einem zufälligen Tastendruck ca. 7 Sekunden
später reproduzierbar der gewünschte Sprung !!
- die Analyse ergab, mein Programm kam nach dem "RETI" nicht wie geplant
regelmässig zur "detect_start" zurück, sondern hing ca. 30 Zeilen
entfernt in einer "detect_start2" Schleife fest und wartete auf ein
Fernbedienungssignal... :-P
DANKE nochmal für die Gedankenanstösse - Walter
@Krapao:
stimmt, ich sollte mein Programm optimieren und den ganzen Code (naja,
es funktioniert auch so und im Mega8 ist noch Platz genug für
umständliche Programmierung) strukturieren.
Aber danke, dein Code wird mich zum Optimieren anregen...
Mein Programm empfängt und sendet Fernbedienungssignale, das finde ich
etwas schwer zu simulieren. Wegen des kritischen Timings.
Ok, ich hab Hilfe im Forum gesucht, wollte aber meinen Code nicht
einfach öffentlich machen, weil doch schon jahrelange Arbeit drinsteckt!
Natürlich ist mit einem kleinem Bruchteil des Codes alles schwer zu
verstehen.
LG.
Walter Pr. schrieb:> Ok, ich hab Hilfe im Forum gesucht, wollte aber meinen Code nicht> einfach öffentlich machen, weil doch schon jahrelange Arbeit drinsteckt!
zum einen hätte mein Deutschlehrer da "Logik?" an den Rand geschrieben,
zum anderen wenn du schon selbst schreibst
Walter Pr. schrieb:> umständliche Programmierung
brauchst du nicht befürchten, dass dir da jemand was wegnimmt
Walter Pr. schrieb:> @Krapao:> stimmt, ich sollte mein Programm optimieren und den ganzen Code (naja,> es funktioniert auch so und im Mega8 ist noch Platz genug für> umständliche Programmierung) strukturieren.> Aber danke, dein Code wird mich zum Optimieren anregen...
Nein, du sollst ihn nicht optimieren (zumindest jetzt noch nicht).
Du sollst ihn in erster Linie verständlich machen!
Und erst dann, wenn du dann feststellst, dass du
* zu langsam bist
* rausbekommen hast, wo die Rechenzeit draufgeht
erst dann beginnt man mit Optimierung, mit dem Feintuning. Wobei man
auch da zuerst einmal nachsieht, ob man auf Algorithmenebene etwas
erreichen kann.
> Ok, ich hab Hilfe im Forum gesucht, wollte aber meinen Code nicht> einfach öffentlich machen, weil doch schon jahrelange Arbeit drinsteckt!
Dann hast du jetzt am eigenen Leib erfahren, dass es wichtig ist, dass
Code in erster Linie verständlich und nachvollziehbar ist. Das ist die
oberste Prämisse, denn nach einigen Monaten/Jahren hat man die Details
der veranstalteten Schweinerein schon längst vergessen.
Code ist nie fertig. In jedem realen Code, abseits von Micky-Mouse
Lehrbuchbeispielen, gibt es immer wieder Dinge, die man besser,
verständlicher, übersichtlicher ausdrücken kann. Und sei es nur, dass
man durch die Code-Formatierung und zwischenschieben von
Blockkommentaren wieder einen Schritt in Richtung 'Verbesserung' macht.
Es gibt 2 Sorten von Programmierern:
* die einen, die dauern jammern, dass ihr Code so unübersichtlich ist,
dass sie sich nicht mehr auskennen, dass sie den Überblick verloren
haben und die nichts dagegen tun. Das sind auch die Programmierer,
die sich sagen: Ich hab jetzt Stunden damit verbracht, das irgendwie
zum laufen zu bekommen (ich weiß zwar nicht genau wie, interessiert
mich auch nicht), aber ich rühr das jetzt auf keinen Fall mehr an.
Das sind meistens die, die die tollsten Fehler in ihren Programmen
haben
* und es gibt diejenigen, die auch schon mal ein paar Stunden nur
zur Codepflege investieren.
Die haben zwar auch ab und an mal Fehler im Programm, aber die
sind meistens von der Art, dass es sich einfach nur um leicht
zu behebende Irrtümer oder Tippfehler handelt oder aber die sich
durch etwas andere Codestrukturierung beheben lassen. Die generelle
Codestruktur ist aber in Ordnung, so dass sich Fehler meistens nur
lokal auswirken.
PS: die erste Sorte der Programmierer erkennt man zb auch daran, dass
sie 'Variablennamen' benutzen, die entweder kein Mensch versteht (weil
bis zur Unkenntlichkeit verstümmelt abgekürzt) oder aber die so banal
sind, dass sie komplett nichtssagend sind. Wie zb Test1, Test2, Test3,
Merker1, Merker2, etc.
Walter Pr. schrieb:> ich sollte mein Programm optimieren und den ganzen Code (naja,> es funktioniert auch so und im Mega8 ist noch Platz genug für> umständliche Programmierung) strukturieren.
Der Punkt ist nicht, daß der Flash knapp wird, sondern daß Du damit
Deine eigene Zeit vergeudest.
Du brauchst viel Zeit, um den Code später selber wieder verstehen zu
können. Und nochmehr Zeit, um in dem Wust Fehler zu suchen oder
Erweiterungen vorzunehmen.
Übersichtlich und modular zu programmieren braucht zu Anfang etwas mehr
Zeit, die man aber in der späteren Projektphase 100-fach wieder
reinholt.
Walter Pr. schrieb:> Mein Programm empfängt und sendet Fernbedienungssignale, das finde ich> etwas schwer zu simulieren. Wegen des kritischen Timings.
FBs haben nur sehr kleine Datenraten, da sollte kein Timing kritisch
sein.
Vermutlich ist nur der Programmablaufplan schlecht erstellt oder
garnicht existent.
Walter S. schrieb:> Walter Pr. schrieb:>> umständliche Programmierung>> brauchst du nicht befürchten, dass dir da jemand was wegnimmt
Stimmt, schlechter Code ist der beste Kopierschutz.
Peter
>>> umständliche Programmierung>> brauchst du nicht befürchten, dass dir da jemand was wegnimmt>Stimmt, schlechter Code ist der beste Kopierschutz.
haha, mag sein. Trotzdem weiss ich, dass einige Leute gerne die fertige
HEX-Datei hätten ;-).
Danke nochmal für die Hilfe und den netten Umgangston hier im Forum,
Walter
PS: der Timer läuft zwar jetzt soweit, nur irgendwie steckt nun woanders
der Hund drinnen - aber ok, ich such erst mal selbst den Fehler und erst
wenns nicht mehr weiter geht, meld ich mich wieder...