Hallo,
wegen definierter Schleifendurchlaufzeit will ich Werte aus einer
Lookup-Table (Sinuskurve) nacheinander ausgeben. Allerdings funktioniert
das nicht. Von den 256 Werten werden nur die ersten 50 ausgegeben und
die restlichen Werte sind immer 0. Das ganze basiert übrigens auf Jesper
Hansen MiniDDS (http://www.myplace.nu/avr/minidds/index.htm).
Aufgerufen wird die DDS-Fkt. aus der main()-Fkt., ist also alles
eigentlich in C programmiert und wegen definierter
Endlosschleifendurchlaufzeit habe ich die DDS-Geschichte in Assembler
von o.g. Seite übernommen.
Der Code, separate Datei dds.S
Diese Endlosschleife ergibt einen Teil der Sinuskurve aus der
Loopkup-Table, nämlich exakt die ersten 50 Werte, also erster Wert =
0x80, letzter Wert = 0xF7. Auf dem Oszilloskop habe ich mir das
angesehen und festgestellt, daß es 200,00 Hz sind bei 7,3728 Mhz, bin
mir aber da nicht so sicher. Kurve übrigens im Anhang, die Schräge Linie
im Bild ist Teil der Sinuskurve, also nicht linear.
Wo ist der Rest der Werte?
Der Aufruf aus der C-Funktion ist einfach nur dds();
Hi,
habe mir >Deinen< Code nicht wirklich angesehen, sondern die
Sinustabelle kopiert und den Rest angepasst.
Ausserdem hab ichs bei assembler belassen.
Gruss,
Ludger
Der Code an sich sollte eigentlich funktionieren.
Das .org 0x100 ist vermutlich das Problem, wenn Du C und Assembler
mischen willst.
Um den Code an 256 Byte Grenzen auszurichten wird align 8 verwendet.
@Ludger
!!!! Volltreffer !!!!
Es ist das ".align 8" nötig und nicht ".org 0x100" oder ".org 0x200".
Ich habe es gerade mal geändert und der Scope malt mir einen richtig
runden Sinus. Jetzt muß ich den ganzen Krams nochmal durchrechnen wegen
Grundfrequenz und Variation in festen, ganzen Schritten und dann wieder
aus der Endloschleife eine abbrechbare Schleife machen. Aber das hatte
ich schon, habs nur wegen des Fehlers rausgeschmissen.
@Torsten S.
Wenn du dir mal asm-Beispielcode in GCC und in einer separaten Datei
ankukkst, dan iwrst du sehen, das die Register ohne 'r' geschrieben
werden. Ist zwar ungewöhnlich, weil so Dingers wie "mov 16,24" und "ldi
16,24" zwei verschiedene Dingers sind ("mov Reg,Reg" vs. "ldi
Reg,Konst").
Danke an euch, vorallen Ludger!
Nichts zu danken!
Ich erzeuge mir in der Regel mit OBJDUMP ein Linker Listing. Da kann man
sehen, was der Linker an Assembler Code generiert hat und an welche
Stelle es gelinkt wurde.
Siehe makefile im angehaengten zip :-)
Das .align 8 bewirkt nur, dass das Folgende an einer >runden< Page
Adresse beginnt. Je nachdem wieviel Code noch vorher gelinkt wird, ist
das dann eben 0x200, 0x300, ..., 0x1f500, ..., 0x1ff00, usw.
Fuer die Sinustabelle in der dds ist es aber nur wichtig, genau eine
Page zu belegen, da dann das ZH Register beim Zugriff auf die
Sinustabelle immer gleich bleibt.