Gast
#966029
Hallo, wie kann ich am geschickstesten eine DD Synthese in C Programmieren? Wie kann ich die Funktionswerte am besten abspeichern und dann ausgeben? Gruß Marc
|
Anzeige
|
Wie am geschicktesten DD Synthese in C Programmieren?
Gast
#966029
Hallo, wie kann ich am geschickstesten eine DD Synthese in C Programmieren? Wie kann ich die Funktionswerte am besten abspeichern und dann ausgeben? Gruß Marc
Gast
#966078
was ist DD und mit was isst man es?
Gast
#966108
DD Synthese =>DDS => direct digital synthesis.... Ringspeicher, mit einer Periode des gewünschten Signals. Dann zum Pointer, der darauf zeigt, immer das Tuning-Byte/Word dazuaddieren und den Wert an der entsprechenden Speicherstelle via DAC, PWM oder WDTW ausgeben. Aber da findet man echt viel im Netz dazu, ist ja auch nicht so schwierig; das sind etwa zwei Zeilen C-Code plus noch der Datensatz. Aber was ist eigentlich genau deine Frage?
Gast
#966127
@Ralf Schwarz: Du hast meine Frage eigentlich weitestgehend beantwortet. (Stichwort Pointer, Ringspeicher!) Dankeschön
Gast
#966144
OK habe nun die Daten im Array nun komm ich aber nicht weiter mit dem Zeiger auslesen. Ich dacht an so etwas: unsigned char iArray[251]; z = &iArray[0]; z++; z++; PORTD = *z; Geht das vom Prinzip her? Als was muss ich z deklarieren? Kann ich ein Byte einfach überspringen indem ich z++; schreibe oder wie macht man das?
Gast
#966182
>Als was muss ich z deklarieren?
>Byte einfach überspringen indem ich z++;
z++ geht nur zum Nächsten. Zum Überspringen musst du mindestens zwei
addieren, oder das tuningbyte x. Bei dem Tuningbyte ist allerdings der
Überlauf besonders zu beachten! Mein Beispiel ist da noch nicht
"bombenfest"
@ Matthias Lipinsky Nicht dein Tag heute? ;-) Das > if ( z > sizeof(iArray)/sizeof(iArray[0]) ) ist doch das selbe wie > if ( z > 251 ) und müsste, damit es keinen amoklaufenden Pointer gibt, zumindest so heissen > if ( z >= 251 ) damit nicht hinter das Array gegriffen wird. Leider ist es auch dann noch falsch, weil z ja irgendein Wert (Pointer) ist. Fast sicher ist z aber kein Wert zwischen 0 und 250... >int8_t iArray[251]; Warum nicht einfach eine Array-Größe von 256 definieren? Dann geht das mit dem Überlauf fast von alleine. So z.B.:
Die Welt ist einfach und schön rund, wenn für binäre Prozessoren auch binär gedacht wird.
Gast
#966338
>Nicht dein Tag heute? ;-)
Sieht so aus..
Ich leg mich nochmal hin
Gast
#966751
Klasse hat geklappt. Vielen Dank!
Das Array ging nur bis 251 weil ich zum testen nen Sinus ausgerechnet
hab:
for (l=0;l<251;l++) {
x = (sin(0.025*l))*127.5 +127.5;
iArray[l] = x;
}
(ab 252 ginge der x Wert über 127.5 und es würde einen Zacken geben. Die
Kurve hat sowieso einen Zacken weiß auch nich warum aber zum testen
isses OK, besser als 200 Werte von Hand auszurechnen^^)
Hier meine Provisorische Lösung:
signed char iArray[251];
unsigned char *z = &iArray[0];
unsigned char *save = &iArray[0];
z++;
zaehler++;
if (lol >251) {
z = save;
zaehler=0;
}
PORTB = *z;
Eins noch: Was macht dieser Befehl: z += x; ?
>>Eins noch: Was macht dieser Befehl: z += x; ?
Das ist dasgleiche wie z = z+x; Das geht auch mit weiteren Operatoren.
Cheers
Detlef
Wie schon gesagt, (Matthias war schlecht aufgestanden :-) das > if (lol > 251) { geht schief, weil dein Array zwar 251 Elemente hat, aber die Indices für diese Elemente zwischen 0 und 250 liegen müssen. Du lässt aber einen Index von 251 noch ohne Überlauf durchgehen!! Korrekt müsste es so heissen: > if (lol >= 251) { Dann tauchen auch diese Zacken nicht mehr auf. Allerdings ist auch deine Berechnung etwas gewöhnungsbedürftig... So wäre sie vielleicht etwas besser durchschaubar:
Alternativ auf dein 251 Elementiges Array
Gast
#967483
Ah da kommt dieser zacken her. (Das lol soll eigentlich zaehler heißen und cArray wäre sicher sinvoller). Ich muss sagen deine Berechnung von dem Array gefällt mir sehr. Is viel genauer als meine. Dankeschön!!!
Gast
#970491
Kaum zu glauben, dass die Schleife 256 mal durchlaufen wird. Ich würde eher sagen, gar nicht. Aber ich kann die gewollte Pfiffigkeit erkennen :-)
Um das Niveau dennoch hoch zu halten, spare ich mir die Korrektur. @ Schwurbl > for (w=0; w; w++)... Gut, wenigstens einer merkt es ;-) > ...// solange, bis w wieder 0 ist, also 256 mal Die Funktionsweise ist im Kommentar doch klar beschrieben :) > Um das Niveau dennoch hoch zu halten, spare ich mir die Korrektur. Ganz in deinem Sinne...
Gast
#996040
Die Tabelle unbedingt 256 Bytes groß machen, spart die Abfrage nach >249. Der Phasenakkumulator muss doch viel breiter als der Pointer sein. #define hi 0 //je nach Endianess des Zielsystems union {t_int32 i32;t_int8 Byte[4]} ddsSum,ddsAdd; ddsSum.i32 += ddsAdd.i32; PORTB = iArray[ddsSum.Byte[hi]]; Evtl. löst der Compiler folgendes elegant: PORTB = iArray[(ddsSum.i32+=ddsAdd.i32)>>24]; Eine DDS ist in Assembler wesentlich eleganter. Beitrag "Re: atmega8, pwm, tongenerator ganz einfach" Ganzen Thread lesen. "poor man's dds"
Gast
#996088
Hier noch was Interessantes: Beitrag "Würde gerne Assembler in C umschreiben, aber ich blick's net" Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|