Hallo,
ich versuche das Programmbeispiel AVR-Tutorial: Timer auf meinem
ATMega644 zum Laufen zu bekommen. Offenbar muss ich die Bezeichnungen
für die Timer ändern, da der 644 3 davon hat, TIMSK0-2. Ebenso muss wohl
auf TTCR0B zugegriffen werden, da TTCR0A andere Aufgaben hat und kein
CS00 Flag hat.
Geändert habe ich also TCCR0 in TCCR1 und TIMSK in TIMSK0.
Build gibt mir aus, dass ihm der Operand (1<<TOIE0) nicht in TIMSK0
passt.
Laut Datasheet besitzt dieses Register aber diesen Flag.
Fehlermeldung ist: Operand 1 out of Range.
Die Fehlerzeile:
1
ldi temp, (1<<TOIE0) ; TOIE0: Interrupt bei Timer Overflow
2
-> out TIMSK0, temp
Hier die Beschreibung vom fraglichen Flag von TIMSK0:
Bit 0 - TOIE0: Timer/Counter0 Overflow Interrupt Enable
When the TOIE0 bit is written to one, and the I-bit in the Status
Register is set, the Timer/Counter0 Overflow interrupt is enabled. The
corresponding interrupt is executed if an overflow in Timer/Counter0
occurs, i.e., when the TOV0 bit is set in the Timer/Counter 0 Inter-
rupt Flag Register - TIFR0.
Muss ich das I-Bit manuell setzen? Ich denke, dass wird von SEI
erledigt.
Ich hoffe, ich hab das Problem richtig rübergebracht, Vielen Dank im
voraus für Lösungsansätze.
Offensichtliches Problem: Die Endlosschleife am Ende von main fehlt!
1
sei ; Ende deines Codes
2
3
endlos: ; neuer Code
4
RJMP endlos ; neuer Code
Die zum Timer0-Overflow-Interrupt gehörende Interrupt Service Routine
(ISR) gibt es auch? Und die ist an der richtigen Vektorposition
eingetragen (.org xxx)?
Der Kommentar ist vom Original kopiert. :-)
DDRC ist für mich schon korrekt, da dort die LED sitzt.
Zum Vektor: Ich bin nicht sicher, ich fuchtel zum ersten Mal mit
Interrupts rum. :-)
Im Datasheet kann ich nichts zu OVF0addr finden, in der m644def steht es
aber drin:
.equ OVF0addr = 0x0024 ; Timer/Counter0 Overflow
Zur Schleife: Im Original ist die nächste Zeile
1
loop: rjmp loop
Hätte wohl den kompletten Code einfügen sollen, bin noch nicht erfahren,
wie ihr das am Liebsten habt. :-)
Also hier einmal komplett, ist ja nicht so gross:
Hi
>timer0_overflow: ; Timer 0 Overflow Handler> out PORTC, leds> com leds> reti
Spielt in dem Programm noch keine Rolle, aber du solltest dir angewöhnen
in der Interruptroutine SREG und die die verwendeten Register zu
sichern.
timer0_overflow: ; Timer 0 Overflow Handler
push temp
in temp,SREG
push temp
out PORTC, leds
com leds
pop temp
out SREG,temp
pop temp
reti
MfG Spess
Funktioniert, wenn du
out TIMSK0, temp
in
STS TIMSK0, temp
änderst. TIMSK0 ist beim Atmega644 memory-mapped und du kommst da mit
OUT nichtdran (Build Meldung im Assembler2 beachten).
Deine ISR wird alle 255 µs aufgerufen, wenn der Atmega644 mit 1 MHz
läuft (Stopwatch im Simulator).
Danke an euch Beiden, läuft nun.
Der Prescaler war in dem Tutorial absichtlich erstmal ungeteilt für die
Simulation. Die Fehlermeldung "error: Operand 1 out of range: 0x6e" hat
mir nicht gerade weitergeholfen.
Wo hätte ich denn nachlesen können, das dieses Flag nicht per OUT
gesetzt werden kann?
Hi
>Wo hätte ich denn nachlesen können, das dieses Flag nicht per OUT>gesetzt werden kann?
Im Datenblatt ist relativ weit hinten eine Tabelle mit den IO-Registern
('Register Summary'. Die Register bis zu den Adressen 0x3F (0x5F) lassen
sich per in/out ansprechen.
MfG Spess