Forum: Mikrocontroller und Digitale Elektronik ATmega1284P: Daten für FFT sammeln mit ADC Abtastrate


von Florian B. (blorianf)


Lesenswert?

Moin zusammen,

Kurz zu meinem Setup:
- Der ATmega1284P läuft mit einer Taktfrequenz von 16MHz
- Der interne ADC tastet ein Audiosignal mit 125kHz ab
- Innerhalb einer Schleife werden 256 Werte gesammelt (für eine FFT 
Berechnung)
1
void capture_wave (int16_t *buffer, uint16_t count)
2
{
3
  ADMUX = (ADMUX & ~(0x1F)) | (Q60 & 0x1F);
4
  do {
5
    ADCSRA |= (1<<ADSC);
6
    while(bit_is_clear(ADCSRA, ADIF));
7
    *buffer++ = ADCW;
8
  } while(--count);
9
}

Nun zu meiner Frage, diese bezieht sich auf die Frequenzzuordnung des 
Spektrums nach Berechnung der FFT:
Wie schaff ich es jeden der Abtastwerte zu speichern? Das sammeln der 
Daten mit obigem Code dauert nach Messung mit dem Oszi 28,67ms was 
bedeutet dass ich nicht jeden Abtastwert bekomme. Somit kann ich also 
nicht die 125kHz verwenden um nach der FFT dem Spektrum Frequenzen 
zuzuordnen.
Gibt es eine schnellere Möglichkeit die Werte zu speichern?

Vielen Dank und Viele Grüße

von Felix U. (ubfx)


Lesenswert?

Hast du interrupts aktiviert? Wenn nicht musst du das ADIF bit noch 
clearen. Dass ein SRAM Zugriff 25ms braucht, kann nicht sein.

Außerdem solltest du den ADC im free running mode betreiben.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Ohne ADCSRA oder besser das ganze Programm zu kennen, lässt sich wenig 
sagen; außer, dass statt ADIF ADSC benutzt werden sollte.

von Ingo Less (Gast)


Lesenswert?

Ich denke dein Ansatz ist schon etwas falsch. Der ADC selber läuft mit 
125kHz. Du musst, um zeitdiskret zu sein, den ADC immer im selben 
Zeitfenster anstoßen um auf die Frequenz rückschließen zu können.

Der ADC schafft nicht mehr als 15kS/s, somit würde ich auf 10kS/s runter 
gehen. Damit schaffst du Frequenzen bis 5kHz. Schneller ist der ADC 
leider nicht und mehr ist auch nicht möglich. Falls du mehr benötigst, 
brauchst du andere Hardware...

von S. Landolt (Gast)


Lesenswert?

"If a lower resolution than 10 bits is needed, the input clock frequency 
to the ADC can be higher than 200kHz to get a higher sample rate."

"Absolute accuracy at ADC clock = 1MHz: 3.25 LSB"

von c-hater (Gast)


Lesenswert?

Florian B. schrieb:

> Kurz zu meinem Setup:
> - Der ATmega1284P läuft mit einer Taktfrequenz von 16MHz
> - Der interne ADC tastet ein Audiosignal mit 125kHz ab

Wohl nicht.

Und falls doch, ist es völliger Schwachsinn, 16 (bzw. tatsächlich 10) 
Bit vom ADC verarbeiten zu wollen, weil bei dieser Samplefrequenz 
maximal noch so etwa 5..6Bit der Samples überhaupt noch irgendeine 
signifikante Beziehung zur Messgröße hätten, der Rest ist Rauschen.

Und leider nichtmal schönes Rauschen, sondern ziemlich "buntes". Wenn 
man sich die Mühe macht, die Farben zu lernen, geht da noch einiges, 
aber Wunder sind nicht zu erwarten. Und für das, was bei dieser 
Samplefrequenz tatsächlich noch geht, reichen definitiv die oberen 8Bit 
der Samples.

Also:

1)
Lernen, wie die ADC tatsächlich tickt. Nämlich 13 mal langsamer als du 
wahrscheinlich glaubst.

2)
ADLAR benutzen und nur ADCH auslesen. Spart einen Haufen von vornherein 
völlig nutzloser Rechnerei...

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Und bei solchen Faxen auch nicht den guten, alten Bjarne Stroustrup 
vergessen, der da meint, man sollte die passende Programmiersprache zum 
Problem waehlen.
Bei einer Vorgabe von: Darf hoechstens <=128 Takte dauern, wird das 
nicht unbedingt C sein.
Ich zitier' mal aus meinem LED-"Spektrumsanalyzer" aufm atmega16:
1
adc_irq:
2
    in r6,0x3f   ; save flag register
3
    ldi r25,0x08 ;
4
    out 0x38,r25 ; int ack
5
    in r25,0x05  ; read adc
6
    subi r25,128 ; convert to signed 8 bit
7
    st z,r25     ; store in buffer
8
    inc r30      ; increment buffer write pointer
9
    mov r25,r30
10
    andi r25,0x0f; every 16th time do not branch to nodisplay
11
    brne nodisplay
12
...
13
nodisplay:
14
    out 0x3f,r6  ; restore flag register
15
    reti

Dabei liegt der 256 byte grosse Puffer genau an einer 256-Byte 
Seitengrenze im RAM, weswegen man immer nur die unteren 8 bit vom 
z-Register incrementieren muss und durch den Ueberlauf von R30 auch der 
Puffer wieder von Anfang an beschrieben wird.


Gruss
WK

von Florian B. (blorianf)


Lesenswert?

Vielen Dank an alle - hat mir teilweise weitergeholfen.
Hat sich in der Zwischenzeit jedoch geklärt!

Grüße

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
Noch kein Account? Hier anmelden.