Forum: Mikrocontroller und Digitale Elektronik DDS normal ?


von Werner (Gast)


Lesenswert?

Hallo,

ich habe so ähnlich wie hier

Beitrag "DDS erster Versuch"
oder beim Vater dieser Dinger
http://www.myplace.nu/avr/minidds/

'mal einen DDS zusammengenagelt.

Bei mir stimmt die Frequenz nicht wirklich:
    10Hz =      9,97Hz
   100Hz ~    109Hz
  1000Hz ~   1007Hz
 10000Hz ~   9852Hz
100000Hz ~  91139Hz

gemessen mit TANDAR TF 200 und VOLTCRAFT VC1008 und "Dings" Multimeter
Die sind sich einig.

Quarz 14,745600MHz
Schleife wie Jesper.

;  f = r24/r25/r26 * (14745600/9)/16777216
;  f = r24/r25/r26 * 0.09765625

Ist das normal ? Um ein - zwei Hertz würde ich ja nicht streiten.

MfG Werner

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:

> Ist das normal ?

Ich würd sagen: Nein.
Ist ein bischen viel Abweichung quer durch die Bank.

von Wolfgang (Gast)


Lesenswert?

Ohne deinen Code zu kennen, ist es schwierig, den Fehler einzukreisen. 
Mögliche Ursachen sind eine falsche Prozessorzyklenzahl als Basis der 
Frequenzberechnung, eine von der Angabe auf dem Quarz abweichende 
Prozessorfrequenz oder sonstwas ...

Aber normal ist das bestimmt nicht.

von Werner (Gast)


Lesenswert?

Hallo,

es ist ein ATmega8 mit besagtem Quarz.
Er wird von einem zweiten ATmega16 ( Tastatur, Drehgeber, LCD, USB 
Interface etc.) per TWI getsuert.
Also nur über TWI Interrupts unterbrichen.
Die Zweiteilung wollte ich um eine bessere Bedienerführung, - oberflöche
zu haben.
Aber einmal eingestellt schweigt der 16er. Ich kann ihn auch abziehen.
Die paar Zeilen im 8er laufen völlig ungestört ab. Code Snipsel unten:

Hat schon einmal jemand nachgemessen ?

LG Werner

ldi    r16,low(RAMEND)
    out    SPL, r16    ; setup stack pointer
    ldi    r16, high(RAMEND)
    out     SPH,r16



    clr    r16
    out    PORTD,r16    ; clear all PORTD bits
    out    PORTB,r16    ; clear all PORTB bits
    ser    r16        ;
    out    DDRD,r16    ; set all PORTD bits as output
    out     DDRB,r16        ; set all PORTB bits as output

      ; TWI INITIALISIERUNG
    rcall TWI_INI

    ; STARTWERTE
    clr DATA
    clr ADRESS

    ; alle Interrupts freigeben
    sei            ; global enable interrupts

    ; set sinewave output as default

    ldi ZH, high(sine*2)              ; Initialize Z pointer

    ldi ZL, low(sine*2)

    ; clear accumulator

    ldi   r29,0x00    ; clear accumulator
    ldi   r28,0x00    ; clear accumulator

    ; setup adder registers

    ldi   r24,0x55    ; setup adder value
    ldi   r25,0x35    ; to 1 kHz
    ldi   r26,0x00    ;

; main loop
;
;  r28,r29,r30 is the phase accumulator
;    r24,r25,r26 is the adder value determining frequency
;
;   add value to accumulator
;  load byte from current table in ROM
;  output byte to port
;  repeat

LOOP1:
    add    r28,r24      ; 1
    adc    r29,r25      ; 1
    adc    r30,r26      ; 1
    lpm            ; 3
    out    PORTD,r0    ; 1
    rjmp  LOOP1      ; 2 => 9 cycles


;*********************************************************************** 
*******
; data tables
;*********************************************************************** 
*******

  ; force table to begin at 256 byte boundary

  .org 0x080

sine:    ; 256 step sinewave table
  .db 
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x 
07,0x08
  .db 
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x 
21,0x23
  .db 
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x 
49,0x4c
  .db 
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x 
79,0x7c

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:

> Er wird von einem zweiten ATmega16 ( Tastatur, Drehgeber, LCD, USB
> Interface etc.) per TWI getsuert.

Dann würde ich mir in besagtem 2-ten Mega mal die Berechnung der 
Additionskonstante genauer ansehen.
Mit deren Korrektheit steht und fällt die Genauigkeit der Jesper-DDS

von Werner (Gast)


Lesenswert?

Hallo,

das ist ein schönes Forum!
Es hätte ja sein können, dass Jesper so geht ..

Der "große" 16er läuft mit BASCOM.
Die DDS relevanten Variablen waren Typ "single", das reicht wohl nicht,
( Frequenz, Auflösung )
1 und 10 kHz sahen "double" schon OK aus... +/- Auflösung

morgen klingelt wieder der Wecker :0(

Danke.

von noch einer (Gast)


Lesenswert?

Typ single reichen natürlich nicht. Denn single hat im optimalen Fall 
5-6 stellen Auflösung.

von Werner (Gast)


Lesenswert?

Hallo,

heute habe ich nochmal dran gemacht....

Die Rundungsfehler ( mangelnde Genauigkeit ) sind wohl weg.
BASCOM mit der DOUBLE.LBX und mein Taschenrechner errechnen die gleichen 
Werte für den Addierer.
Also wieder gemessen:

    10 Hz   ~     9,9 Hz
   100 Hz   ~   100,1 Hz
  1000 Hz   ~   999,9 Hz
 10000 Hz   ~  9843,0 Hz
100000 Hz   ~ 91019   Hz

? Ich habe die Berechnung im 16er auch weggelassen und die Sollwerte 
direkt
per TWI reingeschrieben.
? Am Ende habe ich den 8er so programmiert, dass auf Reset die Sollwerte
angenommen wurden 1024 , 10240 , 102400 usw.
?
LG Werner

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:
> Hallo,
>
> heute habe ich nochmal dran gemacht....
>
> Die Rundungsfehler ( mangelnde Genauigkeit ) sind wohl weg.
> BASCOM mit der DOUBLE.LBX und mein Taschenrechner errechnen die gleichen
> Werte für den Addierer.

Das heißt noch lange nicht, dass sie stimmen.

Gib doch mal ein paar Werte an.

> Also wieder gemessen:
>
>     10 Hz   ~     9,9 Hz
>    100 Hz   ~   100,1 Hz
>   1000 Hz   ~   999,9 Hz
>  10000 Hz   ~  9843,0 Hz

angenommen, nur angenommen (du magst das praktische Experiment machen), 
du würdest hier bei dieser Einstellung deinen Additionswert um 1 erhöhen 
und mit dem die DDS laufen lassen; wärst du dann über 10000 Hz drüber?

von Simon K. (simon) Benutzerseite


Lesenswert?

Eine DDS mit Gleitkomma? Ich dachte man benutzt DDS um ohne Gleitkomma 
auszukommen ;-) Wenn nicht sogar Gleitkomma mit der begrenzten 
"schwammigen" Genauigkeit da mehr kaputt macht als ganz.

von Werner (Gast)


Lesenswert?

Hallo

Quarz 14,745600 MHz,
9 Zyklen
(14745600 / 9) / 2°24
1638400 / 16777216 = 0,09765625

f(out) = 0,09765625 * ADDER
ADDER = f(out) / 0,09765625

z.B. für 1000 Hz
1000 / 0,09765625 = 10240 = ADDER


                            ADDER jewils + 1
    10 Hz   ~     9,9 Hz        9,9 Hz
   100 Hz   ~   100,1 Hz      100,1 Hz
  1000 Hz   ~   999,9 Hz      998,6 Hz
 10000 Hz   ~  9843,0 Hz     9986,9 Hz
100000 Hz   ~ 91019   Hz    91089   Hz

Also nicht über 10.000 Hz. Aber näher dran.

Grüße Werner

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:
> Hallo
>
> Quarz 14,745600 MHz,
> 9 Zyklen
> (14745600 / 9) / 2°24
> 1638400 / 16777216 = 0,09765625
>
> f(out) = 0,09765625 * ADDER
> ADDER = f(out) / 0,09765625
>
> z.B. für 1000 Hz
> 1000 / 0,09765625 = 10240 = ADDER
>
>
>                             ADDER jewils + 1
>     10 Hz   ~     9,9 Hz        9,9 Hz
>    100 Hz   ~   100,1 Hz      100,1 Hz
>   1000 Hz   ~   999,9 Hz      998,6 Hz

das ist jetzt aber verblüffend. Die Frequenz wird kleiner?

>  10000 Hz   ~  9843,0 Hz     9986,9 Hz
> 100000 Hz   ~ 91019   Hz    91089   Hz
>
> Also nicht über 10.000 Hz. Aber näher dran.

Mit anderen Worten:
Deine Berechnung ist Sch....

von Werner (Gast)


Lesenswert?

Hallo Simon,

nein in den DDS gehen 24 bit.

Nur ich kann das nicht im Kopf, also soll z.B. 1000 auf der Tastatur
eingegeben werden und dann 10240 reingeschoben werden.
Das geht auch, nur > ~ 5000 Hz ist der DDS zu ungenau.
Warum auch immer ?

Grüße Werner

von Werner (Gast)


Lesenswert?

Mit anderen Worten:
Deine Berechnung ist Sch....

Und wenn du das so rechnest

> 1638400 / 16777216 = 0,09765625
> 1000 / 0,09765625 = 10240 = ADDER

wundert mich das noch nicht einmal.

und wie dann? Etwas konstruktiver.

LG Werner

von Karl H. (kbuchegg)


Lesenswert?

Ich hab mir das mit der Berechnung noch mal durch den Kopf gehen lassen 
und ein wenig mit dem Taschenrechner gespielt. War nicht so schlimm wie 
gedacht.

Probier mal was aus
1
    ....
2
3
    ; setup adder registers
4
5
    ldi   r24,0x00    ; setup adder value
6
    ldi   r25,0x00    ; to 1 kHz
7
    ldi   r26,0x01    ;
8
9
    ....

und setz keinen Wert von extern.

das müsste bei deiner Quarzfrequenz glatte 6400 Hz ergeben.

Wieviel misst du tatsächlich?

Was ist wenn du den sei rausnimmst, so dass auf keinen Fall Interrupts 
dazwischen kommen können?

von Werner (Gast)


Lesenswert?

egal wie,

(1000 * 16777216) / 163840

Die Zahlenfolge bleibt 1024 + eine Reihe Nullen.
Wenn ich das direkt im Addierregister des 8er habe kommt trozdem die
falsche Frequenz raus.

Oder sehe ich da was nicht ?

Werner

von Ulrich (Gast)


Lesenswert?

Der Wert von 0,09765625 für die Skalierung ist schon Ok. Vermutlich war 
nicht klar, das die Taktfrequenz des Quarzes tatsächlich durch 9 teilbar 
ist.

Die Rechnung ist halt schon etwas BASCOM angehaucht, immer nur 1 Schritt 
pro Zeile. Sonst aber wohl OK.

Das Problem wird wohl sein wie die ADDR-Werte berechnet werden, also der 
Code vom Mega16.
Ein Problem könnte das
1000/ 0,09765625
sein besser wäre ggf.
1000.0 / 0,09765625 - so wäre klar das die Konstante auch Fließkomma 
ist.

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:
> egal wie,
>
> (1000 * 16777216) / 163840
>
> Die Zahlenfolge bleibt 1024 + eine Reihe Nullen.
> Wenn ich das direkt im Addierregister des 8er habe kommt trozdem die
> falsche Frequenz raus.
>
> Oder sehe ich da was nicht ?

Nein, nein.
Du hast schon recht.
Da ist irgendwas anderes faul

* Quarz daneben. Dazu ist die Abweichung zu groß
* Übertragung klappt nicht richtig
* Interrupts funken dazwischen.


Daher der Vorschlag: Schreib den Wert direkt ins DDS Programm rein und 
sorg dafür, dass auf keinen Fall Interrupts dazwischen funken können. 
Dann MUSS die Frequenz richtig rauskommen. Und dann arbeiten wir von 
hinten nach vorne und aktivieren wieder einzelne Teile.

von Werner (Gast)


Lesenswert?

r24 = 0x00, r25 = 0x00, r26 = 0x01

TANDAR TF 200 6335 Hz
( Der Zähler zählt )
VC1008        6350 +/- 10Hz
( Das Voltcraft macht das aus der Periodendauer,
schankt wegen des Jitter ( noch ein Thema zum Jesper ))

Der ATmega ist ganz alleine, der 16er abgezogen.

Grüße Werner

von Karl H. (kbuchegg)


Lesenswert?

> Wenn ich das direkt im Addierregister des 8er habe kommt trozdem die
> falsche Frequenz raus.

Sorry. Überlesen.
Dann gibt es nur noch einen Schluss.
Wenn der SEI auch noch auskommentiert ist, dann stimmen die 14.xx Mhz 
nicht.

von Werner (Gast)


Lesenswert?

SEI ist raus.

Die 14,745600 MHz kann ich am ATega nicht messen.
Der Zähler hat dort 50 Ohm Eingangsimpedanz ,saldo NULL.
Wenn ich das Voltcraft an's Quarz hänge passiert seltsames.

Ich habe eine Schleife um den ATmega gelegt.

Ein KENWOOD TS 850 SAT enpfängt QRG 14,745600 im Schwebungsnull.
Und das Ding war teuer, stimmt.
Das Quarz sollte also +/- 50 Hz stimmen.
1 Hz wenn ich die Schwankungen der Feldstärkeanzeige verfolge.

Hat denn jemand schon 'mal gemessen, oder freunen sich alle wenn sie 
eine
Frequenz wählen / anzeigen und etwas zappelt ?

mfg Werner

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:

> Hat denn jemand schon 'mal gemessen, oder freunen sich alle wenn sie
> eine
> Frequenz wählen / anzeigen und etwas zappelt ?

Darum gehts nicht.
Aber wenn deine Schleife 9 Taktzyklen braucht UND der Quarz 14.x Mhz hat 
UND die Tabelle 256 Einträge umfasst, die eine Schwingung beschreibt, 
dann laufen da 6400 Schwingungen pro Sekunde durch. Was anderes ist 
nicht möglich. So ein µC ist ja eine deterministische Maschine - völlig 
vorhersehbar.

von Werner (Gast)


Lesenswert?

Danke auch Ulrich,

habe ich jetzt erst gesehen.

f(our) ist as DOUBLE dimensioniert.
Da bei 10, 100, 1000, 10000 usw. eh glatt auch egal.
Die Berechnung ist auch als Ursache ausgeschlossen,
die Werte habe ich auch "hard wired" im DDS gehabt.

