mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Programmablauf für 3-Kanal LED-Fading


Autor: Christoph B. (nuke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo allerseits,

Ich hab mich in letzter Zeit mal wieder ein bisschen mit Software PWM 
beschäftigt und möchte nun eine 3-Kanal PWM zum Dimmen einer (oder 
mehrerer ;-) ) RGB-LED(s) realisieren. Ich nutze einen Atmel Atmega8. 
Mein bisheriger Code dimmt eine LED logarithmisch in einer festgelegten 
Geschwindigkeit zwischen einem MIN und einem MAX Wert rauf und runter, 
ist aber schon gut auf die 3 LEDs erweiterbar.
.include "m8def.inc"

.def counter = r16        ;PWM-Counter
.def temp = r17          ;temp-Register
.def port = r18          ;Port-Byte

.def led1 = r19          ;Helligkeitswert 1 mit Gammakorrektur
.def led2 = r20          ;Helligkeitswert 2 mit Gammakorrektur
.def led3 = r21          ;Helligkeitswert 3 mit Gammakorrektur

.def ledpointer1 = r22      ;Helligkeitswert 1 ohne Gammakorrektur
.def ledpointer2 = r23      ;Helligkeitswert 2 ohne Gammakorrektur
.def ledpointer3 = r24      ;Helligkeitswert 3 ohne Gammakorrektur

.def dir = r25          ;Richtungs-Flagregister
.def speed1 = r26        ;Counter 1 für Geschwindiggkeit

.equ CMAX = 255          ;PWM-Counter Maximalwert

.equ MIN1 = 50          ;Minimalwert 1
.equ MAX1 = 255          ;Maximalwert 1

.cseg
.org $0000
    rjmp reset        ; Reset Handler
    reti          ; IRQ0
    reti          ; IRQ1
    reti          ; Timer/Counter2 Compare Match
    reti          ; Timer/Counter2 Overflow
    reti          ; Timer/Counter1 Capture Event
    reti          ; Timer/Counter1 Compare Match A
    reti          ; Timer/Counter1 Compare Match B
    reti          ; Timer/Counter1 Overflow
    rjmp calc_leds      ; Timer/Counter0 Overflow
    reti          ; Serial Transfer Complete
    reti          ; USART, Rx Complete
    reti          ; USART, Data Register Empty
    reti          ; USART, Tx Complete
    reti          ; ADC Conversion Complete
    reti          ; EEPROM Ready
    reti          ; Analog Comparator
    reti          ; Two-Wire Serial Interface
    reti          ; Store Program Memory Ready

reset:
    ldi temp, LOW(RAMEND)  ;Init Stackpointer
    out SPL, temp
    ldi temp, HIGH(RAMEND)
    out SPH, temp

    ldi ZL, LOW(pwm_seq*2)  ;Init Z-Pointer
    ldi ZH, HIGH(pwm_seq*2)

    ldi temp, 0xFF      ;Config Port D
    out DDRD, temp
    out PORTD, temp      ;LEDs aus
    
    ldi led2, 0
    ldi led3, 0

    ldi temp, 1<<TOIE0    ;Config Timer/Counter0
    out TIMSK, temp
    ldi temp, 0x00
    out TCNT0, temp
    ldi temp, 0b00000001  ;ohne Prescaler
    out TCCR0, temp

    sei

    clr speed1
    clr ledpointer1
    clr dir

main:
    brtc main        ;Idle-Schleife, solange PWM-Zyklus noch nicht fertig
    
    inc speed1
    cpi speed1,3
    brne fade_end

    cpi dir,255
    breq backward

forward:
    inc ledpointer1

    cpi ledpointer1,MAX1
    brne next1

    com dir

next1:
    clr speed1

    rjmp fade_end

backward:
    dec ledpointer1

    cpi ledpointer1,MIN1
    brne next2

    com dir

next2:
    clr speed1

fade_end:
    clt
    
    rjmp main

calc_leds:
    ldi ZL, LOW(pwm_seq*2)  ;Gammakorrektur
    ldi ZH, HIGH(pwm_seq*2)
    ldi temp,0

    add ZL,ledpointer1
    adc ZH,temp

    lpm led1,Z
    

check_led1:
    ldi port, 0b11111000  ;Alle LEDs an

    cp counter, led1    ;LED1 vergleichen
    brlo check_led2

    ori  port, 0b00000001  ;wenn led1>=counter: LED1 aus

check_led2:
    cp counter, led2    ;LED2 vergleichen
    brlo check_led3

    ori  port, 0b00000010  ;wenn led2>=counter: LED2 aus

check_led3:
    cp counter, led3    ;LED3 vergleichen
    brlo check_end

    ori  port, 0b00000100  ;wenn led3>=counter: LED3 aus

check_end:
    out PORTD, port      ;Portausgabe

    cpi counter, CMAX    ;Maximalwert erreicht?
    breq cycleReset      ;ja: PWM-Zyklus zu Ende
    inc counter        ;nein: counter+1

    reti

cycleReset:
    clr counter        ;counter = 0

    set            ;T-Flag im SREG setzen, PWM-Zyklus fertig

    reti

pwm_seq:            ;logarithmische Helligkeitswerte für Gammakorrektur
    .db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,10,10,11,11,11,11,12,12,12,13,13,13,13,14,14,14,15,15,15,15,16,16,16,17,17,17,18,18,18,19,19,20,20,20,21,21,22,22,22,23,23,24,24,25,25,26,26,26,27,27,28,28,29,30,30,31,31,32,32,33,33,34,35,35,36,37,37,38,38,39,40,41,41,42,43,43,44,45,46,46,47,48,49,50,51,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,71,72,73,74,75,77,78,79,80,82,83,84,86,87,89,90,92,93,95,96,98,99,101,102,104,106,107,109,111,113,115,116,118,120,122,124,126,128,130,132,134,137,139,141,143,145,148,150,153,155,157,160,162,165,168,170,173,176,179,181,184,187,190,193,196,199,202,206,209,212,216,219,222,226,229,233,237,241,244,248,252,255

Jetzt würde ich gern eine Art Programmablauf im Programmspeicher 
speichern, wo die nächsten Helligkeitswerte der einzelnen LEDs (noch 
ohne logarithmischen Verlauf, sprich "ledpointerX" im Code), sprich die 
nächste Farbe und die Fade-Geschwindigkeiten gespeichert sind. Dieser 
Programmablauf soll dann zyklisch durchlaufen werden.
Also z.B. R1,G1,B1,Zeit1,R2,G2,B2,Zeit2,...
Das Problem besteht jetzt darin, alle 3 Helligkeitswerte in der 
vorgegebenen Zeit von drei unterschiedlichen Anfangswerten zu drei 
unterschiedlichen Endwerten zu dimmen, also die Farbe zu wechseln.

Vielleicht hat sowas schonmal jemand gemacht (bestimmt) und kann mir 
weiterhelfen.

Vielen Dank!

Grüße,
Christoph

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.