Forum: Mikrocontroller und Digitale Elektronik PWM-Ausgabe stimmt nicht bei AVR DDS


von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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).

von Alex (Gast)


Lesenswert?

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

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

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?

von Alex (Gast)


Lesenswert?

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)

von Wolfgang (Gast)


Lesenswert?

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.

von Alex (Gast)


Lesenswert?

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.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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).

von Alex (Gast)


Lesenswert?

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.

von Walter (Gast)


Lesenswert?

> An den Lücken ändert sich aber auch bei höherer Abrastrate nichts (z.B.
> 8 MSa/s).

Bild?

von Alex (Gast)


Lesenswert?

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.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Walter schrieb:
> Bild?

12kHz direkt an Messpunkt 1 gemessen.

von Alex (Gast)


Lesenswert?

Alex schrieb:
> 12kHz direkt an Messpunkt 1 gemessen.

Eingestelltes Tastverhältnis ist 0,4%

von Wolfgang (Gast)


Lesenswert?

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.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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).

von Wolfgang (Gast)


Lesenswert?

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.

von Alex (Gast)



Lesenswert?

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).

von Jörg (Gast)


Lesenswert?

Wird bei der Schaltung die PWM nicht am Anschluss HS ausgegeben?

von Alex (Gast)


Lesenswert?

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)

von Codelesa (Gast)


Lesenswert?

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 .....

von Walter (Gast)


Lesenswert?

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.

von Codelesa (Gast)


Lesenswert?

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 ....

von Wolfgang (Gast)


Lesenswert?

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.

von Codelesa (Gast)


Lesenswert?

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.

von Alex (Gast)


Lesenswert?

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.

von Alex (Gast)


Lesenswert?

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)

von Codelesa (Gast)


Lesenswert?

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?

von Wolfgang (Gast)


Lesenswert?

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. ;-)

von Walter (Gast)


Lesenswert?

> 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.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Codelesa (Gast)


Lesenswert?

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 ....

von Wolfgang (Gast)


Lesenswert?

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€ 
;-)

von spess53 (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.