Ich frage mich eher: Hat es keiner gemerkt ?
ODER
Was mache ich falsch ?


Grüße Werner.

von Karl H. (kbuchegg)


Lesenswert?

Ich überleg gerade, ob das hier

  .org 0x080

korrekt ist.
Ich denke: ja. weil das ja eine Wort-Adresse ist (wegen CSEG)

von Werner (Gast)


Lesenswert?

0x100 / 2

Wollte weniger Platz verschenken.
Die Bytes kommen brav in der richtigen Reihenfolge.
( AVR Studio , Debugger )

Das D/A Signal ist auch OK.
Ausser dieser Jitter.
Ich vermute die Schwankungen in der Periodendauer addieren sich auf,
das wird mit höherer Frequenz immer wichtiger?

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:
> 0x100 / 2
>
> Wollte weniger Platz verschenken.
> Die Bytes kommen brav in der richtigen Reihenfolge.
> ( AVR Studio , Debugger )

Müsste alles stimmen

> Das D/A Signal ist auch OK.
> Ausser dieser Jitter.

macht mich stutzig.
Bei einem Quarz solltest du ja eigentlich keinen (oder fast keinen) 
Jitter haben.

> Ich vermute die Schwankungen in der Periodendauer addieren sich auf,
> das wird mit höherer Frequenz immer wichtiger?

Seh ich auch so.
Nur wo kommen die Schwankungen her?

So wie ich das sehe, gibt es 4 Möglichkeiten

* unabsichtliche Reset zwischendurch
* Interrupts
* Watchdog
* Quarz instabil

mehr fällt mir zu dem Thema nicht ein.

von Werner (Gast)


Lesenswert?

der Jitter ist wohl unvermeidlich.

Auf dem Phasenrad werden mehr und mehr Werte der (D/A) Wertetabelle
übersprungen. Umso mehr dest höher die Frequenz.

Mit einem DigiScope sieht das lustig aus.
( Wenn dessen Abtastrate grad passt )
Auf dem analogen scheinen die Flanken zu zittern.

Werner

Hat den jeman so einen Jesper und kann mal messen ?

von Karl H. (kbuchegg)


Lesenswert?

Ich hab leider kein Messequipment, sonst hätt ich das schon längst in 
einen µC gebrannt :-)

Muss mir doch mal ein Oszi kaufen.

> Auf dem Phasenrad werden mehr und mehr Werte der (D/A)
> Wertetabelle übersprungen. Umso mehr dest höher die Frequenz.

Drum ja auch der Vorschlag mit 00 00 01.
Da müsste das Signal stehen wie eine 1, weil genau jeder einzelne Wert 
aus der Tabelle ausgegeben wird, ohne irgendwelches Überspringen. Die 
Kurve wird zwar nicht genau ein Sinus sein, aber alle Sinuse müssten 
absolut deckungsgleich sein. Softwareseitig kann es da keinen Jitter 
mehr geben.

von Karl H. (kbuchegg)


Lesenswert?

Das lässt mir keine Ruhe.

Kannst du unabsichtliche Reset zwischendurch ausschliessen?

von Ulrich (Gast)


Lesenswert?

Das mit dem Jitter kenne ich. Das sollte so ab etwa 20 kHz auch dem 
analogen Skope gut sichtbar werden, wenn man sich da nur das MSB 
anschaut. Sonst hängt es von der Qualität des Filters hinter dem AD ab.
Die Schwankungen addieren sich aber gerade nicht auf beim DDS, sondern 
heben sich in der Summe sogar mehr auf.

Vielleicht ist es ja doch die Frequenzmessung, die nicht so gut 
funktioniert. Bei viel Jitter kann das mit einer einzelnen Periode schon 
daneben gehen.

von Werner (Gast)


Lesenswert?

16er und 8er laufen am selben Netzteil.
Auch wenn sie TWI getrennt sind.
Der 16er läuft durch.

Nach / während dem RESET wären die Ausgänge des R2R  PORTs tristate
( Eingang )
Das würde man im Signal sehen..
R2R an 8 High Z INPUTS ...

Nichts zu sehen.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Keiner mehr eine Idee ?
Dann kommt das "Projekt" in die Tonne.
Gibt es etwas anderes "Simples" ?
Funktionsgenerator bis 100 kHz ?

> das müsste bei deiner Quarzfrequenz glatte 6400 Hz ergeben.

> Wieviel misst du tatsächlich?


TANDAR TF 200 6336,x Hz        mit nun 100 Sekunden Torzeit ( gähn... )
VC1008        6350 +/- 10Hz  ( aus Periode berechnet )

und ein Speci... der sonst zuverlässig geht.

Grüße Werner

von Ulrich (Gast)


Lesenswert?

Wenn noch nicht probiert, mal zum Test alle Interrupts sperren (SEI 
raus) und damit man einen ggf. auftretende Reset (z.B. über Watchdog) 
auch wirklich bemerkt am Start eine Warteschleife rein. Beim Code oben 
ist die Pause ggf. doch etwas kurz und könnte übersehen werden.


Bei der Takterzeugung wäre ggf. zu überlegen es mit einem anderen Quarz 
zu probieren. Oder zum Test rein für den Quarz zusätzlich ein PWM Signal 
auszugeben. Mit dem dem Spci müsste man die Quarzfrequenz per Antenne ja 
auch finden können. Ein Quarzoszillotor läßt sich ggf. auch von außen 
stören wenn man Pech hat und der Aufbau schlecht ist. Da die Abweichung 
so groß ist, wäre es auch einen versuch wert das ganze mal mit dem 
internen RC Takt laufen zu lassen um den Fehler einzugrenzen - da kann 
weniger schief gehen.

von W.S. (Gast)


Lesenswert?

Werner schrieb:
> Gibt es etwas anderes "Simples" ?
> Funktionsgenerator bis 100 kHz ?

Na klar gibt's sowas: AD9833, DDS mit max. 25 MHz Takt, Sinus, Dreieck, 
Rechteck - Sinus mit Filter bis ca. 10 MHz, Dreieck und Rechteck bis 100 
kHz zu gebrauchen.

Oder : ein CPLD oder kleines FPGA und alles selber machen. Ist im Kern 
eigentlich ganz einfach, bloß die Sinus-Approximation macht Aufwand.

W.S.

von Werner (Gast)


Lesenswert?

Die Interrupts hatte ich gestern schon gesperrt.

> SEI ist raus

Der Speci ist ein Soundkarten Device ( empfehlenswert, Freeware für
private Anwender ) geht aber nur bis 20 kHz.
Wenn jemand der keine Messgeräte hat und einen Jesper gebaut hat und mal 
mit Scope 1.40 nachmessen möchte / könnte

Das "Dings" Multi ist im Auto.
Es hat aber genauso wie die drei Anderen gemessen.
Für mich ist erst 'mal Fakt : Jespers Frequenz stimmt nicht.

Die Quarzfrequenz stimmt, ein TS 850 lügt nicht :0)
10 und mehr % kann ein Quarz garnicht abweichen...

Im 8er habe ich heute einen warte TWI eingebaut.
Ich muss nach dem RESET nun eine START Condition senden, damit es 
losgeht.
Bei einem RESET alleine läuft nix.
Wurde nie ein zweites Mal erwartet, hat nie geresetet.

?

von Helmut L. (helmi1)


Lesenswert?

Mal nur so gefragt. Du sagst das dein Signal jittert. Hast du auch ein 
Tiefpassfilter hinter dem DAC. Ohne dieses Filter sieht das Signal wie 
Stacheldraht aus. Eventuell könnte dein Messfehler daher kommen.

von Werner (Gast)


Lesenswert?

am Ausgang des R2R geht es 1K 220pF 1k und dann ein OPAmp * 1.

AD648 , bei 100 kHz ist die Amplitude bereits 0,7 * 5 Volt (ss)
Ich will da auch garnichts investieren, wenn das am Ende sowieso
nicht funzt.

Die Frage impliziert einen Messfehler ?
Ich will gerne folgen
( wenn mir jemand sagt ich messe xy Hz und das ist OK so )

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe den "Lattenzaun" vor dem Tiefpass photographiert.
Dahinter sieht es nicht anders aus.

Die 30 + 30pF ( Scope und Zähler in parallel ) reichen eigentlich schon 
?

Scope ein 40Mhz (? oder waren es 20) HAMEG.

von Helmut L. (helmi1)


Lesenswert?

Wenn du 6400Hz ausgibst dann schalte mal einen Tiefpass mit einer 
Grenzfrequenz von ca. 10KHz dahinter. Das beseitigt schon mal 
hochfrequente Störungen. Es können sonst irgendwelche Spikes auf deinem 
Signal den Zähler schon mal durcheinander bringen.

Werner schrieb:
> am Ausgang des R2R geht es 1K 220pF 1k und dann ein OPAmp * 1.

Das ist aber sehr geizig gefiltert. Bei mir hängt hinter dem DAC immer 
ein Tiefpass von mindestens 5 oder 7 Ordnung.

Was du nochmal machen könntest:

Lege deine DDS Routine mal in einen Timerinterrupt. So ist schon mal 
dafuer gesorgt das unabhängig vom Programm immer die selbe Samplerate da 
ist.

Du kannst dort auch mal einen Impuls auf einem Portpin ausgeben und den 
mal nachmessen ob das mit der Taktrate hinkommt.

Normalerweise wenn man alles richtig gemacht hat sollte das schon 
funktionieren.

So Schluss für heute.

von Werner (Gast)


Lesenswert?

Yoh Helmi,

ich geh dann auch.

Den Zähler würden Spikes mehr zählen lassen , mir fehlt aber was...
Die FFT von Scope 1.40 findet genau die gleiche Frequenz wie der Zähler.
Die Periodenmessung des Voltcraft liegt 10 Hz höher aber auch 50 unter 
Soll
Das "Multidings" ( keine Ahnung wie es des macht ) liegt mainstream
Soviele Methoden können nicht irren ?

Mich wundert, dass niemand sagt:
" Ich habe das Ding gebaut und messe 6400Hz "

Gute Nacht

von Ulrich (Gast)


Lesenswert?

Ich habe einen ähnlichen DDS Generator (mit Tiny2313), mit 10 MHz Quarz 
und einem Wert zum zu addieren von 13653 sollten da 904,20 Hz 
rauskommen. Gemessen habe ich 902,04 Hz. Wobei ich mir mit der 
Kalibrierung des Frequenzzählers aber auch nicht ganz sicher bin, und es 
ist relativ kalt (< 10 C). Die Abweichung ist irgendwie auch etwas 
größer als erwartet, aber noch nicht so groß wie hier. Die Frequenz ist 
auch relativ stabil (bei ca. 0,1 s Torzeit am Reziprokzähler).

Den Quarz habe ich auch einmal gegen ein anderes Exemplar ausgetauscht, 
ohne nennenswerte Änderung.

von Werner (Gast)


Lesenswert?

Hallo Ulrich,

ich war doch noch hier :0)
Bei 1 kHz ist die Abweichung bei mir kaum messbar
( das dauert 100 Sekunden sind meine längste Torzeit )
Bei 5 kHz und darüber steigt der Fehler nicht linear.
Die Fromel ist falsch ... ?
Es gibt keine lineare Korrektur ... ?
Ich weiss es nicht ...

Grüße
Werner

von Karl H. (kbuchegg)


Lesenswert?

> Für mich ist erst 'mal Fakt : Jespers Frequenz stimmt nicht.

Das muss aber irgendwas bei dir Spezielles sein.

Mit dem Programm ist nachvollziehbar, welche Frequenz bei einer 
bestimmten Taktfrequenz und Teiler rauskommen muss. Wenn das nicht 
stimmen würde, dann würde überhaupt kein Timing mit einem µC 
realisierbar sein. Denn deine Abweichungen sind relativ groß und vor 
allen Dingen nicht konstant. Und das ist das, was mich am meisten 
verblüfft. Wenn du wenigstens konstant immer 10% Abweichung hättest.

Also so pauschal würde ich das nicht sagen, dass der Ansatz 
grundsätzlich mies ist.

von Werner (Gast)


Lesenswert?

Tja,

letzter Versuch ....

Ich habe die Oberwellen des DDS abgehört:
f(soll) 10 kHz gemessen 9,843 kHz.
Auf 985 kHz ist ein Signal.
1000 kHz mausetot. 10 kHz kommt im Ausgangssignal des DDS nicht vor.

Scope 1.40 hat auch einen Funktionsgenerator.
f(soll) = 6400 Hz, gemessen mit Tandar und Voltcraft 6400,0x Hz

Grüße Werner.

von Joe G. (feinmechaniker) Benutzerseite


Lesenswert?

Hallo Werner,

ich habe das vor einigen Jahren auch mal aufgebaut, geht heute noch ohne 
Fehler. Um eine exakte Frequenz zu bekommen, hatte ich die Schleife auf 
10 Befehle erweitert. Quarz war 4.194304 MHz

; f = deltaPhase * fClock/2^24
; fClock is in this case the CPU clock divided by the
; umber of cycles to output the data ( 10 cycles )
; f = r24/r25/r26 * (4194304/10)/16777216
; f = r24/r25/r26 * 0.025

LOOP1:
    add    r28,r24      ; 1
    adc    r29,r25      ; 1
    adc    r30,r26      ; 1
    lpm          ; 3
    out    PORTB,r0    ; 1
    nop          ; 1
    rjmp          LOOP1      ; 2 => 10 cycles

von Helmut L. (helmi1)


Lesenswert?

Hallo Werner,

so ich habe deinen Code mal ausprobiert.

Mit einem ATMega88 und einem 16MHz (habe keinen 14.7456MHz da) Quarz 
habe ich mal versucht eine Frequenz von 6400Hz zu erzeugen.

    ; setup adder registers

    ldi   r24,0xed    ; setup adder value
    ldi   r25,0xeb    ; to 6400 Hz
    ldi   r26,0x00    ;

Der Updatewert ist dann 60397.

Step = (fo  9  2^24)/fref

fo = Ausgabefrequenz
fref = Oszillatorfrequenz

Und die gemessene Frequenz stimmt exakt mit der berechneten ueberein.
Gemessen mit einem HP5334B Frequenzzaehler.

von Michael (Gast)


Lesenswert?

Werner schrieb:
> Ich habe die Oberwellen des DDS abgehört:

Warum hörst du dir nicht die genaue Quarzfrequenz an und guckst dann 
damit im Simulator von AVR-Studio mal zusammen mit der Stopuhrfunktion 
den Phasengenerator des DDS an?

von Werner (Gast)


Lesenswert?

Mann, Mann, Mann...

Das hat mir keine Ruhe gelassen.
Nun melden auch noch zwei defintiv ein OK.

