mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit RGB-LED-Fader Atmega8


Autor: Michael Mayer (eos400dman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe erste vor ein paar Woche mit Assembler und AVRs angefangen.
Gerade versuche ich mit PWM einen RGB-Fader zu programmieren, geht auch 
schon recht gut.
Allerdings springt er nicht erst aus den Routinen wenn ocr_X = 00 ist 
sonder schon bei recht zufälligen Werten bei rot zbsp: schon bei 242.
Wahrscheinlich habe ich einen ganz einfachen Denkfehler aber ich hoffe 
ihr könnt mir trotzdem helfen.
.include "m8def.inc"
 
.def temp  = r16
.def PWMCount = r17
.def ocr_1 = r18                      ; Helligkeitswert Led1: 0 .. 127
.def ocr_2 = r19                      ; Helligkeitswert Led2: 0 .. 127
.def ocr_3 = r20                      ; Helligkeitswert Led3: 0 .. 127
.def counter = r23

.org 0x0000
        rjmp    main                    ; Reset Handler
.org OVF0addr
        rjmp    timer0_overflow         ; Timer Overflow Handler
     
main:
        ldi   counter, $01
        ldi     temp, LOW(RAMEND)       ; Stackpointer initialisieren
        out     SPL, temp
        ldi     temp, HIGH(RAMEND)
        out     SPH, temp
  
        ldi     temp, 0xFF              ; Port C auf Ausgang
        out     DDRC, temp
 
        ldi     ocr_1, $ff          ; Blau  
        ldi     ocr_2, $ff        ; Grün
        ldi     ocr_3, $ff        ; Rot
 
        ldi     temp, 1<<CS00           ; CS00 setzen: Teiler 1
        out     TCCR0, temp
 
        ldi     temp, 1<<TOIE0          ; TOIE0: Interrupt bei Timer Overflow
        out     TIMSK, temp
 
        sei

loop:  
    rol counter

    sbrs counter, 0
    rcall rot_an
    sbrs counter, 1
    rcall gruen_an
    sbrs counter, 2
    rcall blau_an

    sbrs counter, 3
    rcall rot_aus
    sbrs counter, 4
    rcall gruen_aus
    sbrs counter, 5
    rcall blau_aus

    rjmp loop
 
;*****************
blau_an:   
    cpi ocr_1, $00
    breq loop
    dec ocr_1
    rcall pause
    cpi ocr_1, $00
    brne blau_an
    ret

;****************
blau_aus:  
    cpi ocr_1, $fe
    breq loop
    cpi ocr_2, $00
    breq blau_aus_2
    cpi ocr_3, $00
    breq blau_aus_2
    rjmp loop

blau_aus_2:
    inc ocr_1
    rcall pause
    cpi ocr_1, $fe
    brne blau_aus_2
    ldi counter, $01
    ret

;******************
Gruen_an:   
    cpi ocr_2, $00
    breq loop
    dec ocr_2
    rcall pause
    cpi ocr_2, $00
    brne Gruen_an
    ret
;***************
gruen_aus:  
    cpi ocr_2, $fe
    breq loop
    cpi ocr_1, $00
    breq gruen_aus_2
    cpi ocr_3, $00
    breq gruen_aus_2
    rjmp loop

Gruen_aus_2:
    inc ocr_2
    rcall pause
    cpi ocr_2, $ff
    brne Gruen_aus_2
    ret
;*************
Rot_an:   
    cpi ocr_3, $00
    breq loop
    dec ocr_3
    rcall pause
    cpi ocr_3, $00   <--Hier springt er schon bei 242 nicht mehr zu rot_an 
    brne Rot_an
    ret
;**********
rot_aus:  
    cpi ocr_3, $fe
    breq loop
    cpi ocr_1, $00
    breq rot_aus_2
    cpi ocr_2, $00
    breq rot_aus_2
    rjmp loop

Rot_aus_2:
    inc ocr_3
    rcall pause
    cpi ocr_3, $fe
    brne Rot_aus_2
    ret

timer0_overflow:                      ; Timer 0 Overflow Handler
        inc     PWMCount              ; den PWM Zähler von 0 bis
        cpi     PWMCount, 127        ; 127 zählen lassen
        brne    WorkPWM
        clr     PWMCount
 
WorkPWM:
        ldi     temp, 0b11000000      ; 0 .. Led an, 1 .. Led aus
 
        cp      PWMCount, ocr_1       ; Ist der Grenzwert für Led 1 erreicht
        brlo    OneOn
        ori     temp, $01
 
OneOn:  cp      PWMCount, ocr_2       ; Ist der Grenzwert für Led 2 erreicht
        brlo    TwoOn
        ori     temp, $02
 
TwoOn:  cp      PWMCount, ocr_3       ; Ist der Grenzwert für Led 3 erreicht
    brlo    ThreeOn
        ori     temp, $04

ThreeOn:      
        ori     temp, $08
 
SetBits:                              ; Die neue Bitbelegung am Port ausgeben
    andi temp, 0b00000111
        out     PORTC, temp
 
        reti

pause:
; ============================= 
;   Warteschleifen-Generator 
;     20000 Zyklen:
; ----------------------------- 
; warte 19998 Zyklen:
          ldi  R21, $21
WGLOOP0:  ldi  R22, $C9
WGLOOP1:  dec  R22
          ;brne WGLOOP1
          dec  R21
          ;brne WGLOOP0
; ----------------------------- 
; warte 2 Zyklen:
          nop
          nop
; ============================= 
ret



Autor: Thomas P. (topla)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest in der Interruptroutine timer0_overflow unbedingt das sreg 
sichern.

Thomas

Autor: Michael Mayer (eos400dman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!
Jetzt läuft es.

Gruß Michael

Autor: Vivil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mal diese Zeilen bedenken. Ansonsten hast du einen Zeitbombe.
blau_an:   
    cpi ocr_1, $00
    breq loop


blau_aus:  
    cpi ocr_1, $fe
    breq loop


Gruen_an:   
    cpi ocr_2, $00
    breq loop


gruen_aus:  
    cpi ocr_2, $fe
    breq loop

Rot_an:   
    cpi ocr_3, $00
    breq loop


rot_aus:  
    cpi ocr_3, $fe
    breq loop

Autor: Michael Mayer (eos400dman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es mittlerweile von fe auf ff geändert, kann dir aber nicht 
ganz folgen. Kannst du mir etwas genauer erklären, was du mit Zeitbombe 
meinst?

Gruß Michael

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.