Hallo miteinander, ich habe eine kurze frage zu Interrupts. Mit dem 16 Bit Timer des ATmega8 möchte ich gerne ein Zahl hoch zählen. Der Interrupt funktioniert soweit auch. Allerdings habe ich das Problem, dass der Interrupt nur ein einziges mal ausgeführt wird und dann nichts mehr. Kann ich innerhalb eines Interupthandlers bestimmte Funktionen mir rcall aufrufen und dann mit RET wider zurück springen? Wenn der Interrupt in einer Endlosschleife ausgelöst wurde springe ich dann mit RETI zurück in diese Schleife oder zurück zur Interrupt Adresse?
Konrad M. schrieb: > Kann ich innerhalb eines Interupthandlers bestimmte Funktionen mir rcall > aufrufen und dann mit RET wider zurück springen? Ja. > Wenn der Interrupt in > einer Endlosschleife ausgelöst wurde springe ich dann mit RETI zurück in > diese Schleife oder zurück zur Interrupt Adresse? RETI springt exakt dorthin zurück, wo untergebrochen wurde. Interrupts halten also den Programmfluss im Hauptprogramm nur temporär auf, ändern ihn aber nicht.
Konrad M. schrieb: > Kann ich innerhalb eines Interupthandlers bestimmte Funktionen mir rcall > aufrufen und dann mit RET wider zurück springen? Kannst du, aber ob du das solltest, müsstest du dich selbst hinterfragen. Um ein halbwegs gescheites Timing hinzukriegen sollten deine ISRs auch von einer überschaubaren Komplexität sein. > Wenn der Interrupt in > einer Endlosschleife ausgelöst wurde springe ich dann mit RETI zurück in > diese Schleife oder zurück zur Interrupt Adresse? Vergegenwärtige Dir doch mal, was die eigentliche Aufgabe von RET ist (was passiert da auf dem Stack). Da die Interruptbehandlung eine Unterbrechung des normalen Programmablaufs ist, erfordert diese einen speziellen Befehl um wieder in den normalen Programmablauf zurückzuspringen - und das macht RETI.
Danke soweit für die Hilfe. Das Timing ist nicht ganz so kritisch. Das größere Problem was ich habe, ist, dass der Interrupt nur einmalig ausgeführt wird obwohl ich ein RETI am ende des Interupthandlers habe und momentan auch keine weiteren Adressen im Interrupt anspringe.
Das kann sich durch diese Fragen auch nicht beantworten lassen.
Eventuell kann mir von euch jemand sagen was das faul im Programm ist. Das soll jetzt ein erster versuch werden ein LCD anzusteuern. Ich würde im Grunde nur ganz gerne eine Zahl hoch zählen und ausgeben. Leider wird der Interrupt nur einmalig ausgelöst. Mir ist bewusst, dass pause_lang kürzer ist als pause_weniger_lang, dass sollte bei diesem Problem aber nichts ändern.
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 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
Konrad M. schrieb: > Allerdings habe ich das Problem, > dass der Interrupt nur ein einziges mal ausgeführt wird und dann nichts > mehr. SP wurde richtig initialisiert? Besteht das Hauptprogramm wirklich nur aus einer Endlosschleife? Falls nicht, könnte es sein, dass die ISR Auswirkungen auf den Lauf des Hauptprogramms hat -- alle doppelt genutzten Register müssen gesichert werden. Vielleicht liegt der Fehler aber auch in Zeile 42...? ;-)
Vergleiche doch einfach mal deinen Code mit etwa: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr Was ist mit SREG beim Interruptaufruf?
Gast
#3750804
> interrupt: > inc zahl > reti du musst doch das Prozessor Register (SREG) sicher und wiederherstellen. inc verändert es.
Habe den Fehler beseitigen können. Ich fürchte da war wohl irgend eine Schwarze Magie am werk. Habe den Abschnitt Timer1 in folgendes umgeändert:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Also ich benutze nun den CTC Kanal A. Wieso das nun einen Unterschied macht weiß ich auch nicht. Kann mir das evtl. jemand erklären? Natürlich habe ich die Interruptadresse auch geändert.
Konrad M. schrieb: > Also ich benutze nun den CTC Kanal A. Wieso das nun einen Unterschied > macht weiß ich auch nicht. Kann mir das evtl. jemand erklären? Es gibt kein "CTC Kanal B". Wenn du den CTC-Modus wählst, und OCR1A auf 0 lässt (wie in deinem ersten Code), dann zählt der Timer nur 0-0-0-0-0-... und erreicht nie die 1000 um den OCR1B-Interrupt auszulösen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.