Hi,
ich habe die vergangenen Stunden damit verbracht, im Internet und diesem
Forum nach einer Lösung für dieses Problem zu suchen:
Ich habe ein myAVR-Board v1.52 mit einem ATMega8. An Port D hängt eine
LED. Folgendes Programm sollte eigentlich alle 710ms die LED an bzw
ausschalten. Es tut sich aber nichts, die LED brennt dauernd. Woran kann
das liegen?
Hi, Lorenz,
Im Programmkode erkenne ich keinen Fehler.
Anamnese:
1. Läuft der Oszillator?
2. Verhält sich ein anderer Chip genauso?
3. Stromlauf ohne Fehler?
Ciao
Wolfgang Horn
TIFR|=(1<<TOV0);// Overflow-Bit löschen -> Auf logisch 1 Stellen
17
}
18
}
19
}
Sobald ich aber sei() nicht mehr auskommentiert habe, bleibt die LED an.
Verhängt sich mein ATMega8 auf der Suche nach einer Interruptfunktion?
Ich habe nur diesen eine Controller, evtl tut mir jemand, der auch im
Besitz eines ATMega8 ist, den Gefallen, das mal auszuprobieren?
Was du mit Stromfluss meinst, kann ich nicht nachvollziehen. Aber ein
allzu schwerer Fehler kann nicht vorliegen, denn alle meine Programme,
die keine Interrupts verwenden, laufen anstandslos. Oder?
Danke für die Mühe,
Lorenz
Lorenz Hopfmüller wrote:
> Sobald ich aber sei() nicht mehr auskommentiert habe, bleibt die LED an.> Verhängt sich mein ATMega8 auf der Suche nach einer Interruptfunktion?
Richtige Vermutung. Die ISR für den Timer0 Overflow fehlt.
Hi,
dein Code bringt leider auch nichts, die LED bleibt in beiden Fällen an.
Ich habe aber heute Morgen nochmal das Datenblatt gewälzt, und bin dabei
auf folgendes gestoßen:
Mit meinen Fuse-Bits, die noch auf Werkseinstellung sind, ergibt sich
laut dem Datenblatt
http://atmel.com/dyn/resources/prod_documents/doc2486.pdf , Tabelle 19,
für die Interrupt-Vektor-Startadresse 0x001. Ich habe folgendes
Minimalbeispiel mit "avr-gcc -mmcu=atmega8 miniinterrupt.c" kompiliert
und den Disassembler avrdisas
(http://www.johannes-bauer.com/avruc/index.php) drüberlaufen lassen. Der
Output ist angehängt, der Code kommt hier:
1
#include<avr/interrupt.h>
2
intmain(){}
3
ISR(INT0_vect){}
4
ISR(INT1_vect){}
Die Interrupt-Vektoren, zu erkennen an der langen Reihe von rjmps, von
denen der 2. und der 3., also INT0 und INT1 (-> Datenblatt S.47) auf
"eigene" Funktionen zeigen, sind nicht etwa an 0x01, sondern an 0x54!
Kein Wunder, dass der ATMega8 beim Sprung dahin, wo er die Vektoren
vermutet, in einen undefinierten Zustand übergeht.
Ich habe das natürlich auch mit "vernünftigen" Code ausprobiert, mit dem
Beispiel aus meinem ersten Posting sind die Vektoren an 0x74.
Entweder habe also ich etwas mit den Interrupt-Vektoren-Adressen
gründlich missverstanden, oder mein avr-gcc schert sich keinen Deut
darum, dass diese Vektoren an einer bestimmten Adresse stehen müssen,
und nicht einfach irgendwo im Speicher. Wie kann ich dem gcc in dieser
Hinsicht Manieren beibringen? Ist vielleicht meine avr-libc-Version eine
verkorkste?
Ich wäre dir, Stefan, sehr dankbar, wenn du das mal auf deinem ATMega8
testen könntest. Toll wäre es auch, wenn du die Binary hier mal posten
könntest, dann kann ich das mal mit einer anderen gcc-Version testen.
Danke für die Mühe,
Lorenz
Lorenz Hopfmüller wrote:
> Ich wäre dir, Stefan, sehr dankbar, wenn du das mal auf deinem ATMega8> testen könntest. Toll wäre es auch, wenn du die Binary hier mal posten> könntest, dann kann ich das mal mit einer anderen gcc-Version testen.
Binary zu diesem Quellcode im Anhang:
(AVR-Studio 4.12 SP2, WinAVR 20071221)
Ich habe nur eine LED an PD5 auf dem [[Pollin
Funk-AVR-Evaluationsboard]] zur Anzeige benutzt.
1
// MCU = atmega8
2
// F_CPU 1000000 in AVR Studio oder Makefile eingestellt
Die LED blinkt fröhlich vor sich hin. Etwas hektisch, da das Board 12
MHz hat. Ändere ich den Vergleich im if auf >= 10*12, ist es ein
schönes, langsames Blinken Pi*Daumen im 1s/1s Takt.
@ Lorenz Hopfmüller:
Das a.out ist kein reines BIN-File (das müsste man daraus erst noch
extrahieren). Sieht so aus, also würde dein Disassembler damit nicht
klar kommen. Er versucht wohl, die Zusatzinhalte in der Datei ebenfalls
zu disassemblieren.
Hi,
@Stefan B.: Blinkt auch bei mir, danke!
@Stefan Ernst: Uups, das hatte ich nicht gewusst. Ich hatte bisher immer
die a.out auf den ATMega8 gebrannt, kein Wunder, dass das nicht ging.
Ein wenig peinlich...
Ich kompiliere jetzt mit
Danke für die Fehlersuche, das Problem befand sich etwa 40cm vom
Bildschirm entfernt. Was mich noch wundert: Wieso funktionierten alle
Programme, die keine Interrupts benutzen?
Danke,
Lorenz
Lorenz Hopfmüller wrote:
> Was mich noch wundert: Wieso funktionierten alle> Programme, die keine Interrupts benutzen?
Zufall. Der Prozessor "wurschtelt" sich anscheinend irgendwie durch den
Müll am Anfang (was macht ein AVR eigentlich bei einem ungültigen
Opcode?). Der eigentliche Code enthält nur relative Sprünge, so dass es
unproblematisch weitergeht, wenn er diesen erstmal erreicht hat.
Initialisierte globale Variablen gibt es auch nicht (die würden nämlich
mit falschen Werten initialisiert werden). Stört also eigentlich "nur",
dass die Interruptvektortabelle nicht an der richtigen Stelle sitzt. ;-)