DAC 8-Bit Atmega8 sehr langsam

#2922112
Lesenswert?

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
(Firma: guloshop.de) #2922160
Lesenswert?

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. :-)
Gast #2922179
Lesenswert?

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
(Firma: guloshop.de) #2922203
Lesenswert?

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.
#2922218
Lesenswert?

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.

.
Gast #2922276
Lesenswert?

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
#2922733
Lesenswert?

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 :=)
#2923562
Lesenswert?

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
#2923595
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren