Liebes Forum,
ich versuche für die Ansteuerung von RGB-LEDs einen Tiny dazu zu
bewegen, mir 3 16bit PWMs bereitzustellen. Mit den beiden PWMs vom
Timer1 ist das kein Problem.
Den dritten wollte ich aus dem Timer0 basteln. Dazu wird der im
Fast-PWM-Modus gestartet und ruft sich in einer Interrupt-Routine immer
wieder selbst auf, bis der 16bit-Wert erreicht ist und schaltet sich
dann ab, bis der Timer1 eine neue Runde einlaeutet.
Das funktioniert auch einigermaßen. Leider gibt es immer wieder
"Ruckler" im Fading. Ich kann die Ursache nicht finden. Vielleicht hat
ja jemand eine Idee dazu, oder sowas schon mal selbst gemacht....
lg,
arne
Hier der Code:
1
'3 Kanal 16bit PWM
2
'
3
'Laesst drei LEDs an OC0A, OC1A und OC1B mit 16 bit ein- und ausfaden
4
'Der dritte 16-bit Kanal wird durch mehrfaches Aneinanderhaengen
5
'von Timer0 (8bit) nachgebildet
6
'
7
'Arne Groh
8
'2011-06-20
9
'
10
'Fusebits
11
'1111 1111
12
'1111 1111
13
'1101 1111
14
'1110 0100
15
16
$regfile = "attiny2313.dat"
17
$crystal = 8e6
18
19
20
Dim I As Byte
21
Dim J As Integer
22
Dim Ocr_0a As Word
23
Dim Ocr0ah As Byte
24
Dim Ocr0al As Byte
25
Dim Ocr1a As Word
26
Dim Ocr1b As Word
27
Dim Flags As Byte
28
Lastrun Alias Flags.0
29
30
31
'------------ Timer konfigurieren --------
32
'-- Timer1 --
33
'Fast PWM-Mode 14 einstellen (TOP in ICR1)
34
Set Tccr1a.wgm11
35
Set Tccr1b.wgm12
36
Set Tccr1b.wgm13
37
38
'Ausgaenge bei Compare Match low schalten
39
Set Tccr1a.com1a1
40
Set Tccr1a.com1b1
41
42
'Overflow-Interrupt einschalten
43
Set Timsk.toie1
44
45
'niedrigste Frequenz einstellen (damit man das PWM voll ausreizen kann)
Arne Groh schrieb:> 'Verharren> Waitms 150
Das siehst du. Alles über 100ms Reaktions- oder Verzögerungszeit kann
der normale Mensch bewusst mit dem Auge erkennen. Schonmal mit dem
'Scope angesehen, was deine Ausgänge machen?
mfg mf
Das soll man ja auch sehen - an den beiden Timer1-Fadings tritt das
Problem ja nicht auf. Nur an dem "frisierten" Timer0.
Ja - das Scope zeigt die Ruckler auf dem dritten Kanal auch...
Ich habe nochmal die Interrupt-Routinen geändert:
jetzt wird der Low-Anteil als erstes verarbeitet. Danach dann der Timer
für High-Anteil Male wiederholt.
Das Ergebniss ist jetzt deutlich "weicher". Allerdings gibt es beim
Übergang von High 1 auf 0 immer noch Sprünge. Ausserdem scheint der
TCNT0 ab und an irgendwie überzulaufen. Jedenfalls gibt es beim
runterzählen Werte, an der die LED wieder heller zu werden scheint.
Hat noch jemand eine Idee dazu?
1
T1ovf:
2
Ocr0count = 0
3
'Beim Neustart des Timer1 zunaechst den Low-Teil des 16bit Wertes durch Timer0 ausgeben
4
Ocr0a = Ocr0al
5
'Datenrichtungsbit vom OC0A auf Output schalten
6
Set Ddrb.2
7
'Timer0 zurueck an den Start
8
Set Tifr.tov0
9
10
Return
11
12
13
T0cm:
14
'Incr Ocr0count
15
'Wenn Anzahl der Durchlaeufe erreicht, dann Datenrichtungsbit aendern (Pin auf Input)
16
'Bleibt bis zum naechsten Start von Timer1 auf Input