Hallo,
meine AVR Atmega88PA Interrupts werden nich ausgeführt, sondern es wird
ein "soft"-Reset ausgelöst.
Danach sind alle Bits im MCUSR 0.
Erwartet: LED geht an und bleibt an.
Was passiert: LED geht kurz an bis Timer bei "20"<<8 und danach blinkt
danach langsam. Im Takt des Timers (Overflow)
Immer wenn ein Interupt ausgeführt werden sollte springt es zum Anfang.
Die Interruptroutine wird nicht ausgeführt.
Wo könnte das Problem liegen?
Habe den Code für atmega88 und atmega88p compiliert. Immer das gleiche,
auch auf anderer Hardware.
Bad Interrupt Routine wird auch nicht ausgeführt. Bei anderen Interupts
passiert auch das gleiche.
Eclipse CDT mit AVR Plugin
avr-libc avrdude avr-gcc
gcc version 4.3.3 (GCC)
Ubuntu 9.10
Hier der Code:
Ich kenne die Eclipse-Umgebung nicht. Kann es sein, dass Du dort den
falschen MCU-Typ eingestellt hast, so dass der falsche Interrupt-Vektor
gesetzt wird oder dein ISR gar nicht als Interrupt-Routine erkannt wird?
Steht im Code auf Byte-Adresse 0x2c (Wort: 0x16) ein Sprung zu Deiner
Interrupt-Routine? (Ggfs. die ersten 3 Zeilen der .hex mitliefern.)
Oder steht da derselbe Sprung wie direkt davor und danach?
Hazeh danke für die Antwort.
Haben das Problem gefunden. Lag bei den Standardeinstellungen vom
AVR-Plugin für Eclipse.
Da beim Compilieren keine .hex Datei, sondern nur ein .elf Datei
erstellt wurde, hatten wir den MC mit der .elf programmiert. Lief alles
wunderbar abgesehen von den Interrupts.
Im Assembler Code war natürlich alles richtig...
Nach 25 Std. Suche...
Häkchen bei "Generate Hexfile for Flash memory" in Project -> Properties
-> Build -> Settings -> Tool Settings -> Additional Tools in Toolchain
setzten und es funktioniert. :)
Schönen Abend noch!
Hallo,
ich habe so ziemlich das gleiche Problem. Ein Interrupt fuehrt immer
dazu, dass der Code von neuem ausgefuehrt wird.
Ich benutze avr-gcc 4.1.2 und schreibe die .hex Datei mit avrdude ins
Flash. Als MC kommt im Moment ein atmega8 zum Einsatz. Zur
Vollstaendigkeit, das Programm sieht folgendermassen aus:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
volatileuint8_tflag;
5
6
ISR(TIMER2_OVF_vect){
7
flag=1;
8
}
9
10
intmain(void){
11
12
DDRD=0xFF;
13
14
// Timer2 konfigurieren
15
TCCR2=(1<<CS22)|(1<<CS21);
16
TIMSK|=(1<<TOIE2);
17
18
sei();
19
20
while(1){
21
if(flag==1){
22
flag=0;
23
PORTD^=(1<<PD0);// LED toggeln
24
}
25
}
26
}
Nun wollte ich, wie <HC Zimmerer> vorschlug, im .hex file nachschauen,
ob an der richtigen Stelle auch die Sprungadresse zu meiner ISR Funktion
steht.
Die Sprungadresse fuer den Interrupt TIMER2_OVF muss an 0x004 im
Programm Code stehen - dem Handbuch entnommen. Nun bin ich mir nicht
sicher, wie ich das hex-file in kate lesen soll:
1
:1000000012C02CC02BC02AC029C028C027C026C0BF
2
:1000100025C024C023C022C021C020C01FC01EC0D4
3
:100020001DC01CC01BC011241FBECFE5D4E0DEBF25
Ich suche also das 5.Bit in der ersten Zeile was sagt "2B" also 43. Dann
sollte meine Interrupt Funktion bei Bit 43 beginnen. Allerdings macht
mich stutzig, dass die ersten 3 Zeilen bei allen meinen hex Files von
verschiedenen Programmen immer gleich aussehen. Was mache ich falsch?
Danke schon mal fuer die Hilfe.
>Nun bin ich mir nicht>sicher, wie ich das hex-file in kate lesen soll:
Dann schau doch in der .lss-datei nach. Da steht die Sprungtabelle im
Klartext.
Bleibt die Frage, woran du erkennst, daß das Programm immer wieder von
vorne losläuft.
Oliver
Das Programm wie oben abgedruckt bringt die LED nicht zum leuchten.
Toggle ich aber den Ausgang mit der LED vor dem sei() und fuege auch
noch ein delay vor dem sei() ein, dann blinkt die LED.
Daraus habe ich geschlossen, dass der Aufruf sei() den Interrupt
TIMER2_OVF aktiviert und ausfuehren will, aber an die falsche Stelle
springt naemlich an den Anfang vom Programm. Dadurch wird die LED wieder
ausgeschaltet und alles geht wieder von vorne los. Vielleicht habe ich
hier auch etwas uebersehen.
Leider weiss ich nicht, wonach ich in der main.lss suchen soll, daher
einfach die ganze Datei:
// hier wird der Hauptschleife ein neuer Timerinterrupt signalisiert
101
ISR(TIMER2_OVF_vect){
102
5e:1f92pushr1
103
60:0f92pushr0
104
62:0fb6inr0,0x3f;63
105
64:0f92pushr0
106
66:1124eorr1,r1
107
68:8f93pushr24
108
flag=1;
109
6a:81e0ldir24,0x01;1
110
6c:80936000sts0x0060,r24
111
70:8f91popr24
112
72:0f90popr0
113
74:0fbeout0x3f,r0;63
114
76:0f90popr0
115
78:1f90popr1
116
7a:1895reti
117
118
0000007c<main>:
119
}
120
121
intmain(void){
122
123
// IO konfigurieren
124
DDRD=0xFF;
125
7c:8fefldir24,0xFF;255
126
7e:81bbout0x11,r24;17
127
128
// Timer2 konfigurieren
129
TCCR2=(1<<CS22)|(1<<CS21);
130
80:86e0ldir24,0x06;6
131
82:85bdout0x25,r24;37
132
TIMSK=(1<<TOIE2);
133
84:80e4ldir24,0x40;64
134
86:89bfout0x39,r24;57
135
136
// Interrupts freigeben
137
sei();
138
88:7894sei
139
140
// Endlose Hauptschleife
141
while(1){
142
if(flag==1){// Neuer Timerzyklus ?
143
8a:90916000ldsr25,0x0060
144
8e:9130cpir25,0x01;1
145
90:e1f7brne.-8;0x8a<main+0xe>
146
flag=0;
147
92:10926000sts0x0060,r1
148
149
PORTD^=(1<<PD0);// LED toggeln
150
96:82b3inr24,0x12;18
151
98:8927eorr24,r25
152
9a:82bbout0x12,r24;18
153
9c:f6cfrjmp.-20;0x8a<main+0xe>
154
155
0000009e<_exit>:
156
9e:ffcfrjmp.-2;0x9e<_exit>
Ich sehe, dass an den Speicheradressen 5e-7b wohl der Code fuer meinen
ISR steht, sehe allerdings nicht, wo der Sprung dahin definiert wird.
Danke fuer die Hilfe.
Prüfe mal bitte ob TIMER2_OVF_vect in den .h auch wirklich definiert
ist. Hatte hier auch schon das Problem, daß der GCC zwar die ISR
einbaut, aber nicht in der IRQ Vector Tabelle eingebunden hat.
Grund war ein Falsch geschriebener ISR Name....
Eine Fehlermeldung gab es komischerweise nicht.
Tim schrieb:
> Prüfe mal bitte ob TIMER2_OVF_vect in den .h auch wirklich definiert> ist. Hatte hier auch schon das Problem, daß der GCC zwar die ISR> einbaut, aber nicht in der IRQ Vector Tabelle eingebunden hat.> Grund war ein Falsch geschriebener ISR Name....
Unnötig. Die Funktion ist ja als Interrupt-Funktion übersetzt worden
(und auch mit der richtigen Vektor-Nummer), also kann es das nicht sein.
@ Matthias:
Ich kann im Build-Output nichts entdecken. Ich würde es mal mit einer
etwas aktuelleren Toolchain probieren.
Stefan Ernst schrieb:
> Unnötig. Die Funktion ist ja als Interrupt-Funktion übersetzt worden> (und auch mit der richtigen Vektor-Nummer), also kann es das nicht sein.
Wo siehst Du hier "die richtige Vektor-Nummer"?
Grrrr schrieb:
> Stefan Ernst schrieb:>> Unnötig. Die Funktion ist ja als Interrupt-Funktion übersetzt worden>> (und auch mit der richtigen Vektor-Nummer), also kann es das nicht sein.>> Wo siehst Du hier "die richtige Vektor-Nummer"?
@Stefan Ernst:
Wie gesagt, gleiches Problem hatte ich hier auch schon.
Ursache war der Umstieg auf einen grösseren AVR (16 auf 64 oder so).
Und damit war ich wohl zu spät :-)
Vielleicht solltest du auch noch -mmcu= an deine Hardware anpassen.
Hc Zimmerer schrieb:
>> avr-gcc -mmcu=atmega8 [...]>> In der Überschrift steht aber ATmega88 (nicht ATmega8).
Was daran liegt, dass der Frager einen alten Thread gekapert hat.
Hc Zimmerer schrieb:
>> avr-gcc -mmcu=atmega8 [...]>> In der Überschrift steht aber ATmega88 (nicht ATmega8).
Ja, das verwirrt ungemein.
Deshalb @Matthias (Gast)
Schreib 100-mal an die Tafel:
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
"Ich soll nicht fremde Threads hijacken!"
Peter
Hallo,
ja, ich habe einen alten thread missbraucht. Meiner Ansicht nach leide
ich an einem sehr aehnlichen Problem, wie der anfaengliche Poster. Aber
das war wohl eine schlechte Idee.
Zurueck zu meinem Problem. In der iom8.h steht:
1
...
2
/* Timer/Counter2 Overflow */
3
#define TIMER2_OVF_vect _VECTOR(4)
4
#define SIG_OVERFLOW2 _VECTOR(4)
5
...
Ich hoffe, dass beantwortet die Frage von Tim.
Die toolchain umfasst wohl den avr-gcc compiler und avrdude? Ich habe da
einfach ein Paket meiner Distribution installiert und mir dazu keine
Gedanken gemacht. Es gibt bei openSUSE ein Packet cross-avr-gcc und ein
Paket cross-avr-gcc44 welche jeweils die Compiler und Support Files
beinhalten. Vielleicht haette ich da die Version cross-avr-gcc44 nehmen
sollen?
Es scheint mir aber so, als ob meine Interpretation der Dinge richtig
liegt und meine ISR Prozedur nicht angesprungen wird. Es ist also ein
Problem bei der Compilierung, oder?
Matthias schrieb:
> Es scheint mir aber so, als ob meine Interpretation der Dinge richtig> liegt und meine ISR Prozedur nicht angesprungen wird. Es ist also ein> Problem bei der Compilierung, oder?
Genauer gesagt ein Problem beim Linken, der Vektor wird nicht
eingetragen. Die fertigen avr-gcc-Pakete der Distributionen sind
ziemlich bekannt dafür, häufiger mal buggy zu sein.
Schau mal bei AVR-Freaks vorbei. Dort gibt es ein Skript, mit dem man
sich avr-gcc ziemlich einfach selbst übersetzen kann. Seit Kurzem gibt
es dort auch fertige Deb-Pakete, es gibt dazu einen Thread mit der
Adresse.
"bad interrupt" setzt man am besten auf eine Routine, welche eine LED
einschaltet und dann in einer Endlosschleife hängen bleibt - falls man
noch einen Pin frei hat. Geht alles gut, sollte die LED niemals
leuchten. Wenn doch, trat ein nicht abgefangener Interrupt auf.
Stefan Ernst schrieb:
> Der build output sieht so aus:>>> -------- begin -------->> avr-gcc (GCC) 4.1.2 20070115 (prerelease) (SUSE Linux)> Copyright (C) 2006 Free Software Foundation, Inc.
Also, dein Programm ist in Ordnung, der Vektor wird aber nicht in die
Sprungtabelle eingetragen.
Wie schon gesagt wurde, besorge dir erst einmal eine aktuelle und
nachgewiesenermassen funktionsfähige avr-gcc-Version. 3 Jahre alte
"prereleases" sind da eher nicht vertrauenswürdig.
Oliver
Stefan Ernst schrieb:
> Oliver schrieb:>> Stefan Ernst schrieb:>>> Der build output sieht so aus:>> Hä???
Hmpf.
Da habe ich den Zitat-Link des falschen Beitrags erwischt. Sollte
natürlich so lauten:
Matthias schrieb:
> Der build output sieht so aus:
Ist aber schon lustig, daß man über den Zitate-Link aus anderen
Beiträgen die Autoren beliebig zuordnen kann.
Oliver
Peter Dannegger schrieb:
>> In der Überschrift steht aber ATmega88 (nicht ATmega8).>> Ja, das verwirrt ungemein.
Was spricht dagegen, das Subjekt zu ändern?
Iwan