Ich habe nun festgestellt, dass ein Mega8 von dreien RICHTIG funzt ???
Bei diesem ist das abgehörte 14 Mhz Signal "glockenklar".
Die beiden anderen haben Rascheln / Prasseln auf dem 14 Mhz Signal.
Das hat mich zuerst nicht gestört, digital halt.
Zwei defekt?

Ne, verfused nochmal %/$/&"$)
Der gute hatte "Ext. Crystal High Freq. Start Up 16K ..."
Die schlechten hatten "Ext. Crystal Low Freq. Start Up 1k ..."
drinne.
"CKOPT 1" hatten alle an.

Auch der Mega16 funzt, ich habe ihn das 'mal machen lassen.
Ohne ein R2R dran messe ich am MSB eben auch grad die RICHTIGE Frequenz 
:0)

Sorry, aber ohne Eure postive Meldung hätte ich nun einfach Jesper 
verteufelt.

Dinge gibts, die ...

Danke Werner

von Werner (Gast)


Lesenswert?

Nachtrag,

ich hatte 'ne Menge rumgemacht.
So habe ich die Loop nun auf 8 Zyklen gedrückt ( Tabellenkopie im SRAM )
Kann man schön "on the fly" austauschen und spart einen Takt.

Die 8 Takte Version ist ruhiger, geht höher.
Und ein Zufallsprodukt, das ich nicht erklären kann:

LOOP1:
    adc    r28,r24      ; 1
    adc    r29,r25      ; 1
    adc    r30,r26      ; 1
    ld      r0,z      ; 2
    out    PORTD,r0    ; 1
    rjmp  LOOP1      ; 2 => 8 cycles

Wenn ich den Carry in r28 mitnehme ist der Jitter kaum mehr wahrnehmbar.
?
Ok die Frequenz ist so 3-4 Hz zu hoch bei 50 kHz, aber es sieht besser 
aus.

Grüße Werner

von Joe G. (feinmechaniker) Benutzerseite


Lesenswert?

Werner schrieb:
> Ne, verfused nochmal %/$/&"$)

Das ist doch auch der Sinn dieses Forums. Wir haben alle wieder was 
gelernt ;-)

Werner schrieb:
> Die 8 Takte Version ist ruhiger, geht höher.

Gute Idee!

von Helmut L. (helmi1)


Lesenswert?

Passt den deine 50KHz ganzzahlig in deinen Takt rein?
Wenn nicht treten Spurios Frequenzen auf im Spektrum.
Dann mischt sich dein Takt (fclk / 8) mit deiner Ausgabefrequenz und 
diese Anteile liegen dann teilweise unter 50KHz. Auch solltes du die DDS 
nicht ohne Filter betreiben.

von Karl H. (kbuchegg)


Lesenswert?

Werner schrieb:

> Ne, verfused nochmal %/$/&"$)
> Der gute hatte "Ext. Crystal High Freq. Start Up 16K ..."
> Die schlechten hatten "Ext. Crystal Low Freq. Start Up 1k ..."
> drinne.
> "CKOPT 1" hatten alle an.

Jetzt weiß ich endlich, was die Konsequenzen eines derartigen Fehlers 
sind. So gesehen, muss man dir für die Hartnäckigkeit dankbar sein :-)

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Du sollst nicht am Jesper zweifeln ...

Die 7,3Hz bin ich selbst schuld ( adc r28,r24 )
Dann steht der Sinus aber wie eine Eins.

Schönen Sonntag noch.

von Joe G. (feinmechaniker) Benutzerseite


Lesenswert?

Was für einen DAC hast du eigentlich am 8-Bit Port oder nur R2R?

von Werner (Gast)


Lesenswert?

Hi,

R2R 10kOhm-20kOhm. ( diskret, 0,1%er )
Simple.
Bei dem hohen Innenwiderstand der Quelle erübrigt sich das Filtern.
Scope und Zähler sind C genug ?

Gruß Werner

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Bei dem hohen Innenwiderstand der Quelle erübrigt sich das Filtern.
> Scope und Zähler sind C genug ?

Noe.

Innenwiderstand des R2R Netzwerkes = 10KOhm. Eingangskapazitaet von 
deinem Skope rund 15pF.

fg = 1/(2 x PI x R x C) = 1.06 MHz

fref =  Fq / 9 oder 8 = 1.55MHz rund

der Tiefpass sollte bei rund 40 % vom fref liegen also bei 600kHz.
Und danach steil abfallen. Das geht nur mit einem Tiefpass hoehere 
Ordnung (4..5. Ordnung).

von Werner (Gast)


Lesenswert?

Gestern stand ich noch am Abgrund, heute bin ich einen Schritt weiter...

Nachdem das Ding nicht in die Tonne geht und noch PINs unbelegt sind,
werde ich einen frequenz- und modusabhängig umschaltbaren Tiefpass 
dranhängen.
Ich denke einfach Cs zu und abschalten ( automatisch )

Die dritte Oberwelle ist z.B. nur magere -12dB.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Nachdem das Ding nicht in die Tonne geht und noch PINs unbelegt sind,
> werde ich einen frequenz- und modusabhängig umschaltbaren Tiefpass
> dranhängen.
> Ich denke einfach Cs zu und abschalten ( automatisch )
>

Brauchst du nicht. Tiefpass bei 40% der Clockrate genuegt.

> Die dritte Oberwelle ist z.B. nur magere -12dB.

Womit gemessen? Es geht auch nicht darum die Oberwelle deines Signales 
zu daempfen sondern das die Sampleclock unterdrueckt wird und die liegt 
bei dir:

fq/8 oder fq/9   also bei 14MHz / 8 = 1.75MHz oder 1.55Mhz wenn man von 
einem 14MHz Quarz ausgeht.

Mit dieser Frequenz tastet dein System ab. Das heist die ganzen 
Kurvenstueckchen sind mit dieser Frequenz aneinandergereiht. Und diese 
Frequenz muss aus dem Signal raus. Das wird in aller Regel mit einem 
mehrpoligen Cauerfilter gemacht. Wobei man noch clevererweise die erste 
Daempfungsstelle des Filters auf die Clockfrequenz legt.

von Werner (Gast)


Lesenswert?

es sind 8 Takte, 1,75 MHz könnte man sehr effektiv mit einem LC 
Sperrkreis
unterdrücken ?
"Rotes" Miniaturfilter aus'm AM-Radio. Liegen hier massenweise rum.

Der Klirrfaktor ist recht hoch.
Ich habe mit einer Soundkartensoftware nachgesehen.
Oberwellen sind schon ein Thema, bei niedrigen Ausgangsfrequenzen.
Das Ausgangssignal eines Soundkartenfunktionsgenerators bringt es bei 
der
gleichen Messsoftware auf -45dB !
Das endet stets bei 20kHz, also habe ich bei 1kHz Ausgangsfrequenz
"gemessen".

von Ulrich (Gast)


Lesenswert?

Der Filter ist nicht wegen den Oberwellen des Signals da, sondern wegen 
der HF Störungen im Bereich oberhalb der Nyquistgrenze. Je besser man 
den Filter hinbekommt, desto höher kann man mit der nutzbaren 
Signalfrequenz gehen. Mit einem einfachen passiben Filer 1. oder 2. 
Ordnung sollte die Grenzfrequenz eher deutlich niedriger liegen als 40% 
von Fs.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> es sind 8 Takte, 1,75 MHz könnte man sehr effektiv mit einem LC
> Sperrkreis
> unterdrücken ?
> "Rotes" Miniaturfilter aus'm AM-Radio. Liegen hier massenweise rum.
>

Hmm.  Die bleiben aber nicht da stehen. Ausserdem unterdrueckst du damit 
nur eine Frequenz. Nimm besser einem Tiefpass das macht der Rest der 
Welt auch so.

> Der Klirrfaktor ist recht hoch.

Das kommt von den nur 8 Bits. Mehr Amplitudenaufloesung gibt ein 
saueberes Signal.

> Ich habe mit einer Soundkartensoftware nachgesehen.
> Oberwellen sind schon ein Thema, bei niedrigen Ausgangsfrequenzen.
> Das Ausgangssignal eines Soundkartenfunktionsgenerators bringt es bei
> der
> gleichen Messsoftware auf -45dB !

Die hat auch mehr Bits zu verfuegung.

Du wirst mit sowas aber keinen Klirrarmen Generator hinbekommen fuer 
Klirrfaktormessungen.

von Christoph H. (mc-entwickler)


Lesenswert?

>Womit gemessen? Es geht auch nicht darum die Oberwelle deines Signales
>zu daempfen sondern das die Sampleclock unterdrueckt wird und die liegt
>bei dir:

Ich gebe zu Bedenken: Aus einem Rechtecksignal kann man mit Hilfe eines 
Tiefpass-Filters auch ein Sinus Signal erzeugen. Der Filter muss einfach 
nur die Oberwellen des Rechtecks abschneiden. Die Samplerate ist daher 
nicht das alleinige Argument. Das Quantisierungsrauschen des DAC kann 
nämlich durch das Filter deutlich reduziert werden.

von Ulrich (Gast)


Lesenswert?

Bei der erreichten sampling Frequenz kann man schon auch LC filter für 
den Tiefpass nutzen, so wie man es sonst bei den höheren Frequenzen mit 
richtugen DDS-ICs macht. Bei der Schleife kann man übrigens noch 1 
Zyklus einsparen, indem in einem Durchlauf 2 Werte ausgegeben werden, 
auch mit dem richtigen zeitlichen Abstand - so werden die 2 Zyklen für 
den RJMP auf 2 Werte verteilt. Auf 10 Bytes mehr Code kommt es in der 
Regel ja nicht an.

Für den Klirfaktor ist neben der Begrenzung der Auflösung auch die etwas 
kurze Tabelle und die Qualität der DA Wandlung verantwortlich. Dazu 
kommt dann ggf.auch noch die Verstärkung dahinter. Es sollte aber 
eigentlich schon für etwa -40 dB für die Oberwellen reichen.

von Werner (Gast)


Lesenswert?

Ich war 'mal essen.

Christoph hat wohl recht.
Alle haben recht.

Die Samplingfrequenz bleibt doch eigentlich konstant.
Die bekommt man dann sicher gut weg mit einem, zwei LC Sperrkreisen.
Wenn sie es überhaupt bis zum Ausgang schafft.
Der folgende OPAmp weiss nichts davon, macht bei 150-200kHz schlapp.

Was übrig bleibt hat aber unter besten Vorraussetzungen wegen der 8 Bit
eine geringe Qualität.
Dem kann man schon mit Tiefpässen nahe f(out) nachhelfen.

Die Idee den RJMP zu rationalisieren ... yoh man könnte 'mal.
So eine Art lange Eimerkette...Code kostet ja nix. Copy und Paste.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Die bekommt man dann sicher gut weg mit einem, zwei LC Sperrkreisen.

Nicht ganz. Deine Ausgangsfrequenz mischt sich mit deiner 
Samplingfrequenz.
Und das gibt dann Produkte in Abstand +-fout an der Samplingfrequenz.
Das Spektrum einer DDS ist nicht ganz einfach zu berechnen.

> Wenn sie es überhaupt bis zum Ausgang schafft.
> Der folgende OPAmp weiss nichts davon, macht bei 150-200kHz schlapp.

Man sollte den OP nicht damit belasten sondern vorher filtern.

von Ulrich (Gast)


Lesenswert?

Den Code noch länger zu machen als 2 Samples pro Schleife bingt nur 
etwas wenn man in der Schleife noch etwas zusätzliches zu tun hat. Die 2 
Zyklen für die Schleife (der Befehl RJUMP) lässt sich halt ganzzahling 
nur auf 2 Teilen. Wenn wenn man weiter aufteilt, bekommt man eine 
ungleiche Zeit zwischen den Samples, und der Schritt von 1 Zyklus auf 
dann vielleicht 1/2 oder 1/4 ist auch nicht mehr so groß.

Man könnte das mehr an Geschwindigkeit ggf. auch nutzen um die Tabelle 
zu verlängern, auf z.B. 512 oder 1024 Einträge. Dafür braucht es dann 
eine passende Lage der Tabelle im Speicher, und ein eine Verknüpfung der 
Adresse per ORI oder ANDI, je nach Adresse.

Wenn der OPAmp schon bei 100 kHz schlapp macht, könnte der für den hohen 
Klirrfaktor verantwortlich sein. Es wird doch nicht etwa ein LM358 sein 
? Nicht umsonst setzt man bei Audioanwendungen für einen geringen Klirr 
teils extra schnelle OPs ein. Die weiter oben genannten Cauerfilter 
haben übrigens schon so etwas wie einen Saugkreis etwa bei der 
Abtastfrequenz. Als rein passiver LC-Filter ist der Aufbau auch nicht so 
unmöglich kompliziert, wenn man die Werte hat und einigermaßen genaue 
Induktivitäten bekommt.

Wenn man es wirklich besser haben will, würde ich aber einen fertigen 
DDS Chip wie AD9833 vorschlagen. Die kosten auch nicht mehr so viel, und 
man hat gleich 10 Bit DA Wandlung und eine rund 10 mal höhere 
Abtastrate.

von Werner (Gast)


Lesenswert?

Hi,
ich habe das übertrieben.
Ich habe 255 LOOPs hintereinander Kopiert :0)
Und 6 Takte angenommen, der Fehler ist ja nur 6/2/255.
Man sieht den "Betrug" aber.
Je nach Rücksprungadresse ein Phasen oder Amplitudenfehler...
( Bei >= 20 kHz )

Ich messen eigentlich direkt am R2R.
Dahinter gibt es noch 1kOhm 220pF 1kOhm und AD648.
So wie es ist macht das keinen Unterschied ob vor und nach dem OP.

Das LC Filter ist das geringste Problem.
DDS > Empfänger
Spule ist abgleichbar ( Rote Spule AM-Radio ) C = 39pF
Abgleich auf geringstes Signal.
Nur das Signal ist schon so schwach, kaum nachweisbar.
Wenige zig/µV. Es schafft es einfach nicht aus dem R2R Wirrwarr
und durch die Leitungskapazitäten.

Ich kenne diese AD, nur es ist 'mal schön auszuprobieren / auszureizen
wie das mit einer Hand voll Schweinefutter geht.

Zwei Additionen in einer LOOP bei korrektem timing, wie machst Du das ?

von Werner (Gast)


Lesenswert?

Hallo nochmal,

ich antworte mir grad selbst:

    ; clear accumulator
    clr     r28
    clr     r29
    clr     r30
    ; Initialize Z pointer
    ldi     ZH, 0x01


    add    r28,r24      ; 1
LOOP1:adc  r29,r25      ; 1
    adc    r30,r26      ; 1
    ld     r0,z         ; 2
    out    PORTD,r0     ; 1
    adc    r28,r24      ; 1
    adc    r29,r25      ; 1
    adc    r30,r26      ; 1
    ld     r0,z         ; 2
    add    r28,r24      ; 1 timeing
    out    PORTD,r0     ; 1
    rjmp   LOOP1        ; 14 / 2 = 7 cycles

