Ich hab mir das nun nochmal angekuckt =)
holger schrieb:
> So müsste das gehen:
> 1. ADC auf SingleConversion einstellen
> 2. Timer auf CTC mit 0.5ms Interruptrate einstellen
> 3. Im Timerinterrupt Conversion starten
> 4. Im ADC Interrupt die Daten abholen
1) Der Timer stand/steht auf SingleConversion
2) Hab mir den 8bit-Timer/Counter0 herbei genommen
1 | // Timer 0 in CTC-Modus bringen
|
2 | TCCR0 |= (1<<WGM01); // CTC Modus
|
3 |
|
4 | TCCR0 |= ((1<<CS01) | (1<<CS00)); // Timer0 Prescaler 64
|
5 |
|
6 | // Timer0 bis 125 zählen lassen ... müsste 0,5ms entsprechen
|
7 | OCR0 = 250-1; //125-1;
|
8 |
|
9 | // CTC-Interrupt erlauben
|
10 | TIMSK |= (1<<OCIE0);
|
Tsja bei den Interrupts bin ich ein wenig ins straucheln geraten ...
Letztendlich bin ich bei folgender Variante angelangt ...
1 | ISR (TIMER0_COMP_vect)
|
2 | {
|
3 | flag = 1;
|
4 | }
|
Von dem Interrupt lass ich mir halt die volatile Variable "flag" auf 1
setzen, um dann ...
1 | void adc_capture (unsigned char channel, unsigned int *voltage)
|
2 | {
|
3 | unsigned int i;
|
4 |
|
5 | ADMUX = 0x40 + channel; // selects single-ended conversion on pin PF0 ~ PF7 (ADC0 ~ ADC7)
|
6 | // selects AVCC as Vref
|
7 | // selects right adjust of ADC result
|
8 |
|
9 | for (i = 0; i < FFT_N; i++) // averaging the ADC results
|
10 | {
|
11 | while (flag != 1)
|
12 | {
|
13 |
|
14 | }
|
15 |
|
16 | sbi(ADCSRA,ADSC); // start a conversion by writing a one to the ADSC bit (bit 6)
|
17 | while(!(ADCSRA & 0b00010000)) // wait for conversion to complete: ADIF = 1
|
18 | {
|
19 | //sentchar1('.'); // for debugging
|
20 | }
|
21 | flag = 0;
|
22 | *voltage++ = ((ADCL) | (ADCH<<8));
|
23 |
|
24 | }
|
25 | }
|
immer mit Timer-Interrupt die Conversion zu starten.
Den Interrupt hab ich vor/nach dem Aufruf von adc_capture an/aus
geschalten.
1 | sei();
|
2 |
|
3 | // ADC 5v to 10-bit digital (0x00 - 0x3FF)
|
4 | adc_capture(channel, voltage);
|
5 |
|
6 | cli();
|
Nun mal zur Sache =)
Es ist sicherlich völlig grauenhaft programmiert, aber ich bin wie
gesagt noch recht frisch in der Materie.
Mein LCD löst mir jetzt den Frequenzbereich von 0-1000 Hz nun mit einem
Frequenzraster von 8Hz auf ...
ABER nur wenn ich den Zähler bis 255 laufen lasse ? =/
Warum denn das?
Ich arbeite mit einem Clock von 16MHz den ich, wie oben gezeigt, durch
64 teile. Dann komme ich auf 250kHz, so das mein Timer/Counter0 bis 125
zählen müsste um die von mir gewollte 0,0005s Interruptrate zu
erreichen.
Wenn ich bis 125 zählen lasse stellt mir das Display 2MHz dar.
Wo hab ich denn den Faktor 2 liegen lassen?
Grüße Matze
#hält für verbale Ohrfeigen seine Wange hin#