Hallo, ich versuche mich gerade an einer Software-PWM. Evtl wirds auch ne BCm, das muss ich dann entscheiden wenn ich damit mehr Erfahrung hab :-) Es sollen damit mehrere LEDs gedimmt werden. Später sollen dann mindestens 2 RGB LEDs angesteuert werden. Bevor ich anfange stellt sich mir die Frage, welche Frequenz ich anstreben sollte, um kein Flackern zu haben bzw. schöne Farben zaubern zu können. Ich hätte gerne 10 Bit Auflösung, um dann über eine hinterlegte logarithmische Tabelle das Ganze auf 8 Bit zu mappen. Auserdem dachte ich erst an sportliche 200 Hz. Laufen wird der Prozessor (ATmega32) später mit 8MHz. Limitierend wirkt ja die Länge der ISR. Deswegen werde ich 200Hz/10Bit wohl nicht schaffen, denn: 8000000 / (200*1024) = 39,0625. So kurz werd ich die ISR nicht kriegen. 120 Hz würd ich momentan schaffen, da hätte meine ISR 65 Takte Zeit. Hab nur Bedenken ob man da Flackern sieht. (Es soll ein Objekt illuminiert werden was fest im Raum steht, d.h. die Personen die das Objekt sehen sind in Bewegung, mit mehreren Metern Abstand). Jetz überleg ich, soll ich mit der Auflösung runtergehen oder mit der Frequenz? Was meint ihr?
@ Lukas (Gast) >ich versuche mich gerade an einer Software-PWM. Evtl wirds auch ne BCm, Siehe Soft-PWM. Die hab ich letztes Jahr mit 20 MHz auf 24 Kanäle und 10 Bit ausgereizt. Beitrag "Re: DMX Steuerung 24 Kanal" >anstreben sollte, um kein Flackern zu haben bzw. schöne Farben zaubern >zu können. 100 Hz sollten es schon sein und sind bei nicht bewegten LEDs meistens ausreichend.
Den Artikel kenne ich.
Dort heißt es 10 Bit ermöglichen ein schönes weiche Fading. Deswegen
strebe ich diese auch an.
Allerdings:
>> relativ niedrigen PWM Frequenz von 100 Hz
Deswegen hatte ich bedenken wegen der Frequenz...
Ok, aber deine 24-Kanal PWM arbeitet auch mit 100 Hz. Dann glaub ich dir
mal dass des reicht.
wie schnell willst du die Helligkeit verändern? bei 10bit Auflösung und 100Hz brauchst du 10s um den ganzen Helligkeitsbereich zu durchfahren. Wenn du die Helligkeit schneller änderst, musst du ein paar Helligkeitsstufen überspringen, dann nützt dir die hohe Auflösung nichts. Dann wäre eine höhere Frequenz sinnvoller. Welche Frequenz ausreichend ist, wird auch von verschiedenen Menschen unterschiedlich empfunden.
Hallo Roland, wie kommst du auf die 10s? Meine Vermutung 10Bit ~ 1000 Werte, 1000 * 1/100Hz = 10s. Richtig? Dann hätte ich jeden Wert einmal angefahren. Nun, in meinem Projekt muss ich eher weniger die Farben wechseln. Meist soll das Objekt einfach nur bunt leuchten. Evtl. bau ich aber ein paar Wechsel als Gimmick ein. Aber das ist eben nicht primäres Ziel. Sind dann also 10Bit @ 100Hz schon zuviel? Gäb ja auch noch die Option 9 Bit (wobei ich nicht glaube dass das 9. Bit den Aufwand rechtfertigt, mit uint16_t Variablen arbeiten zu müssen. Soviele neue Werte mit logarithmischen Verhältnis sind dadurch ja nicht gewonnen...)
@ Lukas (Gast) >wie kommst du auf die 10s? Meine Vermutung 10Bit ~ 1000 Werte, 1000 * >1/100Hz = 10s. Richtig? Dann hätte ich jeden Wert einmal angefahren. Wenn man eine nichtlineare Kennline nutzt, sind es deutlich weniger Stufen. Eher so 128-256. >Sind dann also 10Bit @ 100Hz schon zuviel? Nein, passt schon.
Ok, dann werd ich des ganze mal angehen: 10Bit bei 100Hz, ATmega läuft mit 8MHz. Macht 78 Takte für die ISR, richtig? Schau mer mal :-) Was bisl doof ist: an dem Port sind bereits 2 Pins als GPIO vorgesehen. D.h. ich kann nicht einfach meinen Wert auf den Port schreiben sondern muss erstmal den Port einlesen, Maske setzen, mit dem neuen Wert verodern und dann kann ich erst schreiben... Geht das irgendwie möglichst resourcen(=takt)schonend?
So, ich nochmal... Ich hab meine ISR jetzt soweit fertig. Diese soll mir pro Aufruf einen vorher berechneten Wert auf einen Port ausgeben. Wie in meinem vorherigen Post beschrieben wird aber zuerst dieser Port eingelesen und maskiert, da auch "normale" Ausgänge an diesem Port hängen. Anschließend wird das Timerregister aktualisiert.
1 | efc: 1f 92 push r1 |
2 | efe: 0f 92 push r0 |
3 | f00: 0f b6 in r0, 0x3f ; 63 |
4 | f02: 0f 92 push r0 |
5 | f04: 11 24 eor r1, r1 |
6 | f06: 0b b6 in r0, 0x3b ; 59 |
7 | f08: 0f 92 push r0 |
8 | f0a: 2f 93 push r18 |
9 | f0c: 8f 93 push r24 |
10 | f0e: 9f 93 push r25 |
11 | f10: ef 93 push r30 |
12 | f12: ff 93 push r31 |
13 | f14: 8b b1 in r24, 0x0b ; 11 |
14 | f16: 83 70 andi r24, 0x03 ; 3 |
15 | f18: 90 91 65 04 lds r25, 0x0465 |
16 | f1c: e9 2f mov r30, r25 |
17 | f1e: f0 e0 ldi r31, 0x00 ; 0 |
18 | f20: e3 5b subi r30, 0xB3 ; 179 |
19 | f22: fb 4f sbci r31, 0xFB ; 251 |
20 | f24: 20 81 ld r18, Z |
21 | f26: 82 23 and r24, r18 |
22 | f28: 8b b9 out 0x0b, r24 ; 11 |
23 | f2a: 10 92 b2 00 sts 0x00B2, r1 |
24 | f2e: 8b b1 in r24, 0x0b ; 11 |
25 | f30: 88 0f add r24, r24 |
26 | f32: 8b b9 out 0x0b, r24 ; 11 |
27 | f34: 89 2f mov r24, r25 |
28 | f36: 8f 5f subi r24, 0xFF ; 255 |
29 | f38: 8a 30 cpi r24, 0x0A ; 10 |
30 | f3a: 18 f4 brcc .+6 ; 0xf42 <__vector_9+0x46> |
31 | f3c: 80 93 65 04 sts 0x0465, r24 |
32 | f40: 04 c0 rjmp .+8 ; 0xf4a <__vector_9+0x4e> |
33 | f42: 10 92 65 04 sts 0x0465, r1 |
34 | f46: 83 ec ldi r24, 0xC3 ; 195 |
35 | f48: 8b b9 out 0x0b, r24 ; 11 |
36 | f4a: ff 91 pop r31 |
37 | f4c: ef 91 pop r30 |
38 | f4e: 9f 91 pop r25 |
39 | f50: 8f 91 pop r24 |
40 | f52: 2f 91 pop r18 |
41 | f54: 0f 90 pop r0 |
42 | f56: 0b be out 0x3b, r0 ; 59 |
43 | f58: 0f 90 pop r0 |
44 | f5a: 0f be out 0x3f, r0 ; 63 |
45 | f5c: 0f 90 pop r0 |
46 | f5e: 1f 90 pop r1 |
47 | f60: 18 95 reti |
Ich bin nicht so der Assemblerexperte. Kann mir bitte noch jemand mit drüber schauen? Ich komme auf 74 Takte. Ist zwar knapp, sollte aber passen. Habe 78 Takte zur Verfügung. Auser ich beachte grad irgendwas nicht, zB Delays beim Einsprung in die ISR. Kann mir bitte jemand da drüber schauen?
Timer Register aktualisieren klingt irgendwie mach normalem Timer mode. Der Mega32 sollte genügend timer mit CTC mode haben - das spart schon mal die Manipulation am Timer. Das ist bei kleinem Vorteiler ohnehin problematisch. Ein paar PWM Kanäle kann der µC auch in Hardware. Wenn die Auflösung mit 8 Bit nicht reicht, kann man ggf. hier den 8 Bit Wert in Software Modulieren. Das ist immer noch schneller als echtes Software PWM. Wie sieht denn der C Code aus. Wenn man sich in ASM Anstrengt, kann man noch einiges mehr an Geschwindigkeit raus holen. Irgendwo bei 15 Zyklen plus 5 oder 6 je LED sollte das Limit liegen. Bei nur 6 Kanälen ggf. auch darunter. Ein kleiner Trick, der auch in C noch gehen sollte, wäre es das unterste Bit getrennt zu bearbeiten, und Anfangs ein Zeitfenster mit halber Breite zu nutzen - das gibt mit relativ wenig zusätzlicher Laufzeit 1 Bit mehr an Auflösung.
Lukas schrieb: > Ich hätte gerne 10 Bit Auflösung, um dann über eine hinterlegte > logarithmische Tabelle das Ganze auf 8 Bit zu mappen. Was meinst du damit?
DC schrieb: > Lukas schrieb: >> Ich hätte gerne 10 Bit Auflösung, um dann über eine hinterlegte >> logarithmische Tabelle das Ganze auf 8 Bit zu mappen. > > Was meinst du damit? Kurz: Von meinen 1024 möglichen Werten pick ich mir 256 raus die ungefähr im logarithmischen Verhältnis zueinander stehen (wobei 1024 Werte da eigentlich nicht reichen). Dadurch kann die nicht-lineare Helligkeitswahrnehmung des Auges ausgeglichen werden. @ Falk: welchen Simulator? Imho gibt es momentan nur den von Atmel. Das riecht dann nach Windows-VM mit Atmel-Studio aufsetzen :/ Oder gibts da Alternativen?
@ Lukas (Gast) >@ Falk: welchen Simulator? AVR Studio. > Imho gibt es momentan nur den von Atmel. >Das riecht dann nach Windows-VM mit Atmel-Studio aufsetzen :/ Na dann mal los, Herr Pinguin ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.