Der DA wird alle 7 Takte aktuallisiert ( out PORTD,r0 ).
Nun sind und waren die Tabellen zu grob
Wie oben vorgeschlagen werde ich den Zeitgewinn in eine längere Tabelle
investieren. Z.Zt. kommen nicht einmal alle 256 Werte vor, weniger als
8 Bit Auflösung :O(.

mfg Werner

von Ulrich (Gast)


Lesenswert?

Bei einer 256 Elemente langen Tabelle kommen halt nicht alle Werte vor. 
Bevor man die Auflösung des ADs noch erhöht, kann man besser die Tabelle 
länger machen - braucht dann aber eine paar mehr Zyklen für die 
Schleife.

Wirklich profitieren von der längeren Tabelle werden vor allem die 
niedrigeren Frequenzen. Wenn man mag könnte man dafür je nach Frequenz 
umschalten:
Niedrige Frequenzen (etwa unter 5-10 kHz) mit einer 1024 Einträge langen 
Tabelle aus dem Flash, und darüber wie oben die kurze Tabelle aus dem 
RAM. Nur die Umrechnung der Frequenzen wird etwas lästing, weil man 2 
verschiedene Schrittweiten bekommt.

von Werner (Gast)


Lesenswert?

der Ulrich der kann's.

Grüße Werner

von eProfi (Gast)


Lesenswert?

Respekt, Ulrich!
Was auf jeden Fall nutzt: die Quarzfrequenz erhöhen. Bei sauberem Aufbau 
kann man die AVRs ja ordentlich übertakten. 24 MHz gehen so gut wie 
immer mit einem -20er. Dann wird der Addierwert kleiner, der Jitter 
weniger und der Sinus schöner.

Interessant wirds, wenn man zwei- oder mehrstimmig ausgibt, wie es oft 
für Dialtone gemacht wird. Wann man es ganz richtig machen will, nimmt 
man zwei Sinustabellen, da die beiden Töne nicht exakt gleich laut sein 
sollen.
Beitrag "Re: direkte digitale Synthese (DDS, NCO)"

von Werner (Gast)


Lesenswert?

Hat jemand eine 512 Byte lange 8 Bit Sinustabelle parat ?

von Wolfgang (Gast)


Lesenswert?

Werner schrieb:
> Hat jemand eine 512 Byte lange 8 Bit Sinustabelle parat ?

Ist deine Tabellenkalkulation kaputt?

von Werner (Gast)


Lesenswert?

Ne, nur faul ...
sollte auch gleich in den Assembler passen :0)

von Werner (Gast)


Lesenswert?

Ulrich wird es haben,
der hat den MEGA Jesper schon fertig :O))

da geht noch was ...

von Willi (Gast)


Lesenswert?

Ulrich schrieb:
> Wirklich profitieren von der längeren Tabelle werden vor allem die
> niedrigeren Frequenzen.

Veto!
Sieht man sich die bisherige sin-Tabelle an, so besteht der pos. 
Scheitelwert aus einigen 0xff und der neg. Scheitel aus mehreren 0x00. 
Es müßte zunächst für eine höhere Auflösung des DAC gesorgt werden, 
bevor eine längere Tabelle die NF verbessert.
Nur wäre damit die schnelle Schleife futsch, da pro Schritt zwei Byte 
ausgegeben werden müßten. Dann doch besser zum AD.... greifen.

von Werner (Gast)


Lesenswert?

Das lohnt schon ... trotz Veto
Es kommt nur die halbe Frequenz raus ( Tabelle ist doppelt lang )
aber schon fast die doppelte Auflösung.
Frequenz hatten wir ja schon satt.

Die 512 * 8 Tabelle wird einmalig aus dem FLASH in das SRAMN kopiert.
$0200 - $3FF

LoopMode:
    cpi Mode,2
    brne ABC
    ldi ZH, high(sine512x8 *2) ; Initialize Z pointer
    ldi ZL, low(sine512x8 *2)
    ldi YH,2
    clr YL
sine512:
    lpm r0,z+
    st y+,r0
    cpi YH,3
    brne sine512
    cpi YL,255
    brne sine512

ABC:

Die LOOP braucht dann 10 Takte, einen mehr als Jesper...
Man kann das dann ausdehnen auf 1024 im Flash etc. bei 10 Takten pro.
Ich löte mir erst 'mal einen 22 Mhz Quarz ein. Evtl. mit 'nem 48-88er.
Tabellen für Sinus und Dreieck... die andern "on the fly"

    ; clear accumulator
    clr     r1       ; rent a zero, there is no ADD CARRY ?
    clr     r28
    clr     r29
    clr     r30

; main loop
;
;  r28,r29,r30 is the phase accumulator
;  r24,r25,r26 is the adder value determining frequency

    add     r28,r24
LOOP1:adc   r29,r25  ; 1
    adc     r30,r26  ; 1
    adc     r31,r1   ; 1 add a zero and carry
    andi    r31,3    ; 1 mask bit 0..1
    ori     r31,2    ; 1 force two
    ld      r0,z     ; 2
    out     PORTD,r0 ; 1
    add     r28,r24  ; 1
    adc     r29,r25  ; 1
    adc     r30,r26  ; 1
    adc     r31,r1   ; 1 add a zero and carry
    andi    r31,3    ; 1 mask bit 0..1
    ori     r31,2    ; 1 force two
    ld      r0,z     ; 2
    add     r28,r24  ; 1 timeing
    out     PORTD,r0 ; 1
    rjmp    LOOP1    ; 2 => 20 / 2 = 10 cycles


;***********************************************************************
; data tables
;***********************************************************************

  ; force table to begin at 256 byte boundary

  .org 0x100

sine512x8:    ; 512 step sinewave table
.db 128,129,131,132,134,135,137,138,140,142,143,145,146,148,149,151
.db 152,154,156,157,159,160,162,163,165,166,168,169,171,172,174,175
.db 176,178,179,181,182,184,185,186,188,189,191,192,193,195,196,197
.db 199,200,201,202,204,205,206,207,209,210,211,212,213,215,216,217
.db 218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233
.db 234,235,236,236,237,238,239,240,240,241,242,243,243,244,245,245
.db 246,246,247,247,248,249,249,250,250,250,251,251,252,252,252,253
.db 253,253,254,254,254,254,255,255,255,255,255,255,255,255,255,255
.db 255,255,255,255,255,255,255,255,255,255,255,254,254,254,254,253
.db 253,253,252,252,252,251,251,250,250,250,249,249,248,247,247,246
.db 246,245,245,244,243,243,242,241,240,240,239,238,237,236,236,235
.db 234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219
.db 218,217,216,215,213,212,211,210,209,207,206,205,204,202,201,200
.db 199,197,196,195,193,192,191,189,188,186,185,184,182,181,179,178
.db 176,175,174,172,171,169,168,166,165,163,162,160,159,157,156,154
.db 152,151,149,148,146,145,143,142,140,138,137,135,134,132,131,129
.db 128,126,124,123,121,120,118,117,115,113,112,110,109,107,106,104
.db 103,101,99,98,96,95,93,92,90,89,87,86,84,83,81,80
.db 79,77,76,74,73,71,70,69,67,66,64,63,62,60,59,58
.db 56,55,54,53,51,50,49,48,46,45,44,43,42,40,39,38
.db 37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22
.db 21,20,19,19,18,17,16,15,15,14,13,12,12,11,10,10
.db 9,9,8,8,7,6,6,5,5,5,4,4,3,3,3,2
.db 2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0
.db 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2
.db 2,2,3,3,3,4,4,5,5,5,6,6,7,8,8,9
.db 9,10,10,11,12,12,13,14,15,15,16,17,18,19,19,20
.db 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
.db 37,38,39,40,42,43,44,45,46,48,49,50,51,53,54,55
.db 56,58,59,60,62,63,64,66,67,69,70,71,73,74,76,77
.db 79,80,81,83,84,86,87,89,90,92,93,95,96,98,99,101
.db 103,104,106,107,109,110,112,113,115,117,118,120,121,123,124,126

Grüße Werner

von Ulrich (Gast)


Lesenswert?

Die längere Tabelle kann man ggf. auch gleich im Flash lassen: bei 
passender Start-Adresse (z.B. $0800) reicht zum maskieren der Bit ein 
Befehl aus. Das was man an mehr Zeit für den Zugriff auf das Flash mehr 
braucht, spart man hier wieder ein. Auch wenn es nicht mehr viel bringt 
könnte man da auch eine 1024 Einträge lange Tabelle nutzen - braucht 
auch nicht länger, nur mehr Platz in Flash. Wenn es sein muss, könnte 
man mit der 512 Einträge langen Tabelle dann noch einen schritt weiter 
gehen: Man hat die Tablle 2 mal im Flash, und macht das Maskieren nur 
jedes 2. mal. Als 4-fach entrollte Schleife könnte man damit noch einen 
Zyklus schneller werden als mit der Tabelle im RAM.

So abwegig ist das mit der etwas längeren Tabelle nicht: der AD9833 
nutzt z.B. auch 12 Adressleitung bei einem 10 Bit DA Wandler.

von Willi (Gast)


Lesenswert?

Vielleicht rechnet jemand einmal durch, wo das Optimum für DAC-Auflösung 
und Tabellengröße liegt.
Eine andere Lösung zur NF-Signalverbesserung wäre, nur eine positve 
Halbwelle mit 8-Bit Auflösung und 256er Tabelle auszugeben und 
alternierend einen Puffer-OPV zwischen +1 und -1 Verstärkung 
umzuschalten. Bei sauberer Ausführung käme man dann auf 9-Bit Auflösung 
mit 512 Schritten.
Wenn es zu langsam werden sollte, einfach den AVR mit 100% übertakten.

Am Ende der Experimente nimmt man dann den AD9833 :-)

von Werner (Gast)


Lesenswert?

Umschalten... für Sinus OK.
Sägezahn und Dreieck ?

Das neunte Bit ist ja schon da, der Carry als MSB.
Bis jetzt ging das "pimp my Jesper" ohne Lötkolben.
Noch ein Takt und out PortX und der Carry wird Bit9 ? 10,11,12
noch 2,4,6 Widerstände...
Die Tabelle sieht dann nätürlich anders aus
0 bis 255 und 0 bis 255 plus 256

von Ulrich (Gast)


Lesenswert?

Für Sägezahn und Dreieck kann man eine eigene Schleife machen, und sich 
dann den Zugriff auf die Tabelle sparen - das geht dann noch ein kleines 
bisschen schneller, und der extra Code ist eher kürzer als die Tabelle. 
Prinzipbedingt wird ein Dreieck/Sögezahn aber nicht so gut bei höheren 
Spitzen, weil die Spitzen irgendwann verloren gehen, denn der Filter 
hinter den D/A interpoliert halt.

Um mehr Auflösung aus dem D/A Wandler wäre theoretisch so etwas wie 
Dithering möglich, und dann den Tiefpaßfilter hinter dem D/A Wandler auf 
eine niedrigere Frequenz umschalten. Ab der Aufwand lohnt ist noch eine 
andere Frage. Für den SPI Bus gibt es mittlerweile auch relativ günstige 
12 Bit D/A Wandler, preislich durchaus eine Alternative zu genauen 
Widerständen für die R2R Kette. Die Ausgabe, auch via Hardware SPI 
braucht aber halt etwas Zeit - wäre also nur etwas für niedrige 
Frequenzen.

von Helmut L. (helmi1)


Lesenswert?

Hier mal etwas Lesestoff was es mit der Anzahl der Bits im DAC und in 
der Sinustabelle auf sich hat und wie man das Stoerspectrum das sich 
aufgrund der begrenzten Amplituden und Phasenaufloesung ergibt berechnen 
kann.

http://www.analog.com/static/imported-files/tutorials/450968421DDS_Tutorial_rev12-2-99.pdf

von Werner (Gast)


Lesenswert?

ich lese noch... :0)

STOP das von Datum: 20.01.2012 22:31 geht nicht wirklich ...

und suche noch.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> ich lese noch... :0)

Ist auch ein bisschen viel Text. Ich hoffe du kommst damit klar.

von Werner (Gast)


Lesenswert?

Yoh,
erster Gedanke:
Wenn ich 512 Byte lange Tabellen haben will, dann kommt die Adresse aus 
den
letzten 9 addierten Bits.
Der Carry hilft mir nix ?
Dann wird es zu lang(sam) ?

von Ulrich (Gast)


Lesenswert?

Ich sehe da noch kein Problem mit dem Code. Das mit dem Addieren des 
Carry-flags funktioniert so schon.

Bei der Berechnung der Frequenz muss man nur sehen, dass man jetzt 25 
Bit für die Phase hat, also die Frequenz nur halb so hoch wird wie zu 
vor mit der 256 Einträge Tabelle. Dazu kommt dann noch die etwas längere 
Schleife mit 10 statt 7 Zyklen.

von Werner (Gast)


Lesenswert?

nun..
ich hatte mit r26 = 1 bis 10 probiert.
Wenn jedesmal ein Carry-Bit übrig bleibt :0(
Es ist die falsche Richtung.
Die "Halbtöne" sitzen in r29 ?

von Ulrich (Gast)


Lesenswert?

Wo soll da ein Problem sein (abgesehen davon das es etwas 
unübersichtlich ist mit dem abgetrennten Add). Das unterste Bit von R31 
wird ganz normal über das Carry mit benutzt.


Etwas übersichtlicher könnte man es bekommen, wenn man die Schleifen die 
dem Auslesen der Tabelle anfängt, und nicht mit dem Addieren. Das ist 
aber wirklich nur Kosmetik und spart nur den einen Befehl vor der 
Schleife.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

ich muss noch 'mal schauen was ich da gesehen habe ...
mit dem Carry geht evtl. doch.

Nebenbei noch diesen 8 Bit D/A Jesper:

2 mal 256 Byte Tabellen ( Kopie im SRAM )
Bit 7 aus r29 des Addierers liefert 0,5 Schritte.
10 Takte pro Aktuallisierung
Phasenfehler ( Jitter ) viel besser.
Auflösung fast 8 Bit. max.

mfg Werner

von Ulrich (Gast)


Lesenswert?

Der Vorschlag unter Jesper_2x256x8.txt  wird nicht funktionieren. Es ist 
ja nicht so das sich das obere Bit immer umdreht. Was man muss also den 
alten Zustand von R31 schon berücksichtigen.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

die Hoffnung stirbt zuletzt :0)

Der 2x256x8 Jesper bei 1000 Hz.
Noch immer ohne jeden Filter.
50 Hz Netz abgeschnitten ( Hochpass ) im Speci.

