Hi! Ich muss in meiner TimerISR ein komisches Verhalten feststellen.
Vorab der Code:
1
volatileintTimer1;
2
inti=0;
1
ISR(TIMER1_COMPA_vect){
2
3
Timer1++;
4
if(Timer1==20){
5
Timer1=0;
6
for(i=0;i<20;i++){
7
printf("%d\n",i);
8
}
9
}
10
}
Es wird überhaupt nichts getan. Im Simulator kann ich sehen wie die
Variablen Timer1 und i 'not in scope' sind, dann auf 0, später auf 1 und
dann weder auf 'not in scope' wechseln.
Lasse ich eine LED beim ISR-Aufruf toggeln, dann ändert sich auch der
Zustand. Versuche ich dies im if-Block tut sie es jedoch nicht.
Breakpoints lassen sich erst gar nicht setzen.
Das Problem ist bei jedem optimierungslevel in den Projekteinstellngen.
Hat jemand Ideen wie ich vorgehen kann um das Problem zu lokalisieren?
Christian Q. schrieb:> Variablen Timer1 und i 'not in scope' sind, dann auf 0, später auf 1 und> dann weder auf 'not in scope' wechseln.
Soweit doch richtig. du musst warten bis Timer1 auf 20 steht, erst dann
läuft er in dein if...
Abgesehen davon: printf in der ISR ist 'bäh'. Zum Debuggen aber
verzeihbar...
A. K. schrieb:> "i" global ist ungut. Gehört in die ISR.
eher so?:
1
ISR(TIMER1_COMPA_vect){
2
inti;
3
Timer1++;
4
if(Timer1==20){
5
PORTD^=(1<<PD6);
6
Timer1=0;
7
for(i=0;i<20;i++){
8
printf("%d\n",i);
9
}
10
}
11
}
Das Problem ist dann aber doch, dass i immer wieder neu initialisiert
wird, oder nicht?
Er erreicht aber den if-Block nie. mysteriös.. aber Computer haben
immer Recht.
Εrnst B✶ schrieb:> Abgesehen davon: printf in der ISR ist 'bäh'. Zum Debuggen aber> verzeihbar...
Aber nicht in einer Timer-ISR: es könnte gut sein, dass der
nächste Interrupt schon da ist, während die ISR noch dabei ist,
die vorherigen 20 printfs abzuarbeiten (UART bei 9600 Bd: 1 ms
pro Zeichen).
Kann das sein, das die 'while()'-Schleife wegoptimiert wird? Das könnte
erklären, dass der Interrupt vorher mal angesprungen wird (während der
ganzen Initialisierungen). Und dann ist 'main()' zu Ende...
Jörg Wunsch schrieb:> es könnte gut sein, dass der> nächste Interrupt schon da ist, während die ISR noch dabei ist,> die vorherigen 20 printfs abzuarbeiten (UART bei 9600 Bd: 1 ms> pro Zeichen).
Dann würde aber bestimmt mindestens 1 Zeichen ausgegeben oder PD6
toggled.
Achso: Frequenz ist 1 Mhz.
Christian Q. schrieb:> Jörg Wunsch schrieb:>> es könnte gut sein, dass der>> nächste Interrupt schon da ist, während die ISR noch dabei ist,>> die vorherigen 20 printfs abzuarbeiten (UART bei 9600 Bd: 1 ms>> pro Zeichen).>> Dann würde aber bestimmt mindestens 1 Zeichen ausgegeben oder PD6> toggled.
Fängt man aber gar nicht erst an, Das ist dann nämlich die nächste
Baustelle!
Schmeiß doch das printf() aus der ISR raus. Wenn du dort einen
Pin wackeln lässt, dann denk dran, dass der ziemlich schnell wackelt.
Falls du da nur eine LED an PORTD0 dran hast, wirst du das Wackeln
nicht sehen ;-), sondern du brauchst ein Oszilloskop dafür.
Du musst schon sehr gut sein, wenn du das aufglimmen einer LEd in der
Dauer von ca 1µs sehen willst. Auf meinem 4Mhz Mega16 kann ich das
gerade noch erahnen. Aber auch nur weil ich weiß, an welcher LED sich
was tun müsste. OHne dieses wissen, würde ich das niemals sehen.
Bei
for (uint8_t i = 0; i < 20; i++)
hingegen, ist das regelmässige Aufblitzen schon deutlich zu sehen.
Es muss ein Fehler beim ADC sein. Wenn ich das init auskommentiere
funktioniert alles wie gewohnt. Naja okay in AVR Studio lassen sich
immernoch keine Breakpoints setzen und es springt in den Disassembler
aber auf der Hardware funktioniert alles wie erwartet.
Hab ich den ADC falsch eingebunden?
Christian Q. schrieb:> Hab ich den ADC falsch eingebunden?
Hast du:
Karl Heinz Buchegger schrieb:> Man gibt keinen Interrupt frei, für den man keine ISR hat.> Niemals!
wirklich beachtet, oder ohne Test einfach:
Christian Q. schrieb:> Leider ändert es überhaupt nichts am Verhalten.
behauptet?
Schaltest du sonst noch andere Interrupts ein, für die du keine ISR
hast?
ggfs einen bad_isr handler installieren, der dir das debuggt.
Ich hatte es getestet. Auf deinen Hinweis jetzt sogar erneut. Und siehe
da jetzt geht es. Entweder ich habe bei meinem Test den Interrupt aus
Versehen angelassen oder ein anderes Ergebnis erwartet. Vielen Dank für
deinen unermüdlich durchgesetzten Lösungsvorschlag :D
Warum sich AVR-Studio trotzdem so komisch verhält verstehe ich nicht.