Forum: Mikrocontroller und Digitale Elektronik Assembler Led Lauflicht, "steht"


von Julius (Gast)


Lesenswert?

Hi,

habe mich an einem kleinen Lauflicht in Assembler versucht, leider wird 
nur die erste LED angeschaltet und das wars.
Das Programm funktioniert als ein 1Hz LED Blinker (Led1 und 2) wenn in 
timer1_overflow die Zeilen invertiert werden (normale Zeilen 
ausdokumentiert, ausdokumentierte als normaler Code).

Der Timer part läuft also schonmal, danach bewege ich mich allerdings 
auf Neuland.

Was passieren soll:
Led 3 aus,          - beim ersten Durchlauf ist Led 3 aus
Led 1 an,
sleep
Led 1 aus
Led 2 an,
sleep
Led 2 aus
Led 3 an


Hat jemand eine idee was bei den Verzweigungen schief läuft?



.def temp = r16
.def led1 = r17
.def led2 = r18
.def led3 = r19
.def lednumber = r20

.org 0x0000
        rjmp    main                  ; Reset Handler
.org OVF1addr
        rjmp    timer1_overflow       ; Timer Overflow Handler

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

    ;Port B auf Ausgang
    ldi     temp, 0xFF
    out     DDRB, temp

    ;Port C auf Ausgang
    ldi     temp, 0xFF
    out     DDRC, temp

    ;Nummer der Led
    ldi     lednumber, 1

    ; Vergleichswert für den Zähler ( ca 1Hz bei 12Mhz, Vorteiler 1024)
    ldi     temp, high( 23437 )
    out     OCR1AH, temp
    ldi     temp, low( 23437 )
    out     OCR1AL, temp
    ; CTC Modus einschalten, Vorteiler auf 1024
    ldi     temp, ( 1 << WGM12 ) | ( 1 << CS10 ) | ( 1 << CS12)
    out     TCCR1B, temp
    ; OCIE1A: Interrupt bei Timer Compare
    ldi     temp, 1 << OCIE1A
    out     TIMSK, temp
    sei

loop:
    rjmp    loop


; Timer 1 overflow handler
; Mehrfachverzweigung, welche Led soll umgeschaltet werden
timer1_overflow:
    ;out     PORTB, r21
    ;com     r21
    ;reti
    cpi     lednumber, 1
    breq    led1on
    cpi     lednumber, 2
    breq    led2on
    cpi     lednumber, 3
    breq    led3on
    reti

led1on:
    cbi     PORTC, 0
    sbi     PORTB, 1
    inc     lednumber
    rjmp    loop

led2on:
    cbi     PORTB, 1
    sbi     PORTB, 2
    inc     lednumber
    rjmp    loop

led3on:
    cbi     PORTB, 2
    sbi     PORTC, 0
    ldi     lednumber, 1
    rjmp    loop

von Matthias B. (matthias882)


Lesenswert?

Du musst aus deinem Interrupt immer mit "reti" rausspringen. Solang du 
das nicht machst, sind alle Interrupts deaktiviert (I-Bit im SREG nicht 
gesetzt). In deinem Code springst du aber in jedem "ledXon" nach loop. 
du beendest den Interrupt also nicht. Ersetzt diese Sprünge durch 
"reti".

Blätter außerdem nochmal im Datenblatt. Du willst den Timer auf einen 
Wert vergleichen, springst aber über den Overflow in deinen interrupt. 
Das sind 2 verschiedene Dinge...

von Julius (Gast)


Lesenswert?

Ah, danke.
Mit "reti" anstatt "rjmp loop" funktioniert es.

Im Datenblatt steht im Abschnitt Timer1:

OCIE1A Timer/Counter1, Output Compare A Match Interrupt Enable

Was auch in diesen Tutorial für CTC verwendet wird:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr



Läuft der Timer1 auf Interrupt bei overflow müsste sich eine Frequenz 
von
(clk/prescalar)/(timer1 max value) ergeben, also:
(12000000/1024)/(65536)=0.1788Hz
Quelle:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer


Verändert man aber die Compare Werte sieht man schnell an den Leds das 
sich die Frequenz geändert hat.

Beispiel:
Target Timer Count = (1 / Target Frequency) / (Prescale / Input 
Frequency)

4Hz
(1/4)(1024/12000000)=2929.6

16Hz
=732

Quelle:
http://2313.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=50106&start=60

Hoffentlich liege ich jetzt nicht total daneben.

Mfg
Julius

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.