Die "größte" Nebenwelle 15625 Hz, die Zeilenfrequenz meines Fernsehers.
Ja, ich schaue noch in eine Bildröhre, noch so ein Thema.
( Wenn es dann HD TV ++++++ gibt und wir zehn weitere Gerätegenerationen
gekauft haben ist das Bild wieder so gut wie 1967 )

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Ulrich,

hat auch einen "schlanken Fuss".
Deine Antwort sah ich erst als ich abgesendet hatte.

Es ist auch so, dass meist mehr als $FF addiert wird und dann flattert 
es...

von Ulrich (Gast)


Lesenswert?

Der Jesper_2x256x8.txt Code sollte doch gehen - irgendwie war ich noch 
zu sehr an der Version davor orientiert. Im Prinzip sollte da aber kaum 
unterschied sein zur Version von 20.01.2012 22:31. Halt einmal mit 25 
Bit Phase Akku und einmal mit 24 Bit.

von Werner (Gast)


Lesenswert?

> Im Prinzip sollte da aber kaum unterschied sein zur Version von
> 20.01.2012 22:31.
> Halt einmal mit 25 Bit Phase Akku und einmal mit 24 Bit.

Der "neue" macht eine ganze Periode in 256 * 10 Takten.
Das ist doppelt so schnell, fast so schnell wie ein UrJesper.

von Ulrich (Gast)


Lesenswert?

Die Version davor mit dem Carry und Bit0 aus R31, ist gleich schnell, 
hat nur 1 Bit mehr an Auflösung bei der Frequenz. Wenn man da das 
unterste Bit auf 0 setzt, sollte sich ein exakt gleiches Verhalten 
ergeben, es sei denn die Tabelle ist nicht so gut.

Bei passender Adresse im RAM (z.B. ab $0200) könnte man ein verschieben 
von Bit 7 aus R29 in Bit 0 von R31 nutzen. Das geht mit BLD R29,7 und 
BST R31,0 um einen 1 Zyklus schneller als die bisherige Version und 
damit genau so schnell wie der Ursprüngliche Code von Jesper (1 Sample 
alle 9 Zyklen). Je nach Rest des Programms müsste dann ggf. der Stack an 
eine andere Position, weil es am Ende zu knapp werden könnte bei 1 K 
RAM.

Die gleiche Geschwindigkeit könnte man auch mit einer längeren (1,5 
fach) Tabelle im Flash (ab 0800) erreichen. Dann mit 25 Bit Auflösung 
für die Phase, und 4 fach ausgeführter Schleifen. Das wäre eher mein 
Favorit, weil das auch noch in den Mega48 reingeht und man hat 1 Bit 
mehr an Auflösung für die Frequenz.

von Werner (Gast)


Lesenswert?

na danke.
Wieder lesen :0)
Das ist mein zweites Assembler AVR Abenteuer.

Tabellen? Ja, ich habe die mit MS ACCESS (VBA) gemacht.
Für EX'CELL bin ich zu blöd.
Nun habe ich einen Laptop der mit ACCESS 2003 HEX(138) = "0" macht
Und einen der mit ACCESS 2000 HEX(138) = "8A" macht.
Ich habe Zeugen, zwei Kollegen.
Dann habe ich auf das Dezimalsystem umgestellt.
Evtl. habe ich die 0xXY  Tabellen getestet, überliest man ja schnell...

von Werner (Gast)


Lesenswert?

> BLD R29,7 und BST R31,0 um einen 1 Zyklus schneller als
> die bisherige Version und

Yoh, 680x was my home, years ago.

Ich habe heute lange gedacht und gesucht.

Ich stolpere so durch den Code :0)
Verstanden habe ich es noch nicht.
Bit für Bit ...

von Ulrich (Gast)


Lesenswert?

Die Befehle BLD und BST nutzt man auch nicht besonders oft. Da kann man 
halt ein Bit einzeln aus einem Register in ein spezielles Flag (T) im 
Statusregister kopieren, bzw. in die andere Richtung.

Für das erst 2. ASM projekt ist das aber schon ganz gut.

von Werner (Gast)


Lesenswert?

Nabend,
es muss heissen:
        ldi     r31,2

        ...

        bst     r29,7           ; get bit 7
        bld     r31,0           ; make highZ odd or even

aber es geht, 9 Takte :0)
Tabelle bei 0x200 bis 0x3FF im SRAM.
STACK 0x1FF und down, kein Problem.

Grüße
Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Der erste 100 kHz der nicht flattert.

Etwas dick der Strich.
Unter der Lupe sind das 2 Periode 4 MHz.
22 / 9. Nun kann man filtern.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

einen habe ich noch.

Verschwenderisch mit den Takten.

4x256x8 Tabellen im Flash.
12 Takte.
Aber scheinbar braucht man zwei Adressleitungen mehr als Datenleitugen
um alle DA Werte vorkommen zu lassen.
100 kHz schafft dieser aber auch locker.
Bei tiefen Frequenzen hat er die Nase vorn.
Das bislang sauberste Spektrum vor dem Filter < 30 kHz.

von Ulrich (Gast)


Lesenswert?

Mit der längeren Tabelle im Flash (1024 Einträge) geht es besser, wenn 
man die Tabelle normal fortlaufend hat, und dann von R31 die Bits 
zusammenstellt, fast so wie oben beim Code von 20.01.2012 22:31
Damit sollte man dann auch auf 9 oder 10 Zyklen pro Sample kommen.

von Werner (Gast)


Lesenswert?

aber dann braucht man viermal solange um einen kompletten
Sinus zu beschreiben ?
Es kommt unabhängig von der Samplerate nur f * 1/4 raus ?

von Werner (Gast)


Lesenswert?

Ne, klar. ?
Vergiss mein Geschwätz von ...
Ich muss viermal soviel addieren, aber das dauert ja nicht ?
Richtig ?

von Ulrich (Gast)


Lesenswert?

Die Version braucht auch nicht länger. Man hat nur bei der Frequenz noch 
zusätzlich 2 Bit mehr an Auflösung, kann die Frequenz also 4 mal feiner 
Einstellen - wenn man den Zahlenwert 4 mal so hoch wählt wie bei der 
Version mit der zerstückelten Tabelle kommt das gleiche bei raus - eine 
ähnlicher (sogar etwas kürzerer) Abstand der Samples und genau die 
gleichen Werte für die Phase. Bei der 1024 Einträge langen Tabelle 
enthält R1 aber dann ggf. auch einen Teil der Frequenz (das höchste Bit) 
- auch wenn das in der Regel (unter etwa 500 kHz) 0 sein wird.

So wie oben kommt man auf 10 Take pro Sample: 1 takt mehr für LPM statt 
LD und dafür ein ORI einsparen, wenn die Adresse passend liegt.

Mit einer um das 1,5 fach verlängerten Tabelle und dann dem Zurücksetzen 
der Bits 2-7 nur nach jeden 2. Sample kann man auch noch auf 9 Takte 
kommen (4 Werte pro Schleifendurchlauf). Damit es einmal auch ohne 
zurücksetzen der Bits 2-7 geht muss die Tabelle einfach etwas länger 
(1,5 fach reicht) sein um den einen Schritt aufzufangen. Damit das Ganze 
dann noch in einen Mega48 reinpasst muss man ggf. mit sbc statt adc 
arbeiten - macht aber sonst keinen Unterschied.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

unser täglich Jesper gib uns heute ...

da nebenbei "Das Leben des Brian" läuft kann ich mich nicht 
konzentrieren.

Ich benutze den ATmega8. Mit 8k Flash, keine Platzprobleme.
Ich habe die Abkürzung genommen, ich bekam das mit 1,5 Tabellen (heute)
nicht hin.

Die Auflösung der Winkel ist genauso gut. 360°/1024
Die Auflösung der Amplitube identisch. 255 Schritte.
Diese Version hat eine höhere Auflösung der Frequenz. 2 Bit mehr
Das Signal ist auch noch etwas besser, da es nur 10 Takte braucht.

von Werner (Gast)


Lesenswert?

paste and copy

im Text 2x1025x8 muss es "load byte from current table in FLASH" 
heissen.

Ich denke 8 Bit D/A ist damit ausgereizt...und schon viel besser als
gewohnt.

von Ulrich (Gast)


Lesenswert?

Hier der wesentliche Teil des oben schon angedeutete Codes mit der 1,5 
fachen Tabelle und 4 fach entrollten Schleife. Die Tabelle kommt an eine
passende Byte adresse wie 0x0400, 0x0C00, 0x1400,... ) z.B. an das Ende 
des Speichers, und muss bis zu 1,5 Perioden lang sein, also z.B. von 
0x0200 bis 0x07FF (bei 2 Kbytes Flash) oder von 0x0A00 bis 0x0FFF

Mit SBC statt adc hat man es leichter einen passende Stelle im Speicher 
zu finden. Mit 2 K RAM könnte man es ggf. auch noch im RAM machen.

ldi r31, high(2*table)  ; Start addresse

loop1:
lpm     r0,z    ; 3
out  PORTD,r0   ; 1  *
sub  r28,r24    ; 1
sbc  r29,r25    ; 1
sbc  r30,r26    ; 1
sbc  r31,r27    ; 1
ori  r31,04     ; 1 limit range to upper part of table
lpm  r0,z       ; 3
out  PORTD,r0   ; 1  *
sub  r28,r24    ; 1
sbc  r29,r25    ; 1
sbc  r30,r26    ; 1
sbc  r31,r27    ; 1
; not limit in tabel -> need table to be one step longer
lpm  r0,z       ; 3
sub  r28,r24    ; 1
out  PORTD,r0   ; 1  *
sbc  r29,r25    ; 1
sbc  r30,r26    ; 1
sbc  r31,r27         ; 1
ori  r31,04     ; 1 limit range to upper part of table
lpm     r0,z    ; 3
sub  r28,r24    ; 1
out  PORTD,r0   ; 1  *
sbc  r29,r25    ; 1
sbc  r30,r26    ; 1
sbc  r31,r27    ; 1
; not limit in tabel -> need table to be one step longer
rjmp  LOOP1     ; 2 => 36 / 4 = 9 cycles

von Werner (Gast)


Lesenswert?

Der Ulrich, der hat immer einen Takt über.

Super, ich schaue mir das an.

Das Signal ist aber so schon ....
Nein! Nicht Quantensprung
( der unerwartete Sprung auf ein nieders Niveau ..)
Warum benutzen das die Leute?

Dann sind wir aber fertig ?

Grüße Werner

von Werner (Gast)


Lesenswert?

das brannte auf den Nägeln.
Gerade sofort ausprobiert.

2 Takte weniger > klasse

.org 0x200  Tabelle  Adder   ldi r24,85
             ldi r25,20
             ldi r26,20
r31 nimmt aber 4 Zustände an

7 , 6 , 5 , 4  also $07FF - $0400
da bin ich gestern auch hängen geblieben, eben mit adc
4 , 5 , 6 , 7  also $0400 - $07FF

noch etwas falsch gemacht ?
Mit Tabellen doppelter Länge geht die vierfach entrollte aber
wertvolle 2 Takte schneller.
Platz wäre ja.

von Ulrich (Gast)


Lesenswert?

Die 4 fach entrollte Schleife und das Abschneiden der Tabelle nur jedes 
2. Mal bringt auch nur 1 Zyklus weniger.
Wie schon richtig erkannt hat man für die einfache Tabelle Werte von
7 , 6, 5 oder 4. Wenn man das Abschneiden per ORI (bei der Version mit 
SBC) nur jedes 2. mal macht sind halt auch die Werte von 3 und 2 erlaubt 
(wobei 2 ggf. nur bei relativ hoher Frequenz vorkommt). Da muss dann 
noch einmal der selbe Inhalt wie bei 7 bzw. 6 drinstehen. Die Tabelle 
braucht auch nur knapp 1,5 fache Länge, denn mehr kommt bei einem 
Schritt nicht dazu.

Bei der Version mit ADC kommen halt Werte von 0 bis 3 normal vor, und 4 
oder 5 mit der verlängerten Tabelle. In beiden Fällen kann man auch noch 
vielfache von 8 dazu addieren.

Der Vorteil der Version mit SBC ist auch nur darin, das man die Tabelle 
besser im Speicher unterbringt, wenn der knapp ist. Ein Platz der da 
immer geht ist das Ende des Speichers. Mit Adc würde es im Prinzip immer 
an den Anfang gehen, aber der ist halt beim AVR fest vergeben für den 
Resetvektor, bzw. die IO register beim RAM.

So wie ich das sehe ist dann auch das Ende der Fahnenstange erreicht. 
Wenn man will, kann man die Tabelle noch einmal verdoppeln. Das wird 
aber wohl kaum noch was bringen - der Aufwand ist aber auch minimal: 
einfach nur mehr Speicher für die Tabelle und ein anderer Wert beim ORI 
bzw. ANDI.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Ulrich,

mit dem subtrahierenden 9er gibt es "run aways" bei r31 = 6.
r31 springt in > 7 , in die Buchstabensuppe 0B, 14 , FF
adder z.B. 85,20,20 auch im Debug.

ich habe nochmal einen mit ADD gebaut der macht das nicht.

Beide haben bei bestimmten Frequenzen viel Jitter und einen
derben Phasenfehler.

Die SUB Variante bei etwa ~270°
Die ADD Variante bei ~ 0°

Hardware sollte OK sein der 2x1024x8_10 geht immer nioch einwandfrei.

Foto: der 4fach entrollte ... ADD , 30kHz

Grüße
Werner

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Beide haben bei bestimmten Frequenzen viel Jitter und einen
> derben Phasenfehler.

Je nachdem wie das Frequenzwort in das Phasenregister reinpasst.
Aber das hast du sicher in der Appnote nachgelesen wo ich dir den Link 
geschickt habe.

von Werner (Gast)


Lesenswert?

Hallo auch Helmi,

ja ich habe versucht das zu lesen.
Am English liegt das Problem nicht,

Es ist schon sehr komplex.
Man kann schon einmal mitnehmen, dass DDS mit einer Phasenauflösung von
360 / 255 Grad nicht einmal die halbe Auflösung des 8 Bit ADC bringen
kann.

von Werner (Gast)


Lesenswert?

Wegstabenvervuchsler

>360 / 255 Grad nicht einmal die halbe Auflösung des 8 Bit ADC bringen

DAC sollte es werden. Sagen wir 5 bis 6 Bit Auflösung .

von Helmut L. (helmi1)


Lesenswert?

Du kannst ja mal ein Frequenzwort programmieren das ganzzahlig ins 
Phasenregister reinpasst. Damit sollte der Phasenjitter minimal werden.
Das ist auch ab Seite 19 beschrieben.

von Werner (Gast)


Lesenswert?

