mikrocontroller.net

Forum: Compiler & IDEs Wie am geschicktesten DD Synthese in C Programmieren?


Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was ist DD und mit was isst man es?

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DD Synthese =>DDS => direct digital synthesis....

Autor: Ralf Schwarz (spacedog) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ralf Schwarz:

Du hast meine Frage eigentlich weitestgehend beantwortet. (Stichwort 
Pointer, Ringspeicher!) Dankeschön

Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Als was muss ich z deklarieren?
int8_t   iArray[251];
uint8_t  *z           = &iArray[0];


//-- zyklisch aufrufen, zB im Timerinterrupt
z += x;      // x: Tuningbyte
if ( z > (sizeof(iArray)/sizeof(iArray[0]) )
{
 z -= (sizeof(iArray)/sizeof(iArray[0]);
}
PORTD = *z;

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  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.:
int8_t   iArray[256];
uint8_t  z;
// -- zyklisch aufrufen, zB im Timerinterrupt
z += x;            // x Tuningbyte
PORTD = iArray[z]; // z kann nie größer werden als das Array (0...255)

Die Welt ist einfach und schön rund, wenn für binäre Prozessoren auch 
binär gedacht wird.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nicht dein Tag heute? ;-)

Sieht so aus..

Ich leg mich nochmal hin

Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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; ?

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Eins noch: Was macht dieser Befehl: z += x; ?

Das ist dasgleiche wie z = z+x; Das geht auch mit weiteren Operatoren.

Cheers
Detlef

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
char iArray[256]; // sollte das nicht besser cArray heissen?
unsigend char w;
:
for (w=0; w; w++) { // solange, bis w wieder 0 ist, also 256 mal
  iArray[w] = (char)(sin(((float)w/256)*6.283185))*127.5 +127.5;
}

Alternativ auf dein 251 Elementiges Array
char iArray[251]; // sollte das nicht besser cArray heissen?
unsigend char w;
:
for (w=0; w<=250; w++) {
  iArray[w] = (char)(sin(((float)w/251)*6.283185))*127.5 +127.5;
}

Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!!!

Autor: Schwurbl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kaum zu glauben, dass die Schleife 256 mal durchlaufen wird. Ich würde 
eher sagen, gar nicht. Aber ich kann die gewollte Pfiffigkeit erkennen 
:-)
char iArray[256]; // sollte das nicht besser cArray heissen?
unsigend char w;
for (w=0; w; w++) { // solange, bis w wieder 0 ist, also 256 mal
  iArray[w] = (char)(sin(((float)w/256)*6.283185))*127.5 +127.5;
}

Um das Niveau dennoch hoch zu halten, spare ich mir die Korrektur.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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...

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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"

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.