mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik wieder einmal dds


Autor: technikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte einen Signal mit dem dds Verfahren auf meinem ATmega32 
ausgeben.

Jetzt habe ich hier im Forum folgende Formel zur Bestimmung des 
Additionswertes (Tabellenzähler):
Additionswert = Ausgabefrequenz * Auflösung Tabellenzähler * Nachladewert_Timer / F_CPU 

Nutze ich einen 16Bit Tabellenzähler
 //Timer ISR
Tabellenzaehler+=Additionswert;
//Auf Tabellenlänge 2048
OFFSET= STEP / 32;
OCR1BL=pgm_read_byte(&signal[OFFSET]);

funktioniert alles einwandfrei. Ich bekomme das Signal mit relativ 
genauer Frequenz ausgegeben.

Nun möchte ich aber einen 32Bit Tabellenzähler nutzen um die Auflösung 
der Wunschfrequenz zu erhöhen.

Wenn ich die oben angegebene Formel benutze und folgendes Rechne:
 (50 * 0xFFFFFFFF * 256)/16000000UL) 

komme ich auf einen Wert (Taschenrechner) von: 3435974

Soweit so gut

Tabellenzähler deklariere ich jetzt als uint32_t und den Additionswert 
habe ich zum Test als Konstante mit dem Ausgerechneten Additionswert 
festgelegt.

Die ISR sieht so aus:
 //Timer ISR
Tabellenzaehler+=3435974;
//von 32 Bit auf Tabellenlänge 2048 
OFFSET= (uint16_t)(Tabellenzaehler / 2097152UL); 
OCR1BL=pgm_read_byte(&signal[OFFSET]);

Leider stimmt die Frequenz des Ausgegebenen Signals nicht mehr.


Jetzt habe ich den Additionswert mit zwei Tastern (Additionswert+=10 
bzw. Additionswert-=10) einstellbar gemacht und den Additionswert bei 
50Hz mit JTAG Debugger ermittelt. Der Wert liegt bei ~50Hz bei 4026386.
Eingesetzt in die ISR komme ich lässt sich das Ergebnis bestätigen.


Leute, kann mir jemand erklären wo mein (Denk)Fehler liegt ?
Bitte keine Diskussionen um das Konzept (Tabellenlänge, 32Bit 
Tabellenzähler, etc.).



Danke
technikus

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es liegt eventuell daran, dass aufgrund der 32bit Division die 
Interruptfrequenz runter geht, da der AVR zu langsam ist.

Autor: technikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich sehe gerade das durch das ganze Probieren mein Sprachzentrum gestört 
wird ;-)
Da der Controller recht "lahm" geworden ist, habe ich mir mal das AVR 
Studio .lss File  angeschaut.
In der ISR zähle ich 67 Assembler Befehle. Ich habe zwar wenig Ahnung 
von Assembler, da im Programm aber sonst nichts passiert, denke ich das 
hier jede ISR sauber durchgearbeitet wird und dann noch einige Takte 
zwischendurch "übrig" sind.

Trotzdem DANKE für deinen Ansatz!


LG
technikus

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einer der Assembler Befehle dürfte ein rcall sein. Dahinter steht dann 
vermutlich irgendwas mit udivmod4 oder so was in der Richtung. Die 
Division dauert aus meiner Erfahrung irgendwas um die 50-100µs.
Bei 32bit benutzt der Compiler nämliche gerne Biblotheksfunktionen oder 
optimiert das ganze sonstwie nicht optimal, da hier (im Gegensatz zu 
16bit Operationen) nicht so viele Optimierungsvarianten einprogrammiert 
sind.

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man Glück hat, erkennt der Compiler die Zahl bei der Division als 
2er Potenz. trotzdem wird dann wohl eine schleife mit Shifts übrig 
bleibe. Besser ist es statt der Division einen Bitweise UND Verknüßfung 
zu nutzen:
also eher

OFFSET= Tabellenzaehler & 255

oder Offset gleich als unsigned Char definieren und nur

OFFSET= Tabellenzaehler

Autor: technikus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

im Anhang mal das was der Compiler aus der ISR macht.

LG
technikus

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, er ist immerhin so intelligent und erkennt die 2^n Division und 
macht da eine Schiebeoperation draus:
 8f8:  25 e1         ldi  r18, 0x15  ; 21
 8fa:  b6 95         lsr  r27
 8fc:  a7 95         ror  r26
 8fe:  97 95         ror  r25
 900:  87 95         ror  r24
 902:  2a 95         dec  r18
 904:  d1 f7         brne  .-12   

Aber diese Schleife wird 21x durchlaufen -> 147 Takte

Insgesamt komme ich auf über 250 Takte.

Autor: technikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
O.K.

147 Takte hört sich überhaupt nicht gut an :-(


Wie kriege ich denn soetwas
//von 32 Bit auf Tabellenlänge 2048 
OFFSET= (uint16_t)(Tabellenzaehler / 2097152UL);

knapper hin ?

Gruß
technikus

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  technikus (Gast)

>Wie kriege ich denn soetwas

>//von 32 Bit auf Tabellenlänge 2048
>OFFSET= (uint16_t)(Tabellenzaehler / 2097152UL);

>knapper hin ?

Wozu? Die Berechung des Frequenzeinstellwortes erfolgt EINMAL, die 
Akkumulation einer Variabelen ständig.

DDS_akku += Frequenzeinstellwort.

Einfacher gehts nicht. Aber das macht man nicht in C, sondern in ASM, 
sonst wird das alles reichlich albern und langsam. Das Programm kan man 
ja in C machen, die Hauptschleife aber als reinen ASM-Block.

Siehe DDS und

http://www.myplace.nu/avr/minidds/index.htm

MfG
Falk

Autor: Hans L. (hansl)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab das mal mit einem 3 Byte-Zähler auf dem Tiny2313 und R2R-
Netzwerk gemacht. Daher auch die Grundlagen.

(Das Einlesen über RS232 habe ich mal kurz entfernt.Hier wird nur
der Additionswert gesetzt.)

Man sieht, wie die DDS in Asembler sehr einfach zu realisieren ist.

gruß hansl

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.