Hallo! Bin gerade beim Bau eines Sinusgenerators mit Hilfe eines Atmega8 und R2R-Widerstandsnetzwerk (8Bit). Soweit funktioniert das auch recht gut, allerdings ist die maximale Sinusfrequenz bloß bei etwa 1kHz und ich würde ca. 20 kHz benötigen. Ich vermute durch den Befehl "Incr" wird die ganze Sache so langsam? Wie könnte ich die Tabelle noch hochzählen? Danke für eure Antworten!! Ich verwende folgende Programmierung in Bascom: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $regfile = "m8def.dat" $crystal = 16000000 Config Portd = Output Dim Nummer As Byte Do Portd = Lookup(nummer , Sine_table) Incr Nummer Loop End Return Sine_table: Data 128 , 131 , 134 , 137 , 140 , 143 , 146 , 149 Data 152 , 155 , 158 , 162 , 165 , 167 , 170 , 173 Data 176 , 179 , 182 , 185 , 188 , 190 , 193 , 196 Data 198 , 201 , 203 , 206 , 208 , 211 , 213 , 215 Data 218 , 220 , 222 , 224 , 226 , 228 , 230 , 232 Data 234 , 235 , 237 , 238 , 240 , 241 , 243 , 244 Data 245 , 246 , 248 , 249 , 250 , 250 , 251 , 252 Data 253 , 253 , 254 , 254 , 254 , 255 , 255 , 255 Data 255 , 255 , 255 , 255 , 254 , 254 , 254 , 253 Data 253 , 252 , 251 , 250 , 250 , 249 , 248 , 246 Data 245 , 244 , 243 , 241 , 240 , 238 , 237 , 235 Data 234 , 232 , 230 , 228 , 226 , 224 , 222 , 220 Data 218 , 215 , 213 , 211 , 208 , 206 , 203 , 201 Data 198 , 196 , 193 , 190 , 188 , 185 , 182 , 179 Data 176 , 173 , 170 , 167 , 165 , 162 , 158 , 155 Data 152 , 149 , 146 , 143 , 140 , 137 , 134 , 131 Data 128 , 124 , 121 , 118 , 115 , 112 , 109 , 106 Data 103 , 100 , 97 , 93 , 90 , 88 , 85 , 82 Data 79 , 76 , 73 , 70 , 67 , 65 , 62 , 59 Data 57 , 54 , 52 , 49 , 47 , 44 , 42 , 40 Data 37 , 35 , 33 , 31 , 29 , 27 , 25 , 23 Data 21 , 20 , 18 , 17 , 15 , 14 , 12 , 11 Data 10 , 9 , 7 , 6 , 5 , 5 , 4 , 3 Data 2 , 2 , 1 , 1 , 1 , 0 , 0 , 0 Data 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 Data 2 , 3 , 4 , 5 , 5 , 6 , 7 , 9 Data 10 , 11 , 12 , 14 , 15 , 17 , 18 , 20 Data 21 , 23 , 25 , 27 , 29 , 31 , 33 , 35 Data 37 , 40 , 42 , 44 , 47 , 49 , 52 , 54 Data 57 , 59 , 62 , 65 , 67 , 70 , 73 , 76 Data 79 , 82 , 85 , 88 , 90 , 93 , 97 , 100 Data 103 , 106 , 109 , 112 , 115 , 118 , 121 , 124
Ich bevorzuge ja Assembler, aber "Incr" sollte selbst in Bascom nicht sehr viele Prozessortakte benötigen. Allerdings nützt "$crystal = 16000000" nicht viel, wenn der µC nicht mit 16 MHz getaktet wird. Wie betreibst du denn den Mega8?
Danke für Deine Antwort! Die 16Mhz passen schon, ich habe einen externen 16Mhz Quarz an den Atmega8 angeschlossen. Gruß Dennis
Xyz Zyx schrieb: > Die 16Mhz passen schon, ich habe einen externen 16Mhz Quarz an den > Atmega8 angeschlossen. Auch die Fuses passend gesetzt?
Jop, die Fuses müssten auch passen (siehe Bild), oder? Gruß Dennis
20 kHz sind aber etwas viel verlangt: 16.000.000 / 20.000 = 800 man hat also 800 Prozessortakte frei um 256 DA-Ausgaben zu machen. Das sind 3,125 Takte für jeden DA-Wert. DAS REICHT BESTIMMT NICHT! Allerdings sollten 4...5 kHz schon drin sein...
Hallo, teste bitte mal diese HEX-Datei deines Programms auf deiner Hardware. AVR atMega8 Frequenz 16 MHz DAC Ausgabe an PortD Was zeigt der Frequenzzähler an ? _
Bernie schrieb: > Ich bevorzuge ja Assembler, aber "Incr" sollte selbst in > Bascom nicht sehr viele Prozessortakte benötigen. > > Allerdings nützt "$crystal = 16000000" nicht viel, > wenn der µC nicht mit 16 MHz getaktet wird. > > Wie betreibst du denn den Mega8? Auch bei tatsächlichen 16 MHz wirds in Assembler knapp, wenn man das in einer Schleife erledigen will. Gehen wir davon aus, die Tabelle liegt im SRAM (wäre am schnellsten), dann brauchst du immer noch 5 Takte pro Wert: Laden mit LD, inkrementieren mit INC, ausgeben mit OUT und springen mit RJMP (2 Takte). Frequenz:
1 | 16 000 000 / 256 / 5 = 12 500 Hz |
Durch einen Trick kannst du auf die RJMP verzichten, wenn du das Programm linear schreibst und nur zu Zeiten springst, in denen sich der auszugebende Wert ein paar Takte lang nicht ändert (da sind ein paar aufeinander folgende Stellen mit 0 in der Tabelle). Dann sind es nur noch 3 Takte je Wert, und die Rechnung ändert sich wie folgt:
1 | 16 000 000 / 256 / 3 = 20 833 Hz |
Noch schneller gehts, wenn man keine Tabelle verwendet, sondern die Werte per LDI direkt ins Programm schreibt:
1 | 16 000 000 / 256 / 2 = 31 250 Hz |
Wenn man unbedingt den ATmega8 nehmen will, der ab 16 MHz schon am Ende ist, dann bleibt ja noch, die Tabelle nicht gar so fein zu unterteilen, also zum Beispiel nur 128 Werten zu verwenden. Oder man weicht auf geeignetere Hardware aus. :-)
Wenn man es drauf anlegt, kommt man in ASM mit 2 Takten/Sample aus. - Da war jemand anders schneller ... Wie sieht denn das aus, was der Compiler erzeugt? Gruß Jobst
Selbst in Assembler wirds eng: Es klappt auch nur, wenn die Tabelle genau an einer Adresse anfängt, bei der XL = 0x00 ist. Der µC ist dann auch nicht in der Lage, irgend etwas Anderes (Reaktion auf Tasten, ...) zu bearbeiten. da_loop: inc XL 1 ld Tmp0, X 2 out PortD, Tmp0 1 rjmp da_loop 2 ===== Benötigte Takte: 6 Das ergibt die erforderliche Taktfreqenz: 6 256 20.000 = 30.720.000 MHz
Wenns nicht schnell genug ist, muss man entweder das Increment pro Durchlauf vergrößern oder die Tabelle kleiner machen, so dass insgesamt von mir aus nur 100 Werte pro Sinusschwingung am DA landen.
@Uwe S. Habe die HEX-Datei getestet. Leider erreiche ich so nur etwa 700Hz. Trotzdem Danke! @Markus Weber Habe auch schon eine kleinere Tabelle benutzt, jedoch schafft er dann auch nicht höhere Frequenzen!? Wie funktioniert denn der Generator hier? : http://www.dl8nci.de/DDS-001.html Gruß
@ Markus Weber Warst ja etwas schneller. Aber "ld X" braucht bei mir zwei Takte! ;-)
Bernie schrieb: > @ Markus Weber > > Warst ja etwas schneller. > Aber "ld X" braucht bei mir zwei Takte! ;-) Hmmm, wir hatten die gleichen Ideen. :-) Bei "LD" steht in meinem Datenblatt, dass er nur einen Takt braucht (wenn nicht Inkrement oder Dekrement dabei ist). Dokument "Instruction Set", Seite 89. Kann aber sein, dass das ein Fehler ist.
Xyz Zyx schrieb: > Habe die HEX-Datei getestet. Leider erreiche ich so nur etwa 700Hz. > Trotzdem Danke! ja ich habe auch mal schnelle das Programm auf einen atMega32 mit 14,7456MHz geladen und mit einem 100MHz Oszilloskop die Frequenz gemessen: 711Hz. Die Idee, die Daten aus dem SRAM zu holen habe ich mit LunaAVR umgesetzt und da liegt die Frequenz des Bit7 bei 3,03KHz @14,7456MHz Takt. .
Hat noch niemand hier was von DDS gehört? Darauf sollte man eigentlich aber schon so drauf kommen.
Noch'n Hex-File. 2-Takter ... :-D Sollte bei 16MHz 31.25kHz produzieren ... Gruß Jobst
Sam .. schrieb: > Hat noch niemand hier was von DDS gehört? Und - das behebt nun sein Problem - oder wie? Gruß Jobst
Jobst M. schrieb: > 2-Takter ... :-D Wollte auch gerade meinen 2-Takter posten. Ich schätze, du hast es ähnlich gelöst:
1 | loop: |
2 | ldi r16, 128 |
3 | out PortD, r16 |
4 | ldi r16, 131 |
5 | out PortD, r16 |
6 | ldi r16, 134 |
7 | out PortD, r16 |
8 | ldi r16, 137 |
9 | out PortD, r16 |
10 | ldi r16, 140 |
11 | out PortD, r16 |
12 | ldi r16, 143 |
13 | out PortD, r16 |
14 | . |
15 | . |
16 | . |
17 | ldi r16, 118 |
18 | out PortD, r16 |
19 | ldi r16, 121 |
20 | out PortD, r16 |
21 | ldi r16, 124 |
22 | out PortD, r16 |
23 | rjmp loop |
Ziegenpeter schrieb: > Ich schätze, du hast es ähnlich gelöst Jain. Ich springe bei den 0-en. Du hast eine Stufe während des RJMPs ... Gerade stelle ich noch einen Fehler fest ... Grmph ... Nun aber - V3 :-D Gruß Jobst
Der Trick besteht darin, je nach gewünschter Frequenz Tabellenwerte entweder zu überspringen oder aber mehrfach auszugeben. Stichwort Phasenakkumulator. Jesper hat das vor 12 Jahren schon vorgemacht: http://www.myplace.nu/avr/minidds/index.htm XL
Bernie schrieb: > 20 kHz sind aber etwas viel verlangt: > > 16.000.000 / 20.000 = 800 > > man hat also 800 Prozessortakte frei um 256 > DA-Ausgaben zu machen. Das sind 3,125 Takte für > jeden DA-Wert. DAS REICHT BESTIMMT NICHT! Warum 256 Werte für eine Periode ausgeben? Da reichen wesentlich weniger Werte. Stichwort DDS. Jobst M. schrieb: > Sam .. schrieb: >> Hat noch niemand hier was von DDS gehört? > > Und - das behebt nun sein Problem - oder wie? Ja. Bei höhren Frequenzen kann man den Phasenschritt wesentlich grösser machen. Also keine 256 Werte pro Periode. Das Filter am Ausgang rekonstruiert daraus wieder einen Sinus. Und damit kommt man dann auch höher in der Frequenz. Axel Schwenke schrieb: > Jesper hat das vor 12 Jahren schon vorgemacht: @Axel Es dauert halt bis sich so was rumspricht :=)
Helmut Lenzen schrieb: > Jobst M. schrieb: >> Sam .. schrieb: >>> Hat noch niemand hier was von DDS gehört? >> >> Und - das behebt nun sein Problem - oder wie? > > Ja. Nein > Bei höhren Frequenzen kann man den Phasenschritt wesentlich grösser > machen. Also keine 256 Werte pro Periode. Das Filter am Ausgang > rekonstruiert daraus wieder einen Sinus. Und damit kommt man dann auch > höher in der Frequenz. Mir ist durchaus bewusst, wie ein DDS-Generator arbeitet. Trotzdem behebt das das Problem nicht. Nochmal zum mitschreiben: Der TO benötigt in seinem Programm offenbar 90 Takte, um einen Sample auszugeben. Die Frage ist, warum ist das so? 'Nimm DDS' beantwortet diese Frage nicht. Gruß Jobst
Jobst M. schrieb: > behebt das das Problem nicht. Nochmal zum mitschreiben: Der TO benötigt > in seinem Programm offenbar 90 Takte, um einen Sample auszugeben. > Die Frage ist, warum ist das so? Er hat sein Programm in BASIC geschrieben. Da muß ich keine weiteren Details wissen. In Ermangelung einer Beschreibung, welches Problem er lösen wollte, können wir noch nicht mal sagen ob sein Lösungsansatz überhaupt taugt. Aber BASCOM erscheint mir schon mal als schlechte Wahl. XL
Hallo! Danke für eure Antworten! Habe nun noch etliche Versuche mit niedrigerer Auflösung gemacht (7Bit, 6Bit, 5Bit...) und trotzdem noch gute Signalkurven gemessen. Nun schafft er etwa 15kHz ;) das ist für die jetzigen Bedürfnisse ausreichend. Danke für die Bemühungen Gruß Dennis
Geht scheinbar auch 1Hz bis 200 kHz problemlos, vielleicht kannst du die Technik ja in dein Basic portieren: http://avr.myluna.de/doku.php?id=de:ddsgen.luna
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.