ich denke 'mal so laienhaft vor mich hin:

Das Problem der Phasenauflösung kann man nicht linearisieren.
Das müsste aus einem gemeinsmen Ursprung parallelisiert werden.

4x256x8_12 tat das ( sehr gut ) brauchte dann aber 2 Takte länger.

von Ulrich (Gast)


Lesenswert?

Das Problem mit der Routine mit den SBC ... kann ich nicht 
nachvollziehen. Bei mit im Simulator läuft das wie erwartet. Man muss 
aber aufpassen mit dem Wert für die Frequenz, R27 darf maximal 1 sein. 
Auch muss man am Anfang mit R31 im richtigen Bereich sein, also z.B. bei 
4.

Der Fehler in der gezeigten Kurve sieht ein bisschen nach einem Fehler 
in der Tabelle aus, eventuell ein Rundungsproblem beim berechnen der 
Werte ? Die Tabelle sieht zumindest ein kleines bisschen unsymmetrisch 
aus: die 128 kommt häufiger vor als 127. Beim Mega8 kann ich mit noch 
nicht vorstellen das der Code und die Tabelle überlappen - beim Tiny2313 
hab ich da schon Probleme (wegen Code für ASCII->  Binärwandlung für die 
Schnittstelle).

Das der Phasenfehler, bzw. die Abweichungen vom Sinus etwas von der 
Frequenz abhängen ist normal. Besonders ungünstig sind die Werte wo 
eines der unteren Bits in der Frequenz gesetzt ist, und dann viele 0en 
kommen - aber auch da sollten sich kein so deutlichen Fehler ergeben.

Wenn man das mit der Version mit der 256 Einträge langen Tabelle 
vergleicht sollten für eine Fairen Vergleich die beiden unteren Bits 0 
sein, denn die hat die die Version mit der längeren Tabelle zusätzlich.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Man kann schon einmal mitnehmen, dass DDS mit einer Phasenauflösung von
> 360 / 255 Grad nicht einmal die halbe Auflösung des 8 Bit ADC bringen
> kann.

Wenn dir die Amplitude bei höheren Frequenzen absinkt denk daran als 
abgetastetes System hast du dort noch einen Amplitudengang der mit 
sin(x)/x geht (Spaltfunktionen). Das heist wenn du den Frequenzgang 
glatt haben willst muss du das auch noch kompensieren. Einige DDS Chips 
von AD haben so eine Kompensation mit eingebaut.

von Ulrich (Gast)


Lesenswert?

Bei dem doch schon etwas längeren Code für die 4-fache Schleife kann 
sich auch schon leicht mal ein Tippfehler einschleichen.
Wenn es schon mit dem Index ein Problem gibt spricht das schon etwas für 
einen kleinen Tipp-fehler.

Es gibt keinen Grund wieso der Code mit den 4 verschachtelten 
Teiltabellen besser funktionieren sollte als der Code, der direkt in R31 
rechnet (egal ob mit Add oder sub). Bei vergleichbarem Wert für die 
Frequenz (4 facher Wert bei der Version direkt in R31), sollten genau 
die gleichen Werte an den DAC gesandt werden. Nur durch die andere 
Laufzeit ist die eine Version die 2 Zyklen schneller und damit die 
Frequenz höher.

von Werner (Gast)


Lesenswert?

@Helmi

Die Amplitude ist konstant. Bis etwa 150 ~ 200 kHz.
Die Kurvenform und das Spektrum ist anders )

@ Ulrich

Ich habe Deinen Code aus dem Thread kopiert.
Nicht abgetippt.

Wie soll r24 bis 31 denn beim Eintritt in die Schleife stehen?
Kannst Du eine Tabelle und deren orgin (Ursprung) für Dein Beispiel
stellen ?

von Ulrich (Gast)


Lesenswert?

Eine passende Tabelle für den Sinus habe ich auch nicht. Um den Teil hab 
ich mich bisher gedrückt und eine Übernommen: die 256 Einträge Version 
von Jesper, die 1024 Einträge Version hier aus dem Thread.

Ob R31 irgendwie aus dem Ruder läuft ist unabhängig von der Tabelle. Bei 
den Startwerten sollte R31 bei 4,5,6 oder 7 liegen (Version mit 
Subtraktion). Die Tabelle beginnt dann bei etwa 0100 Wortadresse (= 0200 
Byteadresse) und geht bis 07FF (Byteadresse). Falls der Speicher knapp 
ist kann man am Anfang noch ein paar Werte weglassen, bzw. für Code 
nutzen. Die werden nur bei unrealistisch hohen Frequenzen ganz nahe am 
Nyquistlimit (0,5* Abtastrate) gebraucht. R27 darf nur 0 oder 1 sein. 
Was in den anderen Registern steht ist egal - da sind alle Werte 
erlaubt. Wichtig ist eigentlich auch nur die Frequenz (R24-R27) bei der 
Phase probiert man auch so so ziemlich alles durch.

Falls man genug Speicher hat darf man auch vielfache von 8 zu R31 
addieren.
Bei der Position der Tabelle per .org gibt man die Wortaddresse an.

von Werner (Gast)


Lesenswert?

Ich Blödmann !!!

warum der SUB ausrastet weiss ich noch immer nicht.

Aber ich habe SUB und ADD mit einer 1024er Tabelle gefüttert.
Der Phasenfehler ist mein TWI Code :0))))
folgend auf die zu kurze Tabelle.

Der ADD geht super.

Die Welt ist wieder heile...

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

hier mal die Baustelle, soweit vorhanden.

Ein 48er wäre besser,
man könnte die Registernummer in der TWI Adresse verstecken.
Der hat eine TWI Adressenmaske ...

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

die vermeintlich problematische Stelle unter der Lupe.

f = 32 kHz
vertikal 50mV / Teilung
horizontal 200nS / Teilung
Ort: Nulldurchgang

... natürlich noch Reste der Samplingrate drauf.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo nochmals,

ich "messe" nun deutlich verbesserte Werte ?
Kann, mag das jemand bestättigen ?

Macht ein Takt soviel aus ?

mfg Werner


P.S. Ja GEMA , mein Fernsehgerät ist an ( Cursorposition )

von Ulrich (Gast)


Lesenswert?

Bei dem Bild liegt die Grundwelle bei -10 dB: da ist wohl irgendwo noch 
ein Regler etwas verstellt. Damit werden dann ggf. auch die Störungen 
kleiner. Wenn man das berücksichtige sind die Oberwellen noch nicht 
kleiner geworden. Wie es dicht dran aussieht, ist schwer zu sagen.

So viel macht der Takt nicht aus. 1 Zyklus mehr oder weniger sind halt 
etwa 10% die man in der Frequenz höher gehen kann. Da bringt der Schritt 
zum Mega48 mit 20 MHz schon mehr.

Der Fortschritt zum Original "Jesper" ist ja auch nicht in der 
Geschwindigkeit, sondern in der 4 mal höheren Auflösung in der Phase 
(bei gleicher Laufzeit pro Sample) - das kann etwa 6 dB bringe. Halt der 
Unterschied von Limitiert durch die Tabelle (256 Einträge) zu Limitiert 
durch den DA Wandler (1024 Einträge).

von Werner (Gast)


Lesenswert?

Guten Abend Ulrich!

Ich hatte versucht nur auf absolute Differenzen zu schauen.
Diese Soundkarten-Software macht Quatsch, wenn man auf 0 dB einstellt.
Das ist auch ein Qszi drin. Der sieht bei 0dB komisch aus.

Also habe ich rund -6 dB justiert. das ist leider kein "Messgerät"
6dB, das passt schon, ist aber auch 'was in einer log. Welt.

2x256x8_10 vers 1x1536x8_9 das vergleiche ich (glaube ich) gerade.,,
Zuviele Versionen.

So wie es ist, gefällt es mir.
Ulrich ich danke Dir !

von Werner (Gast)


Lesenswert?

Ulrich schrieb:
> Halt der Unterschied von Limitiert durch die Tabelle (256 Einträge)
> zu Limitiert durch den DA Wandler (1024 Einträge).

Man kann aber schon sagen:
Für die Sinus Funktion ist die Limitierung durch die Länge
der Tabelle relevanter ?
(Bei ursprünglich 256 Schritten in der Tabelle und 256 Schritten im DA 
Wandeler.)

Last Question, Ulrich

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

sch.. Wetter.
So habe ich noch ein Bilderrätsel zum Wochenende ...
DAC Ausgang und Bit1 aus r31 an PORTB.1

Wenn man die addiert, einen Takt spendiert und eine "komische" Tabelle
verwendet, dann bekommt man 9 Bit DAC.

Für die linearen Sägezahn und Dreieck ist ein Bit extra eh nicht 
schlecht.

Schönen Sonntag noch.

von Ulrich (Gast)


Lesenswert?

Das mit dem zusätzlichen 9. Bit sieht interessant aus, vor allem wenn 
man da noch einen OP Port frei hat und entsprechend schnell ausgeben 
kann. Ich hätte aber Bedenken dass da die einfache R2R Lösung direkt am 
Ausgang noch ausreicht, denn man hat beim Ausgangswiederstand eine 
Unsicherheit von rund 10-20 Ohm.

Dann würde es sich ggf. sogar lohnen auch die Tabelle noch einmal zu 
verdoppeln - falls man den Platz hat (müsste beim Mega8 gehen), ist der 
Aufwand ja minimal (einfach nur ein Bit mehr in R31 lassen).

Nach dem DDS Tutolrial machen etwa 4 mal mehr Werte in der Tabelle als 
Stufen beim DAC schon Sinn, vor allem bei relativ niedriger Frequenz.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

... addiert wird natürlich mit zwei weiteren Widerständen im R2R.

1x1536x9_10 ist kein Sprinter. > 20kHz ist er nicht besser als 
1x1536_8_9.
PORTB und PORTD kann man nicht exakt gleichzeitig aktuallisieren.
Es jittert auch wieder ein wenig bei sehr hohen Frequenzen.
Es gibt dort einen "Glitch".
Erst konnte man etwas Gescheites ausfiltern.
Jetzt sollte man filtern.
Bei niedrigen Frequenzen hat er aber klar die Nase vorn.

Mag jeder selber schauen oder kombinieren.

von Werner (Gast)


Lesenswert?

och der Ulrich.
Hallo!
Das war gleichzeitig.

Yoh, je nach Tabellenlänge kann man die Auflösung in beiden Dimensionen
erhöhen...

von Werner (Gast)


Lesenswert?

Ulrich schrieb:
> Ich hätte aber Bedenken dass da die einfache R2R Lösung direkt am
> Ausgang noch ausreicht, denn man hat beim Ausgangswiederstand eine
> Unsicherheit von rund 10-20 Ohm.

Das Problem hat aber jedes MSB in einem R2R.
Egal das wievielte es ist.

von Helmut L. (helmi1)


Lesenswert?

@Werner

Hast du schon mal darueber nachgedacht eine andere CPU zu nehmen.
Da gibt es zur Zeit von ST ein Board mit einem Cortex M4 Prozessor fuer 
kleines Geld. Da hast du dann auch 2 12Bit DACs mit auf dem Board. Da 
koenntes du gleichzeitig zwei Phasenverschoben Signal erzeugen etc.

Und mit 168 Mhz Takt duerftes du auch keine Probleme bekomnmen.

von Werner (Gast)


Lesenswert?

Hallo Helmut,

ich habe diesen Jesper erst vor Kurzem gefunden.
Jahre später als die meisten hier. Sofort war der Gedanke :
Logisch, da hättest du auch selbst drauf kommen können.
Das Rad gab es schon, Räder drehen sich und mathematisch beschreiben
kann man das schon lange ...
Sekunden später das sichere Gefühl, dass er das nicht zuende gedacht 
hat.
Also Hut ab, mit einer Hand voll "Schweinefutter" (Widerstände)

Dann die Wut darüber, dass ich soetwas Simples nichteinmal selber kann.
99% dieses Thread sind gefüllt mit meiner Dummheit...

> Wenn es zu langsam werden sollte, einfach den AVR mit 100% übertakten.
> Am Ende der Experimente nimmt man dann den AD9833 :-)

Ja, einen Funktionsgenerator habe ich schon 1000mal vermisst.
Aber die kann man auch kaufen.

Ich habe gerade den Spass meinen zweiten Gedanken zu verfolgen :0)
Die "handvoll Schweinefutter" macht sich ja auch unerwartet gut.
Etwas mit 168MHz Takt hat man nicht so in der Schublade, dass ist auch
nichts für Lochrasterplatten...

Für HF habe ich ein wenig gutes Zeug, auch R&S, Schomandel und so.
Für NF nix.
Wenn am Ende Gutes bis 20-30kHz rausschaut und auch
30-100kHz rauskommemn, fein.
Und ich habe es mir dann bewiesen :0)

Hochskalieren kann man es dann immer noch.
Man sieht ja wieviel Jesper ungenutzt lies.
Um so mehr Power die Hardware hat, um so mehr übersieht man im Konzept.

Grüße Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Der "Glitch" noch,

das soll nicht verschwiegen werden.

Jenachdem ob das Bit 8 ( also 9 ) zuerst oder an zweiter Stelle rausgeht
ist er rauf oder runter.
Mit 1/f(Quarz) S geht das hier schief.
Es folgt z.B. $1FF auf $FF , wenn auch nur ganz, ganz kurz.
Bit 8 ( also 9 ) kommt immer einen Takt früher oder später.

Desto mehr Bits man benutzt, um so mehr lindert man das Problem.
Es rutscht 2°N nach rechts.

Da braucht es einen Filter.

von Werner (Gast)


Lesenswert?

Nachtrag;

The original Jesper is "glitch" only

von Werner (Gast)


Lesenswert?

Ulrich schrieb:
> Das mit dem zusätzlichen 9. Bit sieht interessant aus, vor allem wenn
> man da noch einen OP Port frei hat und entsprechend schnell ausgeben
> kann.

Hallo,
nichts ist schneller als ein induktivitätsarmer / -freier Widerstand.
Ein OPAMP verliert immer....

Man sieht Dinge die nach einem OPAMP nicht exístieren ?

von Ulrich (Gast)


Lesenswert?

Den Glitch kann man ggf. noch etwas reduzieren, mit einem kleinen 
Kondensator an der R2R Kette, nach 8 Bits nach GND. Damit werden die 
ersten 8 Bits ggf. etwas (ca. 70 ns) verzögert.

von Werner (Gast)


Lesenswert?

Hallo Ulrich,

Der Glitch wohnt ( in dieser Konfiguration ) bei 0 - 180 - 360°.
Er Verändert sich auch mit der Frequenz.
Ein Sprung $1FF auf %FF ist worst case, kommt nicht vor.
Das wäre eine extrem tiefe Frequenz.
Wobei, so schlimmt ist er nicht verglichen mit einen 1x256x8_9 Jesper.
Der macht Treppchen überall.

