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
voidcapture_wave(int16_t*buffer,uint16_tcount)
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
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.
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...
"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"
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...
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