Sonntag, 10. August 2014

der Unterschied zwischen SFR und erweiterten SFR

In einem Programm bekam ich ständig Fehlermeldungen beim Compilieren.
Ein Test zeigte dann ein komisches Verhalten in der Timerprogrammierung.

So kann bei einem ATmega328P das Timerregister "TIMSK0" nicht per "OUT" sondern nur über "STS" beschrieben werden.


Beispielcode
/*
 * timertest2.asm
 */ 

.def temp = r16

.def leds = r17

.org 0x0000
        rjmp    main                  ; Reset Handler
.org OVF0addr
        rjmp    timer0_overflow       ; Timer Overflow Handler

main:
        ; Stackpointer initialisieren
        ldi     temp, HIGH(RAMEND)
        out     SPH, temp
        ldi     temp, LOW(RAMEND)     
        out     SPL, temp

        ldi     temp, 0xFF            ; Port D auf Ausgang
        out     DDRD, temp

        ldi     leds, 0xFF

        ldi     temp, (1<<CS00)|(1<<CS02)       ; CS00 und CS02 setzen: Teiler 1024
        out     TCCR0B, temp


        ldi     temp, (1<<TOIE0)      ; TOIE0: Interrupt bei Timer Overflow

        ; out     TIMSK0, temp        ; dieser Befehl bringt eine Fehler (Wert ausser Bereich)
sts TIMSK0, temp              ; STS weil TIMSK0 (0x6E) im erweiterten SFR liegt
        sei

loop:   rjmp    loop

timer0_overflow:                      ; Timer 0 Overflow Handler
        out     PORTD, leds
        com     leds
        reti


Grund des Problems:
Das Register TIMSK0 liegt in den erweiterten SFR (0x60 - 0xFF).
OUT funktioniert nur im normalen SFR (bis 0x5f), danach sind normale SRAM-Befehle nötig.