Hallo zusammen, habe dieses Projekt hier (AVR DDS Signal Generator V2.0) https://github.com/dev26th/avr_dds_20/blob/master/README.md auch nachgebaut. Mir ist dann aufgefallen, dass etwas mit der PWM-Ausgabe nicht stimmt. Und zwar ist es so, dass bei besonders kleinen und besonders großen Tastverhältnissen die Flanken springen. Man kann es mit dem Oszilloskop beobachten und man sieht, dass eine angeschlossene LED parallel dazu flackert. Da ansonsten alles sauber funktioniert, vermute ich, dass es ein Software-Bug ist. Den C-Code habe ich in den Anhang getan (main.c). Vielleicht kann man der Sache hier gemeinsam auf den Grund gehen. Es geht in jedem Fall um die PWM-Ausgabe, nicht um die PWM-HS-Ausgabe (die liegt an einem anderen Pin).
Hier der Code-Bereich, in dem ich den Fehler vermute:
1 | C
|
2 | void pwm_displayDuty(void) { |
3 | LCDGotoXY(10, 0); |
4 | printf("%5.1f%%", ((double)config.pwmDuty+1) / 256 * 100); |
5 | }
|
6 | |
7 | void pwm_updateDisplay(void) { |
8 | signal_updateDisplay(); |
9 | pwm_displayDuty(); |
10 | }
|
11 | |
12 | void pwn_prepareBuffer(void) { |
13 | for(uint8_t i = 0; ; ++i) { |
14 | signalBuffer[i] = (i <= config.pwmDuty) ? 255 : 0; |
15 | if(i == 255) break; |
16 | }
|
17 | }
|
18 | |
19 | void pwm_run(void) { |
20 | while(running) { |
21 | pwn_prepareBuffer(); |
22 | signal_continue(true); |
23 | }
|
24 | }
|
25 | |
26 | void pwm_onStart(void) { |
27 | if(!running) { |
28 | signal_start(); |
29 | pwm_run(); |
30 | signal_stop(); |
31 | }
|
32 | else { |
33 | running = false; |
34 | }
|
35 | }
|
36 | |
37 | void pwm_onUp(void) { |
38 | if(!running) { |
39 | menu_onUp(); |
40 | }
|
41 | else { |
42 | if(config.pwmDuty < 255) ++config.pwmDuty; |
43 | pwm_updateDisplay(); |
44 | }
|
45 | }
|
46 | |
47 | void pwm_onDown(void) { |
48 | if(!running) { |
49 | menu_onDown(); |
50 | }
|
51 | else { |
52 | if(config.pwmDuty > 0) --config.pwmDuty; |
53 | pwm_updateDisplay(); |
54 | }
|
55 | }
|
56 | Code
|
Hier noch ein Screen-Shot vom Oszilloskop-Bild. PWM-Frequenz: 11kHz Tastverhältnis 0,4% Man sieht deutlich die Lücken und die unterschiedlich hohe Amplitude der PWM-Pulse.
Hi >Man sieht deutlich die Lücken und die unterschiedlich hohe Amplitude der >PWM-Pulse. Mach mal ein Foto vom Messaufbau. Welcher Oszi? Ich sehe nur eine Reihe von Messfehlern. MfG Spess
Alex schrieb: > Man sieht deutlich die Lücken und die unterschiedlich hohe Amplitude der > PWM-Pulse. Wieso erwartest du bei einer Abtastrate von 1 MSa/s ein vernünftiges Bild deines PWM-Signals, wenn der Takt zur Erzeugung eines 0.4% Pulses mit 11kHz schon bei deutlich über 2MHz liegen muss?
Rein gefühlsmäßig vermute ich folgendes: a) Es wurde vergessen, bei der PWM-Ausgabe einen störenden Interrupt zu deaktivieren. b) Das Orginal-Projekt läuft auf einem Atmega16. Der Autor für den oben angegebenen Code verwendet einen neueren (oder anderen) Atmega (im Schaltplan gibt er Mega16-P an - ich selber benutze einen Mega16-PU). Könnte eins von beidem zu dem Fehlerbild passen? -------------------------------------------------------------- spess53 schrieb: > Ich sehe nur eine Reihe von Messfehlern. An Messfehler hatte ich auch zuerst gedacht. Dann habe ich eine LED über einen Widerstand parallel zum Ausgang angeschlossen und die LED flackert nun gut sichtbar im Takt der "Messfehler". Werde gleich noch mit einem Frequenzmesser gegentesten. (Oszi ist ein 20MHz-China-USB-Teil - könnte auch noch mal mit einem Analogoszi gegenprüfen, aber wegen der ebenfalls flackernden LED tippe ich sehr darauf, dass das Problem ein Software-Bug ist)
Alex schrieb: > An Messfehler hatte ich auch zuerst gedacht. Alleine die Tatsache, dass bei einem (digitalen) PWM-Signal negative Spitzen auftreten, spricht zumindest für einen falsch abgeglichenen Tastkopf. Guck dir mal bei einer angemessenen Abtastrate die Einzelpulse an.
Wolfgang schrieb: >> Man sieht deutlich die Lücken und die unterschiedlich hohe Amplitude der >> PWM-Pulse. > > Wieso erwartest du bei einer Abtastrate von 1 MSa/s ein vernünftiges > Bild deines PWM-Signals, wenn der Takt zur Erzeugung eines 0.4% Pulses > mit 11kHz schon bei deutlich über 2MHz liegen muss? Da hast du recht, Danke für den Hinweis! An den Lücken ändert sich aber auch bei höherer Abrastrate nichts (z.B. 8 MSa/s). Und wie gesagt "wandern" die Lücken beim Messen über den Bildschirm und eine parallel geschaltete LED flackert im Takt der Wanderbewegungen der Lücken.
Der Frequenzzähler (Reziprokzähler bis 80MHz mit Schmitt-Trigger-Eingang) zählt ab einem Tastverhältnis von >= 0,8% die korrekte Frequenz aus. Bei einem TV von 0,4% zeigt er genau 2/3 der Frequenz an. Hm. Im Anhang noch der Messaufbau (Oszi-Anschluss unten mitte/rechts).
Alex schrieb: > Und wie gesagt "wandern" die Lücken beim Messen über den Bildschirm und > eine parallel geschaltete LED flackert im Takt der Wanderbewegungen der > Lücken. Zwischenzeitlich hatte ich zwischen Ausgang und LED (mit Rv) ein Bustreiber-IC zwischengeschaltet, weil ich dachte, die LED belastet vielleicht den Ausgang zu stark. Das Flackern blieb aber nach wie vor bestehen.
> An den Lücken ändert sich aber auch bei höherer Abrastrate nichts (z.B. > 8 MSa/s). Bild?
Wolfgang schrieb: > Alleine die Tatsache, dass bei einem (digitalen) PWM-Signal negative > Spitzen auftreten, spricht zumindest für einen falsch abgeglichenen > Tastkopf. Die Tastköpfe sind perfekt abgeglichen, grade noch mal getestet. Wenn ich den Tastkopf direkt an Messpunkt 1 anschließe (s. Schaltplan oben), bleiben die negativen Überschwinger aus.
Alex schrieb: > 12kHz direkt an Messpunkt 1 gemessen. Mit PWM hat dieser Puls ja nicht viel zu tun. Was für ein Signal gibst du da aus? Guck doch mal, die Signale direkt an den Digitalausgängen vorm DAC z.B. mit einem LA an.
Wolfgang schrieb: > Mit PWM hat dieser Puls ja nicht viel zu tun. Ja, merkwürdig, fast so, als wäre irgendwo eine parasitäre Kapazität. > Guck doch mal, die Signale direkt an den Digitalausgängen vorm DAC z.B. > mit einem LA an. Die Sache ist ganz einfach, im PWM-Modus gehen alle Pins (also PA0 bis PA7) gleichzeitig auf hi oder lo. Im Anhang direkt an PA0 gemessen. In der Realität springt der Peak hin und her (auf dem Bild natürlich nicht erkennbar).
Alex schrieb: > In der Realität springt der Peak hin > und her (auf dem Bild natürlich nicht erkennbar). Bezogen auf was spring der hin- und her. Wenn du auf den vorhergehenden triggerst, muss er (halbwegs) stehen. Dann kannst du dir auch den Jitter angucken, indem du den Mittelwert über vieles Triggerereignisse anguckst.
Wolfgang schrieb: > Bezogen auf was spring der hin- und her. Das Signal entsteht bei TV von 0,4% immer an einer der drei rot markierten Stellen (auf mehr oder weniger chaotische Art und Weise). Wenn man das Tastverhältnis von 0,4% auf 0,8% hochstellt, ist jeweils über jeder roten Markierung ein Signal zu sehen (stabil ohne Springen und Wechseln).
Wird bei der Schaltung die PWM nicht am Anschluss HS ausgegeben?
Jörg schrieb: > Wird bei der Schaltung die PWM nicht am Anschluss HS ausgegeben? Nein, die HS-Signale werden an Pin 19 ausgegeben. Es gibt auch HS-PWM, von dem ist hier aber nicht die Rede. Hier geht es um die normale PWM-Ausgabe, die über das R2R-Netzwerk an Port A ausgegeben wird. Aber auf jeden Fall Danke fürs Mitüberlegen!!! (HS-PWM kann nur ein paar fest vorgegebene Frequenzen über OC1A ausgeben)
Alex schrieb: > Da hast du recht, Danke für den Hinweis! > > An den Lücken ändert sich aber auch bei höherer Abrastrate nichts (z.B. > 8 MSa/s). Wie änderst du denn in dem Programm die Abtastrate? Ich denke du hast da noch etwas überhaupt nicht verstanden .....
PWM Frequenz: 11 KHz Tastgrad: 1/256 % PWM-Auflösung: 8 Bit Updatezeit: ~364 ns entspicht 7 Zyklen, Rest 14 ns Die Frage ist, ob der µC das auflösen kann? Das Programm habe ich mir jetzt nicht näher angesehen, da es einfach nicht gut genug kommentiert ist.
Walter schrieb: > Die Frage ist, ob der µC das auflösen kann? Nö, glaube ich nicht .... auch ich hab mir das nicht näher angeschaut da es aus dem Bauch heraus beurteilt nicht funktioniert ....
Alex schrieb: > Das Signal entsteht bei TV von 0,4% immer an einer der drei rot > markierten Stellen (auf mehr oder weniger chaotische Art und Weise). Dann guck doch mal im Simulator, warum das passiert. Der Zyklenzähler oder die Stop-Uhr verrät dir, wo du zeitlich liegst.
Wolfgang schrieb: > Dann guck doch mal im Simulator, warum das passiert. Wenn er das mit der Abtastrate (noch) nicht verstanden hat dann ist das hier auch nicht sinnvoll.
Wolfgang schrieb: > Alex schrieb: >> Das Signal entsteht bei TV von 0,4% immer an einer der drei rot >> markierten Stellen (auf mehr oder weniger chaotische Art und Weise). > > Dann guck doch mal im Simulator, warum das passiert. Der Zyklenzähler > oder die Stop-Uhr verrät dir, wo du zeitlich liegst. Mit Simulator meinst du eine Simulation im AVR-Studio? Bin da nicht so bewandert, habe es aber immerhin installiert.
Walter schrieb: > PWM Frequenz: 11 KHz > Tastgrad: 1/256 % > PWM-Auflösung: 8 Bit > > Updatezeit: ~364 ns entspicht 7 Zyklen, Rest 14 ns > > Die Frage ist, ob der µC das auflösen kann? Das Programm habe ich mir > jetzt nicht näher angesehen, da es einfach nicht gut genug kommentiert > ist. Ok, wenn der Atmega das gar nicht schaffen kann, ist die weitere Fehlersuche wohl sinnlos. Aber vielleicht gibt es ja bestimmte Frequenzen, bei denen es exakt hinkommt. Das wäre ja schon mal was, wenn man die kennen würde :O)
Alex schrieb: > Mir ist dann aufgefallen, dass etwas mit der PWM-Ausgabe nicht stimmt. Das angegebene Sourcen-Gefüge ist nicht auf Anhieb fehlerfrei compilierbar. Wenn man dann die kleinen Ungereimtheiten ausmerzt entsteht ein Code der nicht in den angegebenen ATMega16 hineinpasst. --------------------------------------- AVR Memory Usage ---------------- Device: atmega16 Program: 21028 bytes (128.3% Full) (.text + .data + .bootloader) Data: 763 bytes (74.5% Full) (.data + .bss + .noinit) --------------------------------------- wie funktioniert das bei dir?
Alex schrieb: > Mit Simulator meinst du eine Simulation im AVR-Studio? Bin da nicht so > bewandert, habe es aber immerhin installiert. Dann starte den Simulator doch mal mit deinem DDS-Code. Nur installieren alleine bringt nichts. ;-)
> Ok, wenn der Atmega das gar nicht schaffen kann, ist die weitere > Fehlersuche wohl sinnlos. So schnell sollte man nicht aufgeben. --- Die schnellste Routine auf dem µCNet stammt von Werner: Beitrag "Re: DDS Sinus erzeugung"
1 | add r28,r24 |
2 | LOOP1: |
3 | adc r29,r25 ; 1 |
4 | adc r30,r26 ; 1 |
5 | lp ; 2 |
6 | out PORTB,r0 ; 1 UpDate |
7 | add r28,r24 ; 1 |
8 | adc r29,r25 ; 1 |
9 | adc r30,r26 ; 1 |
10 | add r28,r24 ; 1 |
11 | lp ; 2 |
12 | out PORTB,r0 ; 1 UpDate |
13 | rjmp LOOP1 ; 2 => 14/2 = 7 cycles |
Wenn du die Ausgabe so machst wie Werner (unbedingt den ganzen Thread lese, der sehr interessant ist), dann hast du bei einer Taktfrequenz der CPU von 20 MHz und eine PWM-Auflösung von 8 Bit eine max. Frequenz von rund 11160,7 Hz. Gehst du mit der Frequenz höher, dann verringert sich die Auflösung der PWM.
Hallo Leute, vielen herzlichen Dank für das Interesse und das Ausprobieren etc. Codelesa schrieb: > Das angegebene Sourcen-Gefüge ist nicht auf Anhieb fehlerfrei > compilierbar. > > Wenn man dann die kleinen Ungereimtheiten ausmerzt entsteht > ein Code der nicht in den angegebenen ATMega16 hineinpasst. > > --------------------------------------- > AVR Memory Usage > ---------------- > Device: atmega16 > > Program: 21028 bytes (128.3% Full) > (.text + .data + .bootloader) > > Data: 763 bytes (74.5% Full) > (.data + .bss + .noinit) > --------------------------------------- > > wie funktioniert das bei dir? Ich habe einfach die fertige main.hex von hier https://github.com/dev26th/avr_dds_20 auf den Atmega16 geflasht (siehe Anhang). Interessant, dass das Compilieren vom Source-Code ein File erzeugt, das nicht mehr auf den M16 geschrieben werden kann. Eventuell wurde vom Autor ein M32 verwendet, ohne dass er es im Schaltplan geändert hat?!? Auch sehr verwunderlich, das es eine deutlich andere Größe hat als die mitgelieferte main.hex-Datei. Könnte das Problem bei einer Compiler-Optimierungseinstellung liegen? Wolfgang schrieb: > Dann starte den Simulator doch mal mit deinem DDS-Code. Nur installieren > alleine bringt nichts. ;-) Ist auf dem anderen Rechner installiert, morgen kann ich es testen. Walter schrieb: > dann hast du bei einer Taktfrequenz der > CPU von 20 MHz und eine PWM-Auflösung von 8 Bit eine max. Frequenz von > rund 11160,7 Hz. Gehst du mit der Frequenz höher, dann verringert sich > die Auflösung der PWM. Danke für den Beitrag, sehr aufschlussreich!!! Das aktuelle Projekt läuft mit 16MHz, liegt dann die max. mögliche 8-Bit-PWM bei 8928 Hz?
Alex schrieb: > Könnte das Problem bei einer Compiler-Optimierungseinstellung liegen? Nein, ich habe/hatte -0s eingestellt, das ist schon die Optimierung mit dem kleinsten Code. Mehr geht nicht. Einzige mögliche Stolperfalle bei mir: ich habe WinAVR-20100110 benutzt, also weit weg von aktuellen Compiler-Versionen. Aber ich bezweifle dass man noch mehr als 20% mit einer neueren Version einsparen kann ....
Codelesa schrieb: > Wenn man dann die kleinen Ungereimtheiten ausmerzt entsteht > ein Code der nicht in den angegebenen ATMega16 hineinpasst. Gräm dich nicht. Ein ATmega328 gibt es fertig auf Platine für unter 2€ ;-)
Hi
>Gräm dich nicht. Ein ATmega328 gibt es fertig auf Platine für unter 2€
Was nutzt ihm das?
ATmega328 -> 28 Pins
ATMega16 -> 40 Pins
MfG Spess
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.