Auf dem Weg rauf auf dem Sinus ist Verzögern von Bit 9 OK.
Ein verzögertes Bit 9 macht es dann aber auf dem Weg runter noch 
schlimmer.
Bit 9 steht dann zulange.

Der Glitch hat eine andere Schwachstelle, '
seine extrem steile Flanke und kurze Dauer..
Ich habe Probleme seine Amplitude zu messen.
Das Digiscope sieht ihn garnicht :0)
Seine Oberwellen sollten theoretisch bei f(out) x 2 usw. liegen.
Das Sondkarten FFT merkt nix.
Analogscope 1 M / 30pF vom Scope, puh. Er ist da wo man ihn erwaret.
Mit einem 10 / 1 Tastkof kaum machbar ( sichtbar ), angedeutet.
Hänge ich noch den Zähler mit nochmals 30 pF parallel ...
Er macht er soweit mein Scope das noch zeigen kann < 50mV ~
weniger als 5 von 512 Bit, meist weniger, je nach Frequenz.

Ich baue mir mal einen Tiefpass, sagen wir f(Grenz) 500kHz.
Danach ist er wahrscheinlich ( hoffentlich ) weg(gebügelt).

Grüße Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe 'mal genommen, was mir so in die Hand fiel...


R2R ------ 2mH ----+-----  Scope
                   !
                  390pF
                   !
                  ---

Das ist schon der richtige Weg...
Das Bild ist der Glitch bei ~ 100 Hz , 50mV vertikal / Teilung.

Rechts:
Wenn ich genau hinsehe macht er evtl. 100 mV und mehr.
Direkt am R2R gemessen-

Links:
mit dem Primitivfilter.
Scope parallel zum 390pF

Ohne jetzt meine Schulbücher rauszuholen:
2mH und 390pF wo liege ich da ?
Es gab da mal so nette online Rechner füe RLC.

Grüße Werner

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Ohne jetzt meine Schulbücher rauszuholen:
> 2mH und 390pF wo liege ich da ?
            1
fr = ------------------
     2 x pi x sqrt(L x C)

Filter berechnung hier:

http://www.aade.com/filter.htm

von Werner (Gast)


Lesenswert?

Yoh, ein bischen tief / nicht steil genug.
Jenseits 40 kHz geht die Amplitude schon zurück.
Rund die Hälft bleit bei 110 kHz.
Aber da kann man ja was machen.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo nochmal,
Bastelstunde, kalt genug ist es ja.

R2R ----+---- 340µH ----+---- OPamp
        !               !
       10pF            150pF
        !               !
      --+---------------+--
gets rid of it. Gut genug für mich...

Spule ist au sder Krabelkiste. 420µH steht drauf 340µH hat sie.
Die Amplitude geht bei 111 kHz um 10 % zurück.
Für Sinus und Dreieck lass ich das so.
Rechteck kann man besser am MSB abgreifen, es jitter ja nicht mehr so.
Ein Sägezahn ist ohne "extra"* C auch OK.

Das C* am Ausgang de R2R kann man auch frequenzabhängig machen.
100, 220, 470, 820 parallel. Schaltbar über PINs an PORTC.
PIN : Eingang C ab.
PIN : Ausgang und low oder High dran.
Das scheint zu funktioneren.

Grüße Werner

von Ulrich (Gast)


Lesenswert?

Zumindest in der Simulation funktioniert der Kondensator in der R2R 
Kette ganz gut zur Unterdrückung des Glitches: Bei einer R2R Kette mit 1 
K und 2 K kommt es bei 70 ns Verzögerung ganz gut hin mit 100-120 pF 
gegen Masse. Der Glitch reduziert sich auf ca. 1/4 der Fläche. Dabei 
verschwinden vor allem die niedrigeren Frequenz noch stärker - so dass 
danach der Filter um so effektiver wird.

Für ein sauberes, Jitterarmes Rechecksignal sollte man eher nicht direkt 
das MSB nutzen. Da hat man etwa 10 Zyklen = 700 ns Quatisierung bei der 
Zeit. Das bekommt man schon mit einem PWM Ausgang besser (ca. 1 Zyklus) 
hin.
Deutlich besser ist ein Komparator am Sinussignal hinter dem Filter. Da 
kann man bei höheren Frequenzen mit Jitter unter 20 ns rechnen, je 
nachdem wie gut der Aufbau und Filter ist auch noch besser. Im Idealfall 
wird die Zeit zwischen 2 DA Samples damit noch einmal analog in bis zu 
rund 200 Teile geteilt, einfach über die DA Werte vor und nach dem 
Nulldurchgang. Bei kleineren Frequenzen wäre dann ggf. noch ein Teiler 
hinter dem Komparator sinnvoll.

von Werner (Gast)


Lesenswert?

Ulrich,

ich habe ein´10k - 20k R2R.
Ich finde den Effekt nicht.
Wo genau fügst Du das C ein ?

       R1              R2
----- 10k ----+------ 10k ----+----- Filter
              !               !
              !               !
         R3  20k          R4 20k
              !               !
              !               !
      PORTD.7 ( Bit 8 ) PORTB.1 ( Bit 9 )

Den größten Effekt sehe ich wenn ich PORTD.7 ( Bit 8 ) mit 33 pF 
belaste.
Nicht unbeding einen positiven Effekt.

von Werner (Gast)


Lesenswert?

P.S. man nimmt ein OctalLatch.
Man braucht aber einen Clock und es ist kein Jesper im Sinne des 
Einfachen mehr ... :o)

von Ulrich (Gast)


Lesenswert?

Der Kondensator kommt vom Punkt zwischen R1 und R2 nach Masse. Das 
Programm muss dann erst die Bits 1-8 anlegen und dann Bit9.
Bei 10 K und 20 K und 16 MHz Takt - sollte die richtige Kapazität mehr 
so bei 10-12 pF liegen. 33 pF sind schon etwas zu viel - da wird es dann 
schon wieder schlechter.

Der Glitch sollte dadurch zum einen kleiner werden, und dann auch noch 
etwa symmetrisch, also erst eine Abweichung noch oben, und gleich danach 
nach unten.

Als Anhang mal, was ich bei der Simulation raus bekomme: blau nur R2R, 
grün mit Kondensator 120 pF.

von Werner (Gast)


Lesenswert?

Der Anhang fehlt.
Umdrehen: 8 und dann Plus 9.
Probiere ich.

von Werner (Gast)


Lesenswert?

Küsschen!

10pF obenlastig.
2x10pf untenlastig

Ich mache eine Trimmer rein, abgleichbar.

von Werner (Gast)


Lesenswert?

P.S. mit dem blauen Jumper im "Schweinefutter" konnte ich immer noch auf
8 Bit umstecken. Den braucht es nicht mehr.
Jesper hat 9 Bits!
10 Bit ? habe ich noch nicht auf dem Schirm. Latch erledigt.
Aber er müsste dann "Up and Down counten" ?
MSB invertieren... ne geht nicht so ganz "einfach"

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

9 Bit Jesper mit Ulrichs Zeh und einem Filter aus der Krabelkiste...

von Helmut L. (helmi1)


Lesenswert?

Ich habe letztens fuer ein Geraet ein DDS Generator mit dem MSP430F2618 
gebaut.
Der hat einen DAC mit 12Bit auf dem Chip. Bei 1 Khz Ausgabefrequenz 
hatte ich dort einen Klirrfaktor von unter 0.1% gemessen mit einem 
Ausgabe Tiefpass 6. Ordnung mit 2KHz Grenzfrequenz.

von Werner (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Der hat einen DAC mit 12Bit auf dem Chip.

Wie lang war dann Deine Tabelle ?
Ich würde min. 14 Bit denken um den Vorteil ausnutzen zu können ?

P.S. Was versteht der Autor von dem Soundkartending unter
"Totale harmonische Verzerrungen" ?
Irgendwie blieb Glitchi nicht unbemerkt...

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Wie lang war dann Deine Tabelle ?

8192  x 12 (16 Bit)

von Ulrich (Gast)


Lesenswert?

Mit einem Tiefpass bei 2 kHz ein 1 kHz Signal auf unter 0,1% Klirr zu 
bekommen ist keine so große Kunst - das braucht es vermutlich nur 4 Bit 
zu. Die Frage mehr wie es geht wenn der Filter mehr bei 500 kHz ist.

Der Glitch durch das verzögerte 9. Bit hat schon eine kleine Komponente 
auch bei relativ niedrigen Frequenzen, so wie den Oberwelllen des 
Signals. Der Kondensator schafft es halt vor allem den Teil zu 
kompensieren. Der Rest ist dann größtenteils bei >1 MHz und damit 
weniger störend.

Ob das dann noch wirklich sinnvoll ist, Software DDS so weit zu treiben 
ist etwas anderes - reine DDS Chips wie der AD9833 kosten ja auch nicht 
mehr die Welt ( < 7 EUR bei Reichelt). Sinnvoll ist DDS per Software vor 
allem, wenn der µC noch was anderes zu tun hat, und das Signal nur 
Mittel zum Zweck ist, z.B. für die Messung von Kapazitäten / 
Induktivitäten. Dann reichen aber in der Regel auch die 8 Bits locker.

von Werner (Gast)


Lesenswert?

Ja, Hallo Ulrich und Helmut.

Wenn Helmut nun 5kHz Messfrequenz haben möchte und ... Klirrfaktor-
messungen machen woltte. Genau da habe ich auch gestuzt...

Ne, ich lasse es auch jetzt bei 9 Bit.

Nochmal danke mit dem Umdrehen.
So was Blödes, etwas was zu spät kommt verzögern zu wollen zzz..tt

von Werner (Gast)


Lesenswert?

Werner schrieb:
> Um so mehr Power die Hardware hat, um so mehr übersieht man im Konzept.

jetzt habe ich es erst...Helmuts 12 Bit sind der totale Overkill.

von Helmut L. (helmi1)


Lesenswert?

Nicht gerade Klirrfaktormessung ist fuer die Kalibrierung von 
Schwingungswächter. Damit werden Zentrifugen überwacht.

Habe allerdings vor ca. 20 Jahren den ersten DDS Generator gebaut.
Rein mit TTL ICs.  24Bit Phasenauflösung / 8 Bit Amplitude.
Mit 74AS Addierer bin ich bis 4MHz gekommen. Ausgangstiefpass war ein 7 
poliges Cauerfilter. 1. Oberwelle 48db unter der Grundwelle.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> jetzt habe ich es erst...Helmuts 12 Bit sind der totale Overkill.

Mag sein aber der MSP430 hat nun mal 2 12Bit DACs. Und beim 2. brauch 
ich die 12Bit.

von Werner (Gast)


Lesenswert?

OK.

Der Jesper_1x1536x8_9 hätte das ja schon ohne jedes Filter, nur mit
Kapazitäten im Messaufbau gemacht...
Wenn der Autor meines Spielzeug FFT THD mit
"Totale harmonische... " meint und das auch richtig behandelt.

von eProfi (Gast)


Angehängte Dateien:

Lesenswert?

Was mir noch einfällt:
1. +5V mit mehreren SMD-Cs direkt am (auf dem?) µC abblocken, da manche 
Cs bei der Quarzfrequenz eine Resonanzstelle haben und damit gar nicht 
mehr abblocken.

2. für mehr Bits einen 2. µC nehmen und ihn vom selben Takt + Reset 
versorgen --> Ports sollten exakt gleichzeitig schalten.

3. die Berechnung der Sin-Tabelle mache ich mit 127,5 + 127,5*sin
Sie ist schön symmetrisch und hat statt der 21x nur 15x 00 / ff .
512er Tabelle siehe Anhang.

4. Werner, die Idee mit dem 9. / 10. Bit ist gut!

von Helmut L. (helmi1)


Lesenswert?

eProfi schrieb:
> 1. +5V mit mehreren SMD-Cs direkt am (auf dem?) µC abblocken, da manche
> Cs bei der Quarzfrequenz eine Resonanzstelle haben und damit gar nicht
> mehr abblocken.
>

Das Problem beim Werner ist das er auf 2 Ports versucht gleichzeitig 
9..10 Bits auszugeben. Abhilfe schafft hier wirklich nur ein syncrones 
Ausgeben der Bits. Das geht allerding nicht mit dem uC. Man koennte 2 
externe Auffangregister (74xx574) anschliessen und die gemeinsam 
triggern. Eventuelle den Clock fuer die Register durch teilen des 
Quarzsignales erzeugen. Dazu muesste man wiessen wieviele Clocks die 
Schleife verbraucht und dann durch teilen der Quarzclock daruas ein 
Strobesignal fuer die Register erzeugen.

> 2. für mehr Bits einen 2. µC nehmen und ihn vom selben Takt + Reset
> versorgen --> Ports sollten exakt gleichzeitig schalten.

Da er ja auch mal eine andere Frequenz ausgeben will und damit einen 
Interrupt ausloest zur Eingabe der Daten wuerde die Syncronitaet der 
beiden uC nicht mehr funktionieren.

von Werner (Gast)


Lesenswert?

eProfi schrieb:
> 3. die Berechnung der Sin-Tabelle mache ich mit 127,5 + 127,5*sin
> Sie ist schön symmetrisch und hat statt der 21x nur 15x 00 / ff .
> 512er Tabelle siehe Anhang.

Du hast die halbe Tabelle vergessen ?
Meine ist doppelt (1,5mal)so lang.
Da dürfen es schon mal ein paar 255er mehr sein.
Du hast auch das neunte Bit nicht drin ?
Meine Werte sind 0,5er Schritte.
Bit neun sieht man nicht, es versteckt sich in der Adresse.

Helmut hat das schon richtig geschrieben.
Der Glitch wohnt nicht auf Vcc. Er ist im Prinzip begründet.
Ein Latch hatte ich ja auch schon einmal fallen lassen.
Wie schon gesagt ist es dann aber kein Jesper-Einfach mehr.

Für eine DuoCPU gilt das natürlich erst recht.
Das Ding sollte auch ein quasi analoges feeling haben, drehen wie am 
VFO.
Also nicht Frequenz wählen und Reset zum Starten drücken.
Wir sind nicht bei WINDOWS wo man Start drückt zum Beenden :0)
Das scheiden zwei ganz aus. Ich habe ja schon zwei...
Tasten, Drehgeber, LCD, USB: Mega16 und
einen Frequenz- und Kurvenknecht: Mega8.

von Werner (Gast)


Lesenswert?

