Hallo alle,
ich rechne mich grad krumm mit einer ADC-Frequenz im free running Modus.
Target: nanoclone mit mega328p@20MHz. Ich habe die Platine selbst umgequarzt, bisher ist mir kein Timingfehler aufgefallen (Blinkfrequenz Heartbeat ist 0,500/sec, UART läuft bei 115k2 gut).
Nun programmiere ich den ADC3, free running, Prescaler clk/128. Heraus kommt - Mist. Das DMM (billig, PeakTech 2010) zeigt 6,00 kHz, das Oszilloskop (Gould 1602) zeigt von fallender zu fallender Flanke 0,1670 ms, das ginge ja noch (5,988 kHz). ABER meine Rechnung verwirrt mich total: aus 20 MHz errechne ich mit clk/128 => 156 250 Interrupts pro Sekunde; mit ner getoggelten LED also 78 kHz. Gemessen - siehe oben, Oskar-Flanken mit 5,988 kHz.
Wo bitte mache ich den Fehler ?
Code:
// ============================================================================= =
// === Initialisierung fuer ADC mega328 MIT Interrupt
// >>>> ATmega328-P_Atmel-42735B_Complete-11-2016; Siehe Seite 308
// .. input clock frequency between 50kHz and 200kHz to get maximum resolution ..
// === ADC3/PC3 auf 10 Bit, Interrupt ausgelöst <=> free running
void ADC3_10_init_irupt(void) //
{
ADMUX |= (1<<MUX1)|(1<<MUX0); // Wandlung mit ADC3 317
ADCSRA |= (1<<ADATE); // Auto Triggering Enable doc S 307 + 319
ADMUX |= (1<<REFS0); // Referenzspannung ist AVcc 317
// AVCC with external capacitor at AREF pin
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Prescaler = clock/128 320
// Prescaler NUR für system clck ==> 156 250/sec (78,125 kHz) =>
// Messung ???
ADCSRA |= (1<<ADIE); // ADC Interrupt Enable 319
ADCSRA |= (1<<ADEN); // ADC Enable 319
ADCSRA |= (1<<ADSC); // Free Rung .. to start the first conversion 319
//
adc3_cnt = 0; // ADC-Wert wird x-fach aufaddiert
adc3tcnt = 1; //
adc3_tmp = 0; // ADC-x-fach-Speicher
// mrgl12 = 0b00000000; // Motorregelung 12 ausschalten
// mrgl34 = 0b00000000; // Motorregelung 34 ausschalten
}
// ============================================================================== =
// ============================================================================== =
// === Nicht unterbrechbare ISR für ADC3 auf Portpin PC3/mega328 ============== =
// Routine übernimmt ADC-Wert und quittiert mit 170 ins Statusbyte.
//
ISR(ADC_vect) // _VECTOR(21)
{ //
// PORTB ^= (1<<PB4); // Zeit/Interruptfrequ: rtLED/PIN PB4 toggeln
adc3tcnt = adc3tcnt + 1;
if (adc3tcnt < 11) return; // Es wird NUR jeder zwölfte ISR-Aufruf gewertet
// - - - - - - - - - - - - - - - -
// ##>> Ab hier ist adc3tcnt >11, hier also 12
adc3tcnt = 1; // adctcnt zurücksetzen auf 1
// - - - - - - - - - - - - - - - -
adc3_tmp = ADC; // Hole Wert
adcs = adc3_tmp; // aktuell ausgelesener Wert wird hier gesichert
Danke für die Aufklärung .
Kann es sein, dass hier noch die eigentliche Wandlungszeit dazu kommt, sodass die nächste Wandlung erst immer gestartet wird, wenn die laufende abgelaufen ist? Sozusagen der Satz in der Dokumentation ".. A normal conversion takes 13 ADC clock cycles. .." ? ? ? Denn damit käme ich auf 156 250/13 - also 12 019 und wäre bei der Blinkfrequenz von 6 kHz :-/
Lesezeichen