Hallo zusammen, ich bin noch ziemlich neu in der uC-Programmierung. Ich wollte ein Programm schreiben, dass 2 verschiedene Blink-Programme ausführt. Im ersten Programm sollen PortD und PortB blinken und im zweiten Programm sollen sie ganz simpel leuchten. Das Blinken geschieht in Timer0 und funktionierte in vorherigen Tests auch schon. Der Programmwechsel sollte im OverflowHandler von Timer1 stattfinden, aber das klappt leider nicht so ganz. Vielleicht könnte mir jemand Denkanstöße liefern und andere Fehler in meinem Quelltext finden? Vielen Dank, Eroli
1 | |
2 | |
3 | |
4 | |
5 | |
Nach dem Ausführen dieses Codes ist in TIMSK nur TOIE1 gesetzt, TOIE0 nicht.
Hallo, erstmal Danke für deine Antwort. Auf solche Stolperfallen muss man erstmal achten... Habe das nun so umformuliert:
1 | |
2 | |
Das gesamte Programm habe ich nochmal angehangen. Leider ist das Verhalten immer noch nicht ganz richtig. Nach ca. 60 Sekunden fängt es an zu blinken und dann hört es nie wieder auf. Leider kann ich das auch nicht debuggen, da meine Breakpoints (je einer in der ersten Zeile des Overflow-Interrupts) nicht erreicht werden oder zumindest nicht feuern (das Programm läuft einfach weiter?) Kann mir einer sagen, woran das liegen könnte?
Gast
#2070173
Hi Das passt nicht so richtig: > ... > brge resetProg ; "Programmüberlauf" --> prog = 0 > > pop temp ; LESEN von SREG vom STACK (KOPIE) > out SREG, temp ; Wiederherstellen von SREG > pop temp ; Wiederherstellen von "TEMP" > >resetProg: > ldi prog, 0x00 ; Zuruecksetzen > reti resetProg wird immer ausgeführt. Bei dem Sprung zu resetProg wird SREG und der Stack nicht wieder rekonstruiert. MfG Spess
Du startest nur Timer1, bei dessen ersten Überlauf wird dann Prog0 ausgeführt (Timer 0 starten fürs Blinken). Und bei jedem weiteren Überlauf wird wieder Prog0 ausgeführt, weil am Ende jedes Überlaufs prog mit 0 geladen wird. Bei letzterem kann man schon fast "zum Glück" sagen, denn würde bei dem "inc prog" tatsächlich prog mal 2 werden, verabschiedet sich dein Programm ins Nirwana (weil dann das SREG-Zurückschreiben und Stack-Aufräumen gar nicht ausgeführt werden würde).
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
Ist es so besser?
Besser, aber immer noch nicht richtig. prog wird immer noch in jedem Interrupt wieder auf 0 gesetzt.
Wollte es noch editieren, aber da war es schon zu spät: So sollte es nun aber doch funktionieren, oder?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
EDIT: Es Funktioniert wirklich :-) Nochmal vielen Dank an alle helfenden Hände :-) EDIT2: Wie könnte ich denn ein weiterschalten zum nächsten Programm per Taster erzwingen? Kann ich bei einem Druck auf einen Taster einen TimerOverflow erzwingen?
Nochmals Hallo zusammen, kann mir vielleicht noch jemand verraten, wie man das Weiterschalten zum nächsten Programm per Taster zusätzlich auf die Reihe kriegt? Außerdem wollte ich mein Programm um ein neues Blinprogramm erweitern, welches ich ebenfalls in Timer0 ausführen wollte. Bei diesem Programm sollen die LEDs der Reihe nach angehen... Da ich immer noch nicht weiß, wie ich Interrupts debuggen kann (dort werden keine Breakpoints erreicht??), habe ich den Code testweise mal in die mainloop gepackt und dann debugged. Das Ergebnis war, dass das Programm am Ende immer auf RESET sprang und damit bei 0 anfing und das war natürlich falsch. Ich weiß jedoch nicht, woran das liegt? Vielen Dank für eure Hilfe im vorraus, Eroli
Gast
#2071025
Hi >Da ich immer noch nicht weiß, wie ich Interrupts debuggen kann (dort >werden keine Breakpoints erreicht??), Die werden schon erreicht. Das dauert nur sehr lange. Setze zum debuggen einfach die Prescaler der Timer auf 1. > .... > rjmp ende <- unnötig >ende: > ldi temp, 0x00 <- unnötig > out TCNT1L, temp <- beim Overflow fängt der Timer > out TCNT1H, temp <- wieder von Null an Ändere den Teil: > pop temp ; LESEN von SREG vom STACK (KOPIE) > out SREG, temp ; Wiederherstellen von SREG > pop temp ; Wiederherstellen von "TEMP" > inc prog ; Kein "Programmüberlauf" > cpi prog, 2 ; maximales Programm > brge resetProg ; "Programmüberlauf" --> prog = 0 > reti ; Hier mögliches Ende >resetProg: > ldi prog, 0x00 ; Zuruecksetzen > reti mal in
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
um. >ldi temp, 0b101 >out TCCR1B, temp macht man besser so: ldi temp,1<<CS12|1<<CS10 out TCCR1B, temp Ich habe dein Programm nur mal überflogen. Das ist wahrscheinlich nicht alles. MfG Spess
Habe deine Vorschläge mal berücksichtigt, aber einige Fragen: 1) Warum wird der Stack im Timver1Overflow nur rekonstruiert, wenn ein "Programmüberlauf" stattfindet? 2) Zum Debuggen: In der Schaltung wird nach ca. 60 Sekunden das erste Mal das Programm gewechselt. Wenn ich den Debugger anschmeisse und in AVR Studio4 auf Debug-->Run gehe, wird dann nicht bis zum Erreichen eines Haltepunkts laufen gelassen oder wird das debuggen quasi beendet und nur noch ausgeführt? Habe mit obiger Methode (Debug-->Run) schon ca. 10 Minuten darauf gewartet, dass ein Haltepunkt erreicht wird - ohne Erfolg. Mit deinen Änderungen sehe ich folgendes Verhalten in meiner Schaltung: Erst leuchtet alles, so wie es soll und nach ca. 60 sekunden fangen sie zu blinken an, aber das machen sie dauerhaft. Das nächste Programm wird nicht mehr erreicht, aber es wird auch nicht mehr zum ersten Programm (dauerhaftes leuchten) zurückgeschaltet... Irgendwie ist da der Wurm drin...
Gast
#2071090
Hi >1) Warum wird der Stack im Timver1Overflow nur rekonstruiert, wenn ein >"Programmüberlauf" stattfindet? Das bezog sich auf das Programm von: Beitrag "Re: ATmega8 Timer Problem" >2) Zum Debuggen: In der Schaltung wird nach ca. 60 Sekunden das erste >Mal das Programm gewechselt. Wenn ich den Debugger anschmeisse und in >AVR Studio4 auf Debug-->Run gehe, wird dann nicht bis zum Erreichen >eines Haltepunkts laufen gelassen oder wird das debuggen quasi beendet >und nur noch ausgeführt? So richtig verstehe ich die Frage nicht. Ich gehe mal davon aus, das du mit 'Debugger' den Simulator meinst. Mit Debug-->Run wird das Programm simuliert, bis ein Haltepunkt erreicht wird oder du den Ablauf mit 'Break' unterbrichst. Während 'Run' läuft werden keine Registeranzeigen aktualisiert. Die Simulation ist wesentlich langsamer als der reale AVR. Wenn ich in deinem Programm die Prescaler der Timer von 1024 auf 1 setze, kommen die Interrupts im Simulator im Sekundenrhythmus. >Mit deinen Änderungen sehe ich folgendes Verhalten in meiner Schaltung: >Erst leuchtet alles, so wie es soll und nach ca. 60 sekunden fangen sie >zu blinken an, aber das machen sie dauerhaft. Das nächste Programm wird >nicht mehr erreicht, aber es wird auch nicht mehr zum ersten Programm >(dauerhaftes leuchten) zurückgeschaltet... Ich hatte geschrieben >Ich habe dein Programm nur mal überflogen. Das ist wahrscheinlich nicht >alles. Mit der Änderung werden erst mal alle drei 'Programme' im Timer1-Overflow abgearbeitet. Ob die jetzt richtig sind, kann ich dir im Moment auch nicht sagen. MfG Spess
Gast
#2071183
Hi Noch etwas: Könnte es sein, das du im Timer0_Overflow mit dem falschen wert für 'prg' arbeitest? Du stellst im Timer1_Overflow ein bestimmtes Programm ein und änderst danach die Programmnummer, auf die du im Timer0_Overflow wieder zugreifst. MfG Spess
Hallo zusammen, habe gestern nochmals meine Konzentration zusammengenommen und einige Stunden experimentiert. Dabei ist mir aufgefallen, dass da an vielen Stellen noch einiges ziemlich schief lief. Ich habe nach und nach alle Fehler ausgemerzt (und andere auch nochmal eingebaut :-D), aber nach 7 Stunden Arbeit funktioniert mein Programm erstmal :-) Vielen Dank an die geduldigen Helfer und die Denkanstöße :-)
Gast
#2072830
Hi Kleiner Vorschlag: wenn du für dein Blinkprogramm die Ports gleich im Timer1_Overflow inialisierst, kannst du den Teil: >blinken: > sbic PORTB, 0 ;Nächsten Befehl überspringen, falls Bit0 abm PortB ist > > rjmp led_ein ;Ansonsten LED einschalten (s. unten). > sbis PORTB,0 ;Überspringen, falls Bit0 abm PortB ist EIN (= LED ist > rjmp led_aus ;Ansonsten LED ausschalten (s. unten). > led_ein: ;Zum Einschalten: > ldi temp, 0x00 > out PORTB, temp > out PORTD, temp > rjmp end ;und beenden. > led_aus: ;Zum Ausschalten: > ldi temp, 0xFF > out PORTB, temp > out PORTD, temp > rjmp end auf
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
eindampfen. >Ich habe nach und nach alle Fehler ausgemerzt ... Und was ist das? >cpi prog, 3 >breq aufsteigend Deine Programmnummer gehen doch nur von 0..2. MfG Spess
Danke, werde das noch verkürzen. >>cpi prog, 3 >>breq aufsteigend > >Deine Programmnummer gehen doch nur von 0..2. Die Programmnummern sind im Timer0 um eins höher, da sie am Ende von Timer1 ja schon erhöht werden. Ist etwas tricky, aber wenn man es weiß, dann klappt es ganz gut ;-)
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.