Forum: Mikrocontroller und Digitale Elektronik Timer-Tutorial ATMega644


von slimb0y (Gast)


Lesenswert?

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.

von slimb0y (Gast)


Lesenswert?

Korrektur: statt TCCR0 habe ich TCCR0B benutzt (Prescaler), im 
Originalcode TCCR0.

Hier noch einmal main: komplett.
1
main:
2
        ldi     temp, LOW(RAMEND)     ; Stackpointer initialisieren
3
        out     SPL, temp
4
        ldi     temp, HIGH(RAMEND)
5
        out     SPH, temp
6
  
7
        ldi     temp, 0xFF            ; Port B auf Ausgang
8
        out     DDRC, temp
9
 
10
        ldi     leds, 0xFF
11
     
12
        ldi     temp, (1<<CS00)       ; CS00 setzen: Teiler 1
13
        out     TCCR0B, temp
14
 
15
        ldi     temp, (1<<TOIE0)      ; TOIE0: Interrupt bei Timer Overflow
16
        out     TIMSK0, temp
17
 
18
        sei

von Stefan B. (Gast)


Lesenswert?

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)?

von Stefan B. (Gast)


Lesenswert?

>        ldi     temp, 0xFF            ; Port B auf Ausgang
>        out     DDRC, temp

Gehört fast schon ins Kapitel "Superkommentare" ;-)

von slimb0y (Gast)


Lesenswert?

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:
1
.include "m644def.inc"
2
3
.def temp = r16
4
.def leds = r17
5
 
6
.org 0x0000
7
        rjmp    main                  ; Reset Handler
8
.org OVF0addr
9
        rjmp    timer0_overflow       ; Timer Overflow Handler
10
 
11
main:
12
        ldi     temp, LOW(RAMEND)     ; Stackpointer initialisieren
13
        out     SPL, temp
14
        ldi     temp, HIGH(RAMEND)
15
        out     SPH, temp
16
  
17
        ldi     temp, 0xFF            ; Port B auf Ausgang
18
        out     DDRC, temp
19
 
20
        ldi     leds, 0xFF
21
     
22
        ldi     temp, (1<<CS00)       ; CS00 setzen: Teiler 1
23
        out     TCCR0B, temp
24
 
25
        ldi     temp, (1<<TOIE0)      ; TOIE0: Interrupt bei Timer Overflow
26
        out     TIMSK0, temp
27
 
28
        sei
29
 
30
loop:   rjmp    loop
31
 
32
timer0_overflow:                      ; Timer 0 Overflow Handler
33
        out     PORTC, leds
34
        com     leds
35
        reti

von spess53 (Gast)


Lesenswert?

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

von Stefan B. (Gast)


Lesenswert?

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).

von Stefan B. (Gast)


Lesenswert?

255 µs LED schalten ist fürs Auge viel zu schnell. Ich würde den 
Prescaler 1024 benutzen. 261 ms LED Blinken ist sichtbar.

von slimb0y (Gast)


Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.