@ Ulrich
jetzt habe ich das unter der Lupe betrachtet.
Ich habe einen Trimmer 30pF max. eingebaut Anstelle des 8-9 bit Jumper.
Man kann die "losen" Enden vor und nach dem Glitch exakt aneinander
fügen ( abgleichen ).
Diese Einstellung trifft sich mit einem THD Minimum von 0,07%.
THD ist "einstellbar" zwischen 0.14 und 0,07%
Es bleibt an der Klebestelle ein nS Impuls von einigen mV.
( Schaltzeiten Tolleranzen im µC ? )
KLASSE wenn Theorie meets practice
Ich habe jetzt soviel Ruhe auf dem Sinus, dass ich tatsächlich die
Samplefrequenz aufgelöst sehen kann.

von Ulrich (Gast)


Lesenswert?

Mit dem Kondensator kann man die Verzögerung nur näherungsweise 
ausgleichen. Vor allem im HF Bereich > 1 MHz stimmt die Verzögerung 
nicht, wenn es bei niedrigeren Frequenzen stimmt. Das ist aber nicht so 
schlimm, denn da hilft der Rekonstruktionsfilter.

von Werner (Gast)


Lesenswert?

Du simulierst ?
Ich mache das von Zeit zu Zeit mit SwitcherCAD.
Womit machst Du das ?
Hast Du ein Modell für SwitcherCAD ( Spice ähnlich ? )

Warum nimmst Du 1 und 2kOhm R2R.
Die Fehler im RDS(on) werden größer als bei 10 und 20kOhm.

Da der Lötkolben an war...
Der Mega8 rennt auch 24 Mhz ohne, dass ich Probleme erkennen kann.
Ich habe sogar die Temperatur gemessen.

Um den Unken vorzubeugen habe ich jetzt aber ein 16 Mhz Quarz drin.
Die 14745600 habe ich massenweise vom billigen Jakob.
Wegen der Baudrate, aber die brauche ich hier nicht...

von Ulrich (Gast)


Lesenswert?

Ich habe den Teil mit LTSpice Simuliert. In der Simulation ist es 
relativ egal welchen Widerstand man nimmt. Mit 10K/20K bekommt man auf 
Streifenraster so langsam schon Probleme mit den Kapazitäten - ist aber 
noch die bessere Wahl. Für die R2R in Hardware habe ich sonst 10 K und 
4,99 K gewählt - dazu kommen ja noch ca. 30-50 Ohm Ron.

Die Schaltung zur Simulation ist recht einfach: Einfach 2 
entgegengesetzte Stufenfunktionen mit etwas Verzögerung zusammenmischen, 
über Widerstände wie bei R2R, nur halt nur 2 Bits.

von Werner (Gast)


Lesenswert?

OK,

zum Abgleich des Trimers benutze ich auch schon
BERNSTEIN (Abgleichbesteck), unüblich bei LF.

Ich hatte davon geträumt den Lötkolbe (erst einmal auszulassen) ..

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe gerade 'mal Dreieck, Sägezahn und Rauschen angebaut.

Obwohl das Rauschen 5Vss hat, auf die Bandbreite kommt ein kleiner Pegel
für alle Frequenzen raus.
Das Spektrum hat keine Lücken wie es im Bild scheint.
Ich kann aber nur momentane Screeenshots aufnehmen.
Ich bräuchte eine längere "Belichtungszeit".

Unerwartet aber logisch.
Für ein Dreieck und Sägezahn wären noch viel längere Tabellen sinnvoll.
Die momentanen Maxima trifft man nur bei größerer Winkelauflösung.
Eine Reihe Nullern und FFs wären ein Segen.
Der Sinus ist vergleichsweise simple :0)

Dreieck und Sähezahn sehen bis ~ 10kHz brauchbar aus.

Rechteck geht dann wie Ulrich sagt über Komparator.
Ulrich, der Chef hat immer Recht...

von Ulrich (Gast)


Lesenswert?

Beim Dreieck sollte man es auch hinbekommen die Werte direkt 
auszurechnen, also ohne Tabelle. Zumindest bei 8 Bit DA geht das noch 
ganz gut.
Eine Längere Tabelle hilft für Dreieck und Sägezahn auch nicht. Das 
Problem ist einfach das man da viele Oberwellen braucht um auch die 
Spitze mit zu bekommen. Entsprechend ist dann bei z.B. 1 oder 10 kHz 
irgendwann Schluss. Man kann es auch im Zeitbereich sehen: beim Sinus 
ist die Interpolation sinnvoll möglich. Beim Dreieck geht mit einer 
Interpolation aber die Spitze verloren. Da hilft eigentlich nur eine 
höhere Abtastrate oder eine andere Art Generator.

von Werner (Gast)


Lesenswert?

Hallo,
ich habe es mir gedacht,
das Dreieck und Sägezahn habe ich mir im original Jesper nie angesehen.

Für's Dreieck haben mich die Wendepunkte zur Tabelle gebracht.
"Unten" mache ich aber ein schönes Dreieck...auch >> 1 kHz.

Mit dem Sägezahn bin ich noch unglücklich.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

'nabend nochmal.

Ich habe einen Spielplatz gebaut mit 8 und 9 Bit Varianten und Sample 
Rates
von 1,6 bis 3,2 MHz. Interessant wieviele Varianten man sich da 
ausdenken
kann...auch 5 Takte Sägezahn
Eihentlich alle besser als der UrJesper


R2R ----+-------+----10K---+----340µH---+----OPAMP
        !       !          !            !            !
       20K     30pF       20K          150pF
        !      trimm       !            !
        !       !          !            !
        !       !          !            !
       PD7     PC0        PB1          GND
       Bit7  deglitch     Bit8

9 Bit und eine hohe Auflösung der Phase schlägt immer die 8 Bit 
Sprinter.
So ist es halt.

Der BASCOM Schnipsel für den MEGA16 wird z.Zt. über Terminal gespeist.
Er nimmt zumindest das Ausrechnen der Adder Werte ab und erlaubt den 
Wechsel zwischen den Modi.

Nochmals Danke für Eure Hilfe

Werner

von Werner (Gast)


Lesenswert?

P.S. @ Ulrich , klar Dein SUB geht auch!

Ich habe 'mal von ACCESS berichtet das HEX(138) zu NULL macht.
Ich habe auch Tabellen generiert in denen Zeilen fehlten.
AVR Studio spann manchmal ...
Ich habe wegen einer Schweinerei PC-TOOLS SpyDoctor laufen.
Das Ding ist der bessere virische Trojaner :0)

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Ulrich schrieb:
> Eine Längere Tabelle hilft für Dreieck und Sägezahn auch nicht. Das
> Problem ist einfach das man da viele Oberwellen braucht um auch die
> Spitze mit zu bekommen.

... und der Ulrich hat immer Recht.
Wie die schon die angehängte "games.txt" Datei
zeigt auch ein Versuch die Winkelauflösung zu erhöhen (1024er Tabelle)
im Sekunenrhythmus leicht schwankende Amplituden und Spektren.
Auch wenn man meinen könnte das Qszillogramm sei schöner.

Hier hat die 3,2MHz 8Bit Schleife die Nase vorn.
Das Grundrauschen ist geringer, die Amplitude stabil.

von eProfi (Gast)


Angehängte Dateien:

Lesenswert?

> Autor: Werner (Gast)  Datum: 18.01.2012 20:55
> Hat jemand eine 512 Byte lange 8 Bit Sinustabelle parat ?

Im Anhang vier Sinustabellen
1. 256 lang, Hex für Asm, 8 Bit, Formel: 127,5+127,5*sin()
2. selbige in Dez
3. 256 lang, Dez für C,  10 Bit, Formel: 511,5+511,5*sin()
4. 512 lang, Dez für Asm, 8 Bit, Formel: 127,5+127,5*sin()
5. 512 lang, Dez für C,  10 Bit, Formel: 511,5+511,5*sin()

Durch die etwas kleineren Offsets / Faktoren kommen nicht so viele Min- 
(0) und Max- (255 bzw. 1023) Werte hintereinander.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo nochmal,

auf einer langen Autofahrt kam mir der geschenkte Gaul in den Sinn.
Geschenkt ist der Gaul, wenn es keine CPU Zeit kostet.


Mit etwas Hardware könnte man wohl aus dem Bit 7 ein Achtes Bit machen.
Also Bit 9, verwirrend das Ganze.

Ich wollte Bit 7 schon 'mal zum T0 oder T1 führen, um mit dem Timer zu 
zählen.
Beim 8er sind die belegt und leider gibt es nur up / down und kein 
toggle als Trigger.

Siehe "Preisrätsel"

Grüße
Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
die Tabelle brauche ich langsam selber :0)

Für das Rätsel fand sich / ich auch keine simple Lösung.
Ist wohl ausgereitzt...

Es bleibt nun :
- Übertakten
- (Re)konstruktion des 9. Bit aus Bit 8
- Aufbereitung der Adressen und Ablegen der D/A Werte in externem RA/OM
- etwas worauf ich ich komme ....

Der Frequenz/Kurvenknecht (MEGA8) beherrscht eine paar Modi.
Er wird von einem MEGA16 gesteuert, der z.Zt. nur seriell in TWI 
wandelt.

Das LC Filter geht natürlich nur bei Sinus, sonst stört es nur.

Sorry for my bad Assembler, I'm a newbe...

von Werner (Gast)


Lesenswert?

Hi,
ich möchte nochmal stören....

Vom ATmega8 wollte ich auf einen ATmega88 wechseln.
. der PIN Toggle wäre nett.
. 22 MHz wären nett
. das TWI hat ein Adress Mask Register,
  man kann mehrere Adressen verwenden und gleich den Wert übergeben.
. PINCJANGE Interrupt , auch nicht schlecht.
. Pinkompatibel ist er auch.

Beim TWI habe ich ein Problem:
OK, die bei Atmel schreiben im Datenblatt das gleiche
Beispiel wie beim 8er. Das kann eigentlich nicht gehen.
Die TW Register liegen nicht im I/O Beeich.

Klein Hänschen dachte nun,
man tauscht alle "out" gegen "sts" und alle "in" gegen "lds".
Der ansonsten unveränderte Code läuft nicht :0(
Der Interrupt findet statt ( die erzeugte Kurve stolpert kurz )nur die 
Reaktion ist nicht die gewohnte.
Das Adress Mask Register ist noch aus ( 0 ).
Es sollte noch wie gewohnt laufen.
Eigentlich kein Byte wird richtig erkannt / ausgewertet ?

Gibt es noch einen Unterschied für TWI zwischen 8 und 88 ?

Grüße Werner

von Ulrich (Gast)


Lesenswert?

Beim Zugriff auf die Register per STS oder OUT muss man eine andere 
Addresse benutzen. Bei STS ist die Adresse um 32 größer. Leider ist da 
ein unterschied zwischen IO und RAM Addressen.

von Werner (Gast)


Lesenswert?

Hallo Ulrich,

sorry.
Ich hatte den STACK auf $00FF gelegt.
Im 88er ist dort extended IO.
Der Assembler ist damit glücklich.
Der Simulator mekert difus...
Die Wahl eigentlich ohne Grund, denn die in das SRAM kopierten Tabellen 
enden bei §03FF.
Noch Platz genug für den STACK.
Nur der "rti" war faul.
Es geht wieder soweit.

Ich habe das Preisrätsel gelöst ... und simuliert.
Es gibt einen geschenkten Gaul :0)

von spess53 (Gast)


Lesenswert?

Hi

>Beim Zugriff auf die Register per STS oder OUT muss man eine andere
>Addresse benutzen. Bei STS ist die Adresse um 32 größer. Leider ist da
>ein unterschied zwischen IO und RAM Addressen.

Nur bei IO-Adressen <$60.

MfG Spess

von Werner (Gast)


Lesenswert?

spess53 schrieb:
> Nur bei IO-Adressen <$60.

stimmt.

von spess53 (Gast)


Lesenswert?

Hi

>Ich hatte den STACK auf $00FF gelegt.

Wie kommt man auf diese Idee?

MfG spess

von Werner (Gast)


Lesenswert?

Ich hatte im Sinn, dass die Tabelle mit $03FF dem RAMende entspricht.
1/4 K übersehen. Im 8er war das egal.

von spess53 (Gast)


Lesenswert?

Hi

>Im 8er war das egal.

Nur bedingt. Wenn du den RAM intensiver nutzt wirst du lustige Effekte 
bemerken.

MfG Spess

von Werner (Gast)


Lesenswert?

bislang und das wird auch so bleiben liegt da nur die Rücksprungadresse 
des TW Interupts.
Das RAM ist ja schon fast voll mit den Tabellen.

von spess53 (Gast)


Lesenswert?

Hi

>Das RAM ist ja schon fast voll mit den Tabellen.

Ab RAMSTART ohne .org?

MfG Spess

von Werner (Gast)


Lesenswert?

spess53 schrieb:
>>Das RAM ist ja schon fast voll mit den Tabellen.
> Ab RAMSTART ohne .org?

? Ich kopiere aus dem FLASH in das SRAM von $0100 bis $03FF.
Wegen des einen Taktes "lpm" zu "lp".
Aber jeder Takt ZÄHLT.

von spess53 (Gast)


Lesenswert?

Hi

>? Ich kopiere aus dem FLASH in das SRAM von $0100 bis $03FF.

Damit hast du den Stack mit $00FF unterhalb deiner Tabellen.

MfG Spess

von Werner (Gast)


Lesenswert?

Ja, ehemals mit Absicht.

Der zählt doch immer runter und wenn oben (je nach dem ) kein Platz ist.

von eProfi (Gast)


Lesenswert?

Ich schreibe jetzt doch in diesem Thread weiter, weil es thematisch 
besser passt als im "Schwesterthread" 
Beitrag "DDS Sinus erzeugung"
Meine schon lange existente Idee ist, für die für die 9-Bit-Ausgabe 
notwendige Verzögerung statt des RC  SPI zu verwenden.
Entweder es ist schon von Haus aus eine Verzögerung vorhanden, oder man 
braucht eine 4-fach-Fallunterscheidung: Signal
 - bleibt high: nichts oder FF ausgeben
 - bleibt low : nichts oder 00 ausgeben
 - steigende Flanke: 7f ausgeben
 - fallende  Flanke: 80 ausgeben

von Ulrich (Gast)


Lesenswert?

Die Ausgabe mit mehr als 8 Bit macht mit dem AVR nur realtiv wenig Sinn. 
Die Schleife wird einiges Langsamer und je nach DAC geht das 9. Bit ggf. 
auch noch unter. Hilfreicher ist es die Sinustabelle länger (512 oder 
1024 Einträge) zu machen. Dazu gab es auch schon mal einen Thread - 
incl. weiter optimiertem Code. Vieles ist da im "Schwesterthread" schon 
drin.


Will man mehr, gibt es halt fertige DDS Chips: sei es ein AD9833 oder 
ein Modul mit AD9851 von Chinesen bei IbÄ, gleich mit Filter am Ausgang.

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.