Hallo zusammen,

ich hab gestern mal ein bisschen expeimentiert. Und zwar hatte ich das allgemein bekannte Problem, dass man für RGB drei PWM Kanäle braucht, aber z.B. der Mega8 nur zwei 16 Bit hat. (ich brauch zwingend drei).
Zwei laufen einfach auf dem Compare Units des Timer 1.

Als Eingabe habe ich zwei Spannungsteiler. Der eine Wert wandert direkt in das OCR2 Register. Der andere ist im Prinzip ein Dimmwert.

Hab jetzt aus dem 8 Bit des Timer 2 einen 16 er gemacht. Der Timer 2 ist so aufgesetzt, dass er im fast PWM läuft und bei comparematch den OC2 Pin Low schaltet. Trotzdem lasse ich den zugehörigen Interrupt ausführen.
In der ISR wir eine Variable einfach nur hochgezählt, die naturgemäß bei 255 überläuft. Diese Variable wird mit dem Dimmwert verglichen. Ist sie gleich oder größer, wird das Datenrichtungsbit vom OC2 Pin auf Input gesetzt. Ist sie kleiner, auf Ausgang.

Außerdem habe ich eingaut, das im Prinzip "vorrausschauend" gearbeitet wird. Das Kommentiere ich im Code.

Im Ergebnis ist das natürlich kein echtes 16 Bit PWM, weil die einzelnen 8 Bit PWM´s hintereinander ablaufen. Aber für LED Anwendungen ist das gehupft wie gesprungen.

mfg,
The Man

Code:
.include"m8def.inc"

.org 0x0000
	rjmp reset
.org OC2addr	; OCR2 Interrupt Vector Address
    rjmp hitvalue
reset:
ldi r16,HIGH(RAMEND)
	out SPH,r16
	ldi r16,LOW(RAMEND)
	out SPL,r16
	ldi r16,0b00000000
	out DDRB,r16
	out PORTB,r16
ldi r16,0b10000000
out TIMSK,r16
ldi r16,0b01101001
out TCCR2, r16;       fast PWM,
ldi r16,255
out ICR1H,r16
out ICR1L,r16
ldi r16,255
out OCR1AL,r16
ldi r16,0b10100010
out TCCR1A,r16; clear on match, compare output, fast PWM => ICR1A = Top
ldi r16,0b00011001
out TCCR1B,r16; fast PWM => ICR1A = Top, prescaler = 1
sei

main:
;**********************
;Erfassung Dimmwert
;
ldi r16,0b00100000
out ADMUX,r16
ldi r16,0b11010101
out ADCSRA,r16
warten0:
in r16,ADCSRA
sbrs r16,4
rjmp warten0
in r18,ADCH ;DIMMER
ori r18,1
;**********************

ldi r16,0b00100011
out ADMUX,r16
ldi r16,0b11010101
out ADCSRA,r16
warten3:
in r16,ADCSRA
sbrs r16,4
rjmp warten3
in r21,ADCH
out OCR2,r21

;*********************************
;die gehen an die Comapre Units des Timer 1
;
ldi r16,0b00100001
out ADMUX,r16
ldi r16,0b11010101
out ADCSRA,r16
warten1:
in r16,ADCSRA
sbrs r16,4
rjmp warten1
in r19,ADCH

mul r18,r19
out OCR1AH,r1
out OCR1AL,r0

ldi r16,0b00100010
out ADMUX,r16
ldi r16,0b11010101
out ADCSRA,r16
warten2:
in r16,ADCSRA
sbrs r16,4
rjmp warten2
in r20,ADCH

mul r20,r18
out OCR1BH,r1
out OCR1BL,r0
;*********************************
rjmp main

hitvalue:

out DDRB,r27
inc r25;        
;***************************
;hier wird die Bitkodierung des DDRB für den nächsten Durchgang
; vorrausberechnet
mov r26,r25;
inc r26;<<<<=== VORALLEM HIER!!!
cp r26,r18;
brlo ok;
ldi r27,0b00000110;
rjmp nicht_ok;
ok:;
ldi r27,0b00001110;
nicht_ok:;
;***************************
reti