Guten Morgen in die Runde.
Ich habe mir ein Programm geschrieben, das mittels Lookup Table einen
Sinus ausgibt. Das tut es auch soweit.
Allerdings erreiche ich nur 1kHz Ausgangsfrequenz, aber da wird der
Sinus schon enorm eckig und man sieht die Abtastschritte deutlich (ohne
Filter).
Eckdaten:
- DDS Berechnungsfrequenz: 10kHz
- ATmega16 mit Ref.Freq: 16MHz
- Phasenakkumulator: 32Bit
- Anzahl der Stützwerte im Sinus: 512
Die Berechnungsfrequenz ergibt sich durch die Dauer der Berechnungen die
ich durchführen muss.
Meine Frage: Was genau bestimmt die max. mögliche Ausgangsfrequenz und
was muss ich tun um den Sinus bei höheren Werten mit mehr Punkten
auszugeben?
Vielen Dank!
@ Fantamann (Gast)
>Die Berechnungsfrequenz ergibt sich durch die Dauer der Berechnungen die>ich durchführen muss.
jain. Andere Leute schaffe deutich mehr, siehe DDS.
>Meine Frage: Was genau bestimmt die max. mögliche Ausgangsfrequenz
Mit dem Herrn Shannon.
f_max <= 1/2 f_DDS.
>und was muss ich tun um den Sinus bei höheren Werten mit mehr Punkten>auszugeben?
Gar nichts, es ist nunmal so, dass bei höheren Frequenzen weniger
Stützstellen verfügbar sind. Ist aber kein Problem, der FILTER am
Ausgang löst das Problem. Den hast du aber noch nicht, darum siehst du
unschöne Signale. Der Filter ist aber notwendig.
MFG
Falk
P S Jaja, eine DDS kann auch >1/2 f_dds ausgeben, aber das ist für
fortgeschrittene Semester.
@Falk Brunner
Danke für die Antworten. Die max. Frequenz nach Shannung ist meines
Verständnisses nach nur rein theoretisch. Ich muss ja schon ein
paar berechnungen durchführen. Seh ich das richtig?
Das könnte ich effizienter gestallten, da hast du recht. Filter habe ich
auch mal drangemacht, aber der verzerrt mir mein Rechteck. Ich hab ihn
mit
fg=10kHz ausgelegt.
>>Die Berechnungsfrequenz ergibt sich durch die Dauer der Berechnungen die>>ich durchführen muss.>> jain. Andere Leute schaffe deutich mehr, siehe DDS.
Die größte Verzögerung erzeugt mir die berechnung der Schrittweite.
Ich weiß noch nicht wie ich das effizienter gestallten kann.
Falk Brunner schrieb:> Ist aber kein Problem, der FILTER am>> Ausgang löst das Problem. Den hast du aber noch nicht, darum siehst du>> unschöne Signale. Der Filter ist aber notwendig.
Man sollte das dahingehend präzisieren, dass es sich um den Anti
AliasingFilter handelt, der später nach einem DAC sitzt.
Für die rein digitalen Werte ist man nach der DDs fertig, wenn es weiter
verrechnet werden soll. Das einzige, was dnekbar wäre, ist ein
FIR-Filter, um die Funktion zu glätten, wenn die Tabelle zu wenig
Y-Auflösung hat.
@ Fantamann (Gast)
>Danke für die Antworten. Die max. Frequenz nach Shannung ist meines>Verständnisses nach nur rein theoretisch.
Auch praktisch.
> Ich muss ja schon ein paar berechnungen durchführen. Seh ich das richtig?
Nö. Für deine Zwecke passt das schon. Die Vollprofis rechnen noch ne
Weile an einem perfekten Filter, der dann 120dB Dämpfung für die
Oberwellen bringt.
>Das könnte ich effizienter gestallten, da hast du recht. Filter habe ich>auch mal drangemacht, aber der verzerrt mir mein Rechteck.
Logisch, aber du willst doch einen SINUS! Wenn man auch ein jitterarmes
RECHTECK haben will, muss man NACH dem Filter einen Komparator
platzieren.
>Die größte Verzögerung erzeugt mir die berechnung der Schrittweite.
???
Die macht man doch nur einmalig, wenn man die Frequenz ändert.
>Ich weiß noch nicht wie ich das effizienter gestallten kann.
Poste Code. Oder schau dir an, wie dass andere machen. Der Jesper macht
es schon sehr gut.
http://www.myplace.nu/avr/minidds/index.htm
MfG
Falk
Ich hab vergessen zu erwähnen dass ich alles einprogrammiert habe:
Sinus, Rechteck, Sawtooth, Dreieck.
>>Die größte Verzögerung erzeugt mir die berechnung der Schrittweite.>> ???> Die macht man doch nur einmalig, wenn man die Frequenz ändert.
Du hast vollkommen recht. Ich jedesmal mitberechnet. Wenn ich es
auslagere, dann hab ich ca. 15µs die ich brauche für die Ausgabe. Das
macht etwa 65kHz Berechnungsfrequenz. Damit das ganze Filterlos noch
nach Sinus aussieht, brauche ich etwa 10 Werte, das heißt über 6,5kHz
komm ich nicht hinaus.
Das erscheint mir wenig :-/
Formal ist dein Code richtig, aber für maximale Leistung braucht man
hier wirklich Assembler wie beim Jesper. Dann braucht man auch nur 8
Takte pro Datenausgabe und kommt damit auf gut 2 MHz Ausgabetakt mit
einem AVR!
Was man schon mal ändern könnte ist, die Abfrage der Wellenform aus der
ISR rauszunehmen, das spart reichlich Zeit. mit einem Trick kann man
auch das Schieben um 24 Bit sparen, über einen Union-Zugriff. Und
Funktionen ruft man in ZEITKRITISCHEN ISRs besser nicht auf sondern
schreibt es direkt hin. etwa so
okay, danke. Darüber werde ich mal nachdenken.
Meine eingangs gestellt Frage, welcher Teil des Codes jetzt bestimmend
für die max. Ausgangsfrequenz ist, hast du jetzt indirekt beantwortet.
Das mit der Auswahl der Wellenform funktioniert so wie du es beschrieben
hast nicht bei mir, weil die nur der Sinus im Speicher abgelegt ist.
Alles andere berechne ich aus dem counter-Wert heraus.
Zum Beispiel
1
if(mode==SAW)
2
putDAC(phase);
Das mit der Union werde ich aber in Angriff nehmen.
Danke und Grüße
@Fantamann (Gast)
>Das mit der Auswahl der Wellenform funktioniert so wie du es beschrieben>hast nicht bei mir, weil die nur der Sinus im Speicher abgelegt ist.>Alles andere berechne ich aus dem counter-Wert heraus.
Was schon mal ein weiterer Leistungsverlust ist. Und das alles wegen ein
paar läppischen Bytes? Die müssen nicht im RAM liegen, ein Lesezugriff
auf den Flash über pgm_read_byte ist praktisch genauso schnell. Oder du
kopierst jeweils bei der Auswahl die Daten vom Flash in den RAM, das
wäre ein guter Kompromiss.
MFG
Falk
Falk Brunner schrieb:> @Fantamann (Gast)>>>Das mit der Auswahl der Wellenform funktioniert so wie du es beschrieben>>hast nicht bei mir, weil die nur der Sinus im Speicher abgelegt ist.>>Alles andere berechne ich aus dem counter-Wert heraus.>> Was schon mal ein weiterer Leistungsverlust ist.
Das verstehe ich nicht. Wie kann es sein, dass ein auslesen eines bytes
aus dem Speicher mit anschließender ausgabe schneller ist als ein
einfaches:
@ Fantamann (Gast)
>Das verstehe ich nicht. Wie kann es sein, dass ein auslesen eines bytes>aus dem Speicher mit anschließender ausgabe schneller ist als ein>einfaches:>PORTD = counter;
Weil deine ganzen Abfragen der Wellenform immer wieder ausgeführt werden
müssen! Deine if else Kette.
MFG
Falk
Fantamann schrieb:>> Was schon mal ein weiterer Leistungsverlust ist.>> Das verstehe ich nicht. Wie kann es sein, dass ein auslesen eines bytes> aus dem Speicher mit anschließender ausgabe schneller ist als ein> einfaches:>>
1
PORTD=counter;
Weil du in deiner ISR Fallunterscheidungen brauchst!
Auch die kosten Zeit!
In der ISR willst du nach Möglichkeit nur noch Bytes an den Port
rausblasen. Nicht mehr. Alles was nicht unmittelbar damit zusammenhängt
ist für den µC Arbeit, die nicht sein muss.
Du willst nicht da irgendwelche Sonderfälle berücksichtigen müssen oder
sonstiges bedenken müssen. Die ISR soll sich darauf stützen können, dass
das alles für sie schon so mundgerecht aufgearbeitet wurde, dass sie nur
noch Bytes schaufeln muss.
Das geht dann in allen Fällen immer gleich schnell und erlaubt dir, die
ISR Aufruffrequenz bis ans Limit zu treiben. CTC_Modus und den soweit
hochtreiben, dass gerade noch soviel Rechenzeit übrig bleibt, dass du
per Bedienelement die Ausgabe wieder abstellen kannst (weil du zb den
Wert verändern musst), indem du notfalls den Timer stoppst und so
Rechenlast durch die ISR wegnimmst.
Bei Falk kommt das im Code nicht so gut raus, aber das hier
1
ISR(...)
2
{
3
dds_cnt.counter=dds_cnt.counter+stepsize;
4
PORT_DAC=table_p[dds_cnt.phase];
5
}
ist seine ganze ISR. Absolutes Minimum. Noch weniger geht nicht.
spess53 schrieb:> Siehe:> Beitrag "DDS normal ?"> MfG Spess
Hi, dieser Thread dort ist sehr lang geworden und geht meist um mein
Unvermögen....
Niemand liest mehr bis zum Ende :0(
Hier mein Stand der Dinge.
Interrupts taugen nicht.
Hochsprachen taugen nicht.
Für diesen Zweck zählt jede Nanosekunde.
Grüße Werner
Hallo!
@Falk: Der jesper braucht übrigens 9 Takte. Deshalb machen sich bei
seiner 256er-Tabelle Quarzfrequenzen mit Vielfachen von 9x256 besonders
gut, sind aber nicht handelsüblich.
@Route_66 (Gast)
>@Falk: Der jesper braucht übrigens 9 Takte.
OK, dann eben 9.
> Deshalb machen sich bei>seiner 256er-Tabelle Quarzfrequenzen mit Vielfachen von 9x256 besonders>gut, sind aber nicht handelsüblich.
Ist vollkommen egal. Perfekt jitterfrei sind sowieso nur Frequenzen mit
2^n im Increment der DDS, macht bei 24 Bit nur 23 Frequenzen. Der Rest
jittert sowieso, mal mehr, mal weniger.
MFG
Falk
Falk Brunner schrieb:>>@Falk: Der jesper braucht übrigens 9 Takte.> OK, dann eben 9.
Schon die bescheidene Qualität des UrJesper kann man einfach steigern.
Vorausgesetzt man kopiert die Tabellen in das SRAM und recycled den
rjmp.
add r28,r24
LOOP1:
adc r29,r25 ; 1
adc r30,r26 ; 1
lp ; 2
out PORTB,r0 ; 1 UpDate
add r28,r24 ; 1
adc r29,r25 ; 1
adc r30,r26 ; 1
add r28,r24 ; 1
lp ; 2
out PORTB,r0 ; 1 UpDate
rjmp LOOP1 ; 2 => 14/2 = 7 cycles
und dann geht natürlich noch viel mehr.
Werner schrieb:> lp ; 2
Tipfehler lp = ld :0( RAM eben nicht FLASH sind schon 11,5%
Jespers Auflösung für den Sägezahn kann man in 5 Takten erledigen.
Es Jittert nur viel weniger....
add r28,r24
STL2:
adc r29,r25 ; 1
adc r30,r26 ; 1
out PORTD,r30 ; 1 UpDate
add r28,r24 ; 1
adc r29,r25 ; 1
adc r30,r26 ; 1
add r28,r24 ; 1
out PORTD,r30 ; 1 UpDate
rjmp STL2; ; 2 => 10/2 = 5 cycles
eine Tabelle braucht es dann nicht
Jespers Rechteck kann man kaum so nachmachen.
Nimmt man einen AVR der PIN toggle kann ( evtl. nicht fair, ich kenne
seinen Chip nicht ) kann man ein Rechteck in 7 Takten produzieren.
Die Auflösung der Phase steigt aber bereits um ein Bit auf 9 Bit.
Die Auflösung der Frequenz wird ebenfalls um den Carry auf 25 Bit
erhöht.
Das Ganze läuft 23% schneller ab, obwohl die Auflösung deutlich zunimmt.
ser r31 ; initial
out PORTD,r31
RM2:
add r28,r24 ; 1
adc r29,r25 ; 1
adc r30,r26 ; 1
brcc out1 ; 2
out PIND,r31 ; toggle Bit 0..7
out1:
rjmp RM2; ; 2 7 cycles
In 9 Takten kann man ein Rechtecksignal gleicher Auflösung (Qualität
wie Jesper ) erzeugen, nur es gibt ein geschenktes Tastverhätnis
zwischen 0 und 255 dazu.
; Duty cycle 0 to 255
.equ DUTY = r13
ser r31
clr r27
RM11: ; on off
add r28,r24 ; 1 1
adc r29,r25 ; 1 1
adc r30,r26 ; 1 1
cp r30,DUTY ; 1 1
brsh off ; 2 1
nop ; 1
out PORTD,r31 ; 1
rjmp RM11 ; 2
off:
out PORTD,r27 ; 1
rjmp RM11 ; 2 9 cycles
Hi
>In 9 Takten kann man ein Rechtecksignal gleicher Auflösung (Qualität>wie Jesper ) erzeugen, nur es gibt ein geschenktes Tastverhätnis>zwischen 0 und 255 dazu.
Wenn ich ein Rechteck haben will nehme ich einen Timer und nicht so ein
Gedödel.
MfG Spess
Yoh, Gedödel klingt hart.
Schon, mit dem Timer geht das gut,
nur eben nicht für fast beliebige Frequenzen. ( Auflösung )
Es soll auch kein Glaubenskrieg werden ...
Da hatte doch jemand die gleiche Idee....
Der UrJesper verschenkt Zeit, um so langsamer um so größer wirde die
Schrittweite.
Desto größer die Schritte um so mehr verfehlt man das Ziel.
Wirklich gut fand ich ihn erst nachdem die Auflösung erhöht wurde.
So wie im 88DDS,
- lange Tabellen eff. 1024 Schritte pro 360°
- 9 Bit D/A Ausgabe
- 26 Bit Addierregister
- bei höherer Abtastrate (9 bzw 10 Takte bei 22MHz clock)
@ Werner (Gast)
>Schon die bescheidene Qualität des UrJesper kann man einfach steigern.
Bleib mal auf dem Teppich. Der Ansatz von Jesper war und ist gut, auch
unter dem Gesichtspunkt der Resourcennutzung, die DDS läuft auf einem
ATtiny!. Klar kann man noch einiges Verbessern und 7 gegen 9 Takte sind
nochmal 23% weniger Zeit, aber das Grundprinzip, nämliche eine
ultrakompakte Hauptscheife in ASM ändert man kein bisschen. Für eine
reine Softwarelösung schon sehr gut. Wenn man höhere Takte braucht nimmt
man ehe Hardware.
MfG
Falk
Nochmal zu meinem Ursprünglichen Problem.
Möchte ich zeitgewinnen und lege alles in Tabellen ab,
dann ist der ram relativ schnell vol :-(
Find ich doof.
spess53 schrieb:> Wenn ich ein Rechteck haben will nehme ich einen Timer und nicht so ein> Gedödel.
Sehe ich genau so. Wenn es Quarzgenau sein muß, auch mit PLL.
Gruß
Jobst
Karl schrieb:> In der letzten Elektor gab es da einen Artikel, der sich damit> beschäftigt. Vielleicht als Anregung:>> http://www.elektor.de/jahrgang/2012/marz/sdr-mit-a...>> Die schreiben, dass sie ein brauchbares Signal um die max. 200 kHz> erhalten (kombiniert C/Assembler).
Das hat Werner der Länge nach doch alles er- & geklärt.
P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der
Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.
Hi
>P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der>Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.
Ist auch nur Teil 1 eines Artikels. Geplant ist ein Empfänger für den
deutschen Wetterdienst.
MfG Spess
spess53 schrieb:> Hi>>>P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der>>Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.>> Ist auch nur Teil 1 eines Artikels. Geplant ist ein Empfänger für den> deutschen Wetterdienst.>> MfG Spess
Mag sein, Spess, aber die Elektor habe ich nach dem Titelbild gekauft.
Auf dem stand SDR. Nur drinn war ziemlich wenig SDR.
Hört mir eigentlich noch jemand zu? :-)
Mein Programm hat folgende Struktur
MAIN:
1
uint8_t*p_table;
2
3
if(output==ON)
4
{
5
if(mode==SINE)
6
p_table=wave_sine;
7
elseif(mode==SAW)
8
p_table=wave_saw;
9
//...
10
}
11
else
12
{
13
table_p=wave_off;
14
}
ISR:
1
phase=(counter>>24);
2
counter=counter+stepsize;
3
4
putDAC((*p_table+phase));
Das funktioniert leider nicht. Am DAC kommt immer das gleiche raus, d.h.
das "umbiegen" der Zeiger in MAIN macht Probleme. Sieht jemand was ich
falsch mache?
Danke und Grüße,
Fantamann
Du benutzt C, eine Hochsprache und steckst den wichtigsten,
zeitkritischen Teil in ein Interrupt Routine.
Du willst gehört werden, liest aber nicht.
Wenn Du die kürzest mögliche Schleife in C ( kenne mich da nicht aus )
zum Addieren, Tabelle lesen und Ausgabe in Main packst
und das von Zeit zu Zeit mit Frequenz- oder Modusänderunger
unterbrichst...
kommt evtl. etwas raus, sicher nicht viel Gute
Fantamann schrieb:> Am DAC kommt immer das gleiche raus, d.h.> das "umbiegen" der Zeiger in MAIN macht Probleme. Sieht jemand was ich> falsch mache?
Wo liegt denn wave_sine und wave_saw?
Liegen die im RAM oder im Flash?
Wenn im Flash muss du die Daten anders holen mit pgm_read_byte.
@ Fantamann (Gast)
>Möchte ich zeitgewinnen und lege alles in Tabellen ab,>dann ist der ram relativ schnell vol :-(>Find ich doof.
Dein ATmega16 hat 1kB RAM, da werden doch wohl läppische 256Byte für die
Tabelle übrig sein. Wenn dir das immer noch zuviel ist, pack die Tabllen
in den Flash, ist nicht nennenswert langsamer. Hab ich alles aber schon
dreimal erzähl. Jaja, diese Jugend . . . ;-)
Beitrag "Re: DDS Sinus erzeugung"
Falsh ist gewöhnlich mehr als genug vorhanden, für SIN, SAW und OFF
gerade mal läppische 768 Bytes.
>Mein Programm hat folgende Struktur
Warum so halbgar? Hast du Angst vor zu viel Leistung? Lies mein Posting
noch mal und mach es richtig.
>Das funktioniert leider nicht. Am DAC kommt immer das gleiche raus, d.h.>das "umbiegen" der Zeiger in MAIN macht Probleme. Sieht jemand was ich>falsch mache?
ja, du postet keinen vollständigen Code im Anhang. Siehe Netiquette.
MfG
Falk
Falk Brunner schrieb:> Flash ist gewöhnlich mehr als genug vorhanden, für SIN, SAW und OFF> gerade mal läppische 768 Bytes.
Eigentlich braucht man für hohe Ausführungsgeschwindigkeiten nur
Tabellen für Sinus und Dreieck, wegen der Wendepunkte bzw. nicht
monotonen Steigung.
Das kann man realistisch in Echtzeit nicht schneller leisten.
Dann sollten sie im Sinne der Auflösung so lang wie möglich sein.
In einer 256er Sinus Tabelle stecken nicht einmal 7 Bit
Amplitudenauflösung.
Viele Werte kommen garnicht vor.
Eine Tabelle für OFF ??
> Wenn Du die kürzest mögliche Schleife in C ( kenne mich da nicht aus )> zum Addieren, Tabelle lesen und Ausgabe in Main packst> und das von Zeit zu Zeit mit Frequenz- oder Modusänderunger> unterbrichst...> kommt evtl. etwas raus, sicher nicht viel Gute
Ich mache es aus diesem Grund genau andersherum ;-)
Helmut Lenzen schrieb:> Wo liegt denn wave_sine und wave_saw?> Liegen die im RAM oder im Flash?> Wenn im Flash muss du die Daten anders holen mit pgm_read_byte.
habe sie am Programmbeginn mit uint8_t wave_sin[256]={...} deklariert.
Also müsste es im Flash liegen, oder?
Werner schrieb:> Falk Brunner schrieb:>> Flash ist gewöhnlich mehr als genug vorhanden, für SIN, SAW und OFF>> gerade mal läppische 768 Bytes.>> Eigentlich braucht man für hohe Ausführungsgeschwindigkeiten nur> Tabellen für Sinus und Dreieck, wegen der Wendepunkte bzw. nicht> monotonen Steigung.
Das hatte ich in diesem Thread auch gesagt, wurde aber verneint.
Deswegen hab ich jetzt alles in Tabellen abgelegt.
An alle: Ich möchte bei meiner Lösung bleiben und bin auch mit dem
Resultat zufrieden. Ich möchte lediglich mit Zeigern auf die Waves
zugreifen um schneller zu werden, aber da hab ich irgendwo einen
Syntaxfehler vermute ich.
Sieht diesen jemand?
Fantamann schrieb:> Ich möchte lediglich mit Zeigern auf die Waves> zugreifen um schneller zu werden, aber da hab ich irgendwo einen> Syntaxfehler vermute ich.
Du hast nicht gesagt, dass Du weitaus häufiger den Modus oder die
Frequenz
wechseln willst / wirst,
als die Kurve aktuallisiert werden soll.
Werner schrieb:> Du hast nicht gesagt, dass Du weitaus häufiger den Modus oder die> Frequenz> wechseln willst / wirst,> als die Kurve aktuallisiert werden soll.
Ok, jetzt verstehe ich was du meinst. Ich hatte zu Beginn das Problem,
dass ich in der Main unterschiedliche Laufzeiten des Programms hatte,
wegen den ganzen ifelse abfragen. Ich sollte es besser andersrum machen?
Werner schrieb:> ich Werner, nicht Falk
OKay, hab es umgebaut. So scheints mir jetzt auch klüger zu sein.
Ich habe jetzt noch ein bissl weiterprobiert. Sobald
ich mehr als 3 Signale als Tabelle einfüge gehts nicht mehr.
const uint8_t wave_sine[256]={...}
const uint8_t wave_saw[256]={...}
const uint8_t wave_revsaw[256]={...}
const uint8_t wave_triangle[256]={...}
const uint8_t wave_square[256]={...}
d.h. wenn ich triangle und square auskommentiere (oder auch zwei
beliebige andere) dann gehts :-/
Also irgendwo scheints mit der Datenmenge probleme zu geben.
Gibt es noch irgendwen der eine IDee hat?
Fantamann schrieb:> Also irgendwo scheints mit der Datenmenge probleme zu geben.> Gibt es noch irgendwen der eine IDee hat?
Wie voll ist dein Flash denn?
const liegt im Flash
Obwohl, wenn das im SRAM ist, 3 mal 256 Byte und dann ein mords Stack
vom C
Das soll ein MEGA16 sein ?
1K RAM
Dann ein mords Stack für das C Gedönste ?
Wie soll das gehen?
Wie gesagt durch brauchst maximal zwei Tabellen und von denen immer nur
eine zu einer Zeit ....
Du brauchst in deinem RAM nur eine Tabelle und zwar
die für die Ausgabe ausgewählte.
Bei der Auswahl wird diese neu gefüllt. Bei Rechteck,
Dreieck etc. (also leicht und schnell zu rechnen)
über eine Berechnung, bei Sinus eher über eine Tabelle
im Flash und kopieren.
hans
Werner schrieb:> Obwohl, wenn das im SRAM ist, 3 mal 256 Byte und dann ein mords Stack> vom C>> Das soll ein MEGA16 sein ?> 1K RAM
Das klingt plausibel. Was spricht dagegen die Tabellen einfach im
Flash abzulegen?
Kann mir bitte jemand kurz erklären wie das geht? Ich habe es wie oben
gesagt mit const angedacht, aber das scheint ja irgendwie nicht zu
reichen.
Danke und Gruß,
Fantamann
ich weiss nicht wie C den Unterschied RAM und FLASH behandelt.
Von Haus aus und damit durch C auch nicht veränderbar dauert es 1/3
länger ein Byte aus dem Flash zu lesen.
In einem DDS ist Zeit knapp,,,
Du braucht kein Tabelle OFF, SAW, REC usw.
Eine Dreieck kann man in wenigen Zeilen Code errechenen, wenn denn
Dreieck
gewäht wird.
Einen Sinus berechent man lieber vorher und legt ihn ihn FLASH ab.
Wenn denn dann Sinus gewählt wird kopiert man diese in das RAM.
Die Main Routine gibt immer den gleichen Speicherbereich aus dem RAM
aus.
Nur es mus halt drin sthen, was angesagt ist.
Werner schrieb:> Von Haus aus und damit durch C auch nicht veränderbar dauert es 1/3> länger ein Byte aus dem Flash zu lesen.
Das war natürlich untertrieben.
Ein ld aus dem RAM dauert zwei Takte. Ein lpm aus dem FLASH drei.
lpm is also 50% langsamer als ld.
Gute Nacht.
Werner schrieb:> schmeiss C für das Ding weg> und schau Dir den Assembler Code im 88DDS an.
Na Na Werner.
Es gibt auch den goldenen Mittelweg wie immer.
Zeitkritische Teile in Assembler, alles andere in C schreiben.
So mach ich das immer.
Und beim GCC kannst du Assemblerteile in dein C Programm miteinbinden.
@ Fantamann (Gast)
>Das klingt plausibel. Was spricht dagegen die Tabellen einfach im>Flash abzulegen?
In deinem Fall gar nichts.
>Kann mir bitte jemand kurz erklären wie das geht? Ich habe es wie oben>gesagt mit const angedacht, aber das scheint ja irgendwie nicht zu>reichen.
Muss man beim AVR anders machen.
@Werner (Gast)
>Ein ld aus dem RAM dauert zwei Takte. Ein lpm aus dem FLASH drei.>lpm is also 50% langsamer als ld.
Theoretisch richtig, praktisch irrelevant. Der OP WILL bei seiner eher
langsamen Interruptlösung bleiben. Da spiel ein Takt mehr oder weniger
keine Rolle. Damit ist die lpm-Lösung prakitsch gleichwertige mit der
RAM-Lösung.
MfG
Falk
Falk Brunner schrieb:> Muss man beim AVR anders machen.> uint8_t wave_sine[256] PROGMEM ={...};>> ...>> putDAC(pgm_read_byte(p_table+phase));>>> MFG> Falk
Dankeschön
Werner schrieb:> Du braucht kein Tabelle OFF, SAW, REC usw.> Eine Dreieck kann man in wenigen Zeilen Code errechenen, wenn denn> Dreieck> gewäht wird.> Einen Sinus berechent man lieber vorher und legt ihn ihn FLASH ab.> Wenn denn dann Sinus gewählt wird kopiert man diese in das RAM.
Dieser Ansatz führte jetzt vorerst zum Erfolg. Ich erreiche damit etwa
200kHz, mit Filter würd ich sagen dass etwa 20kHz noch als Sinus zu
bezeichnen sind.
Ich bin jetzt weg von der interrupt Lösung und lasse die Lookuptable mit
maximaler Geschwindigkeit abtasten.
Danke für die vielen Beiträge. Grüße!
Fantamann schrieb:> Falk Brunner schrieb:>> Muss man beim AVR anders machen.>> uint8_t wave_sine[256] PROGMEM ={...};>>>> ...>>>> putDAC(pgm_read_byte(p_table+phase));>>>>>> MFG>> Falk>> Dankeschön
Hatte ich dir auch schon gesagt.
Beitrag "Re: DDS Sinus erzeugung"
Helmut Lenzen schrieb:> Hatte ich dir auch schon gesagt.>> Beitrag "Re: DDS Sinus erzeugung"
Hast recht, ich hab den ersten Beitrag dieser Art zitiert, den ich beim
hochscrollen gefunden habe. Dir natürlich genauso: Dankeschön!
Fantamann schrieb:> mit Filter würd ich sagen dass etwa 20kHz noch als Sinus zu> bezeichnen sind.
Na dann.
Jetzt kennst Du auch den Unterschied C zu Assembler :0)
Die Bilder oben
http://www.mikrocontroller.net/attachment/preview/136650.jpg
sind übrigens ohne jedes Filter, die Abtastrate ist so hoch, dass der
Innenwiderstand des R2R und die Eingangskapazität des Scopes reichen.
Schönen Sonntag noch allerseits
Werner
@ Fantamann (Gast)
> 20120305_100545.jpg> 2,6 MB, 0 Downloads> 20120305_100730.jpg> 2,3 MB, 0 Downloads>Aufnahmen bei 20kHz ohne Filter gemacht.
Und ohne Hirn. Lies mal was über Bildformate!
ich hätts besser gelassen :-)
Ein Haufen selbstgefälliger Prinzipienreiter seid ihr. Sorry
wenn ich das jetzt mal sagen musste :-)
Warum gibts denn keine automatische Skalierung der Bilder? Das ist doch
in jedem anderen Forum auch so. Hab mich jedenfalls drauf verlassen.
@ Fatamann (Gast)
>Warum gibts denn keine automatische Skalierung der Bilder?
Weil das hier kein Kindergarten- und Klingeltonform ist sondern man von
den Leuten erwartet und ihnen zutraut, ein wenig mitzudenken.
>>Warum gibts denn keine automatische Skalierung der Bilder?>> Weil das hier kein Kindergarten- und Klingeltonform ist sondern man von> den Leuten erwartet und ihnen zutraut, ein wenig mitzudenken.
So kann man es auch nennen. Du fährst auch ohne Sicherheitsgurt, weil
man von dir erwarten kann, dass du gefälligst nicht durch die
Windschutzscheibe fliegst. Du bist ja schließlich erwachsen.
Fantamann schrieb:> Du bist ja schließlich erwachsen.
Du nicht?
Woher soll den deine automatische Skalierung wissen, welches Bild in
welcher Auflösung vorliegen muss, damit man sinnvoll seinen Inhalt
darstellen kann?
Ich hab' sie jetzt verkleinert, das nächste Mal nimmst du bitte ein
Bildbearbeitungsprogramm deiner Wahl und machst sie so groß, wie es
für deinen Zweck sinnvoll ist.
> Ich hab' sie jetzt verkleinert, das nächste Mal nimmst du bitte ein> Bildbearbeitungsprogramm deiner Wahl und machst sie so groß, wie es> für deinen Zweck sinnvoll ist.
merci
Hallo,
ist im grünen Bereich, wie zu erwarten.
> ... , der FILTER am Ausgang löst das Problem.> Den hast du aber noch nicht, darum siehst du unschöne Signale.> Der Filter ist aber notwendig.
So kommen diese Aussagen zustande.
> Für eine reine Softwarelösung schon sehr gut.> Wenn man höhere Takte braucht nimmt man eh Hardware.
Es wird nicht unterschieden, das ist halt Software DDS.
> .... kommt evtl. etwas raus, sicher nicht viel Gutes.
Wenn ich nun einen Sinus kaufen wollte, welchen würde ich nehmen ?
Zumal der Preis gleich ist.
Sinus ist nun Peanuts.
Es wurde dann auch von Recht- und Dreieck bzw. Sägezahn geschrieben.
Diese Kurvenformen sind ungleich schwieriger zu erzeugen.
Da hilft Dir das Filter nix mehr.
Also wenn Deine Abtastfrequenz so niedrig ist , so dicht an der
Sollfrequenz sitzt.
Grüße Werner
wo es dunkel ist.
Ich kann das leider nicht photographieren,
das sind eigentlich durchlaufende Muster.
So habe ich 'mal lange belichtet.
Das sind 444 kHz aus dem 88DDS.
Da könnte man filtern, es lohnt aber nicht. (evtl. für einen Sinus)
Jenseits 150 oder 200 kHz fehlt Auflösung für Phase und Amplitude.
Du kannst nicht gegen die 12 Bit Phase und 10 Bit D/A dieser AD9XYZs :0)
Heinz schrieb:> spess53 schrieb:>>>> In der letzten Elektor gab es da einen Artikel, der sich damit>>>> beschäftigt. Vielleicht als Anregung:>>>> http://www.elektor.de/jahrgang/2012/marz/sdr-mit-a...>>>> Die schreiben, dass sie ein brauchbares Signal um die max. 200 kHz>>>> erhalten (kombiniert C/Assembler).>>> P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der>>> Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.>> Ist auch nur Teil 1 eines Artikels. Geplant ist ein Empfänger für den>> deutschen Wetterdienst.>> MfG Spess> Mag sein, Spess, aber die Elektor habe ich nach dem Titelbild gekauft.> Auf dem stand SDR. Nur drinn war ziemlich wenig SDR.
Hallo,
den Artikel habe ich mir angesehen, wohl nur weil er so weit vom Thema
schien,
Ich weiss nicht genau was das werden soll.
Wenn es ein Sinusgenerator wird, dann ist dort auch ein schönens
Beispiel wie man den Jesper eine Nuance schlechter kopieren kann ...
Wozu dient der Interrupt, der die Samplerate versaut??
"Das Jittert enorm, aber im Mittel stimmt die Frequenz ... "
Betse Voraussetzungen für ein SDR ?
LOL
Grüße Werner
Nicht durch den Äther aber durch ein Kabel.
"The quick brown fox jumps .... "
( der Fachmann hört sofort es ist ASCII 7,E,2 50 BAUD und nicht BAUDOT )
QRG 147,2575 kHz (Space) & 147,3425 kHz (Mark) ~ 85 Hz shift.
:o)
Schade, Ulrich brachte immer den Kick.
Einen Takt extra, ein Bit mehr.
Solange ich an dem DDS bastele...
Unterwegs habe ich den einen oder anderen Takt oder
das eine oder andere Bit verloren.
Der interne PulUp hatte immer auf "out PORTx" Probleme gemacht.
Wie ich erst jetzt lese kann man das im 48/88/168 abwählen ...
Wahlweise PB0..3 ~ entspricht Bit 8. OK, übersehen.
Nun denn, sei es drum.
Den zweiten Kondensator habe ich nie gebraucht.
So wie die Ports verteilt sind sehe ich ein Potential für
AM FM PM U/f einen VCO aus dem verbliebenen AD Eingang.
Wieder kein Hexenwerk ...
Ob ein 100 kHz FM Sender Sinn macht ?
Zumindest ein schöner U/f Konverter kann das werden
P.S. Das findet keiner interessant ?
Werner schrieb:> Ob ein 100 kHz FM Sender Sinn macht ?
Bei 100kHz sendet immer noch Loran C Navigationssignal.
Auch ist die Bandbreite eines FM-Senders wesentlich groesser als bei AM
so das es keinen Sinn macht bei niederigen Frequenzen.
Bei deiner PSK Modulation schaltest du hart um, damit wird deine
Signalbandbreite ziemlich gross. Besser ist das vor dem umschalten der
Phase die Amplitude zu senken und danach wieder anzuheben.
Helmut Lenzen schrieb:> Bei 100kHz sendet immer noch Loran C Navigationssignal.
Ich will natürlich nicht "on air" gehen.
Langwelle wäre besser als Frequenz gewählt gewesen.
Mein Grundstück ist auch kaum 50 Meter lang :0)
> Bei deiner PSK Modulation schaltest du hart um, damit wird deine> Signalbandbreite ziemlich gross.
Ja, klar.
Senden dürfen die meisten nicht. Manche auf manchen Frequenzen.
Wenn das durch einen Sender mit ein paar RESONANTEN Stufen ginge,
wäre das sowieso weg.
Auf Langwelle hätte man in resonanten Senderstufen eher das Problem
Sendeantenne und Senderstufen breitbandig genug zu bekommen ?
Drahtgebunden, wie bei den Telefonmodems stört das wohl nicht.
> Besser ist das vor dem umschalten der Phase die Amplitude> zu senken und danach wieder anzuheben.
Macht man das so im realen Leben ?
Ich will ja nur probieren wieviele Funktionen man in so einen Jesper
packen kann.
Also als ein EinChip ATmega AVR "custom build" IC.
FAXen machen, HELL schreiben ? usw.
Bzw. ein möglichst vielseitiger Funktionsgenerator.
Sorry; ich habe Fantamans Post unbewusst gekapert,
aber Sinus kommt immer wieder vor :0))
Ich glaube ein paar Dinge gemacht zu haben, die ich so noch nicht
gesehen habe und jede Idee oder Verbesserung ist gerne gesehen.
Natürlich auch Links, falls es das schon gab / gibt und ich es einfach
nicht kenne.
Werner schrieb:>> Besser ist das vor dem umschalten der Phase die Amplitude>> zu senken und danach wieder anzuheben.>> Macht man das so im realen Leben ?
PSK31 Modems machen das so. Dann braucht man dahinter nichts mehr zu
filtern.
http://www.moetronix.com/ae4jy/files/winpsktech10.pdf
Helmut ist HAM ?
>> Dann braucht man dahinter nichts mehr zu filtern.> This means that the transmitter must not compress or limit the audio> waveform otherwise the signal will again get much wider in bandwidth.> This is perhaps the biggest problem with setting up a PSK31 station.> It is very easy to overdrive and distort the PSK31 signal by applying> the relatively high amplitude audio signal from the PC soundcard into> the low level microphone input of a SSB transmitter.
Ok, kenne mich da nicht aus.
Ein SSB Sender sollte bereits einen Haufen Filter darstellen, wenn er
nicht übersteuert wird ?
Das geht leicht in die - 80 bis 90dB > 3kHz.
Wenn man denn nur eine kleine Dose bauen wolte aus der auch (B)PSK
kommt...
73 de DB7EW
Werner schrieb:> Helmut ist HAM ?
Nö. Habe so was nur als interesse mal ausprobiert.
Habe auch den Decoder dazu. Das ganze läuft auf einer ARM uC mit 50 MHz.
Hatte heute Nachmittag mal ausprobiert wie stark man das Signal noch mit
Rauschen überlagern kann. Auf dem Skope sah man das Signal im Rauschen
nicht mehr aber der Decoder konnte es noch einwandfrei decodieren.
Platinchen ist ca 80x80 mm.
Helmut Lenzen schrieb:> Auf dem Skope sah man das Signal im Rauschen nicht mehr aber> der Decoder konnte es noch einwandfrei decodieren.
Ja, das ist so.
Hallo,
man kann damit auch wobbeln.
( die dots im Bild stammen von meinem Speicherscope,
sieht life besser aus)
Die Rate der Frequenzänderung steckt in r20 ( SPEED )
Die Spanne mache ich durch Neustart in definierten Intervallen.
Die Hardwaretimer und ein Interrupt taugen auch.
Die Frequenzänderung / Zeit ist konstant und in 255 Schritten wählbar.
Grüße Werner
P.S. Wieder 9 Takte wie Jesper aber doppelte Auflösung in zwei
Dimensionen & eine Funktion extra.
1
SweepLoop:
2
3
; 2.44 Mc sampling rate
4
; 25 Bit resolution on frequency
5
; 360/512° resolution on phase
6
; 8 Bit resolution on voltage
7
; Data tables from $0100 to $03FF in SRAM
8
; Sweep starts at selected frequency
9
; SPEED controls the rate of change
10
; To control the span, restart or stop it after a certain time...
11
12
cbi DDRB,1 ; Bit 8 is off
13
cbi PORTB,1
14
cbi DDRC,0 ; deglitch not needed
15
cbi PORTC,0
16
cbi DDRC,1 ; addon not wanted
17
cbi PORTC,1
18
19
RestartSweep:
20
21
clr r23 ; r23 temporary accumulator for rate of change
22
clr r27 ; r27 empty, used to add carry only
23
24
; restore adder value
25
mov r24,r4
26
mov r25,r5
27
mov r26,r6
28
; reset accumulatar
29
clr r28
30
clr r29
31
ser r30
32
ldi r31,3
33
34
ser MODE ; make sweep restartable at any time ( fake OffMode )