www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wer kann mir das Prinzip des Codes erklären?


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich habe Jespers MiniDDS gefunden 
http://www.myplace.nu/avr/minidds/index.htm
Die Idee finde ich ganz interessant. Allerdings verstehe ich nur C und 
kein Assembler und schon gar nicht das Registergetrickse. Kann mir 
jemand das Prinzip seines Codes erklären? So weit ich verstehe, gibt er 
einen Analogwert gemäß der Datentabelle aus. Aber wie werden die 
Taktschritte berechnet? Bzw. wann welches Datum dran ist.

Autor: Carbolo Crb (carbolo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:-)

Ein guter C Programmierer ist meist auch in Assembler fit... mal so am 
Rande.

Die Lösung werde ich dir nicht komplett verraten, wäre ja witzlos.

Aber soviel: (Funzt in C analog dazu)

- Definiere einen Vektor mit Werten (Tabelle, x Array)

- Setze einen Pointer auf den Vektor, und lasse es wandern.

- Wandergeschwindigkeit des Pointers = Frequenz

- Die Taktschritte ergeben sich zwingend aus dem Quarz, das 
"Registergetrickse" ist im Gegensatz zu C genau voraussagbar...

Gruss

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Florian (Gast)

>kein Assembler und schon gar nicht das Registergetrickse. Kann mir
>jemand das Prinzip seines Codes erklären? So weit ich verstehe, gibt er

Kennst du das Prinzip von DDS?

http://www.analog.com/en/subCat/0,2879,770%255F843...

DDS ist im Prinzip nur eine Tabelle, die ausgegeben wird. Normalerweise 
ist in der Tabelle ein Sinus kodiert, aber auch andere Formen sind 
machbar. Im MiniDDS gibts Sinus, Dreieck und Rechteck.

Adressiert wird diese Tabelle über den Z-Pointer. Der Trick ist dabei, 
dass der eigentliche DDS-Akkumulator über den Z-Pointer gelegt wird. 
Dadurch spart man das umkopieren und das Ganze ist ziemlich schnell. Vom 
24 Bit DDS-Akku in R28,29 und r30 werden nur die oberen 8 Bit zur 
Adressierung der Tabelle mit je 256 Einträgen genutzt. Der Trick ist, 
dass diese obere Byte gleichzeitig das niederwertige Byte vom Z-Pointer 
ist. Das klappt aber nur durch die Ausrichtung der Tabellen auf einer 
256 Byte Adresse. Das macht

.org 0x100

>einen Analogwert gemäß der Datentabelle aus. Aber wie werden die
>Taktschritte berechnet? Bzw. wann welches Datum dran ist.

In jeder Schleife. Ist einfach nur ein Akku, zu dem ein bestimmter Wert 
immer wieder hinzuaddiert wird. Hier eben in 24 Bit.

MfG
Falk

Autor: Johannes Slotta (johanness)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau, ein R2R-Netzwerk setzt den aus der Tabelle ausgelesenen Wert in 
eine Spannung um. Die ist also proportional zum Wert in der Tabelle.

Wie er herausfindet, welche Zelle er nehmen soll: Er zählt eine 
24-bit-Variable hoch (addiert immer einen festen Wert drauf, je höher 
desto höher die Frequenz) und nimmt das höchstwertige Byte ("zufällig" 
r30), um die Tabellenposition zu bestimmen. Recht effizient denke ich.

Über r31 wird die Tabelle ausgewählt, r30 ist die Position in der 
Tabelle.

[Edit] argl Da freut man sich mal, dass man selbst was verstanden hat, 
und dann waren andere schneller![/Edit]

Autor: Michael Waiblinger (wiebel42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also bei der Initialisierung sezt du das Z Register (R30,R31) auf die 
(16bit) Addresse deiner Tabelle, da die Tabelle "nur" 256 Daten hat 
kannst du R31 somit auch schon wieder Vergessen das würde aber bei einer 
Inkrementierung von R30 auch automatisch nachgeführt werden.
Die Eigentlich Magie findet hier statt:
LOOP1:
    add    r28,r24      ; 1
    adc    r29,r25      ; 1
    adc    r30,r26      ; 1
    lpm            ; 3
    out    PORTB,r0    ; 1
    rjmp  LOOP1      ; 2 => 9 cycles

Hier wird der 24bit Inkrementierungswert (Proportional zur Frequenz) der 
in R24,R25,R26 gespeichert ist auf den Zeiger im Phasenraum 
(R28,R29,R30) aufaddiert, das ist erstmal einfach eine Zahl die immer 
grösser wird, umso schneller je grösser unsere Frequenz/Inkrement. Somit 
zählt er bis zum Überlauf und fängt dann wieder bei 0 an. Die MSBs 
dieses Zeigers im Phasenraum sind, oh wie praktisch, auch gleichzeitig 
unser Z Register, d.h. Z zeigt an die entsprechende Stelle unserer 
Tabelle und legt diesen Wert nach einem LPM, freundlich für uns in R0 
(und R1 für 16bit Werte) ab, wo wir es dann sogleich verwenden könnne.
Daher muss bei dieser Implementierung auch eine volle Periode in der .db 
sein.
Wenn man jetzt z.B. immer nur mit 1 inkrementiert, würde man 65535 mal 
den ersten Wert der Tabelle erhalten dann 65536 man den 2ten usw.
bei einem Inkrementierungswert > 65535, erhält man nicht einmal mehr 
jeden Wert der Tabelle sondern eben nur noch einen Bruchteil, was aber 
natürlich Sinn ergibt, da wir dann eine Frequenz erreicht haben die wir 
gar nicht mehr mit 256 Samplen abarbeiten könnten.

Am Ende kann man die Frequenz fein in 24bit Auflösung einstellen, von 
dem ersten Beispiel in dem man 256*65535 Takte braucht um die Tabelle 
auch nur ein einziges mal auszulessen bis hin zu 1Takt pro Tabelle 
auslesen (was natürlich nicht mehr sinnvoll ist, da es ja dann ein DC 
wäre). -wiebel

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe auch den Artikel Digitaler Funktionsgenerator.

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für Beantwortung der Frage, auch wenn mal wieder einige nicht 
lesen wollten und mir DDS erklären, auch wenn ich sagte, daß ich das 
verstanden habe... :-) Jetzt verstehe ich die Registerschieberei.

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.