25kHz wird eng, der ADC ist nur bis 4kHz ausgelegt, schnellere signale wird er nicht vernünftig messen, auch wenn du bei 16MHz einen prescaler von 2 benutzt, kommen dabei keine 8Mhz ADC clock an, bzw. 8Mhz / 13 clocks = 615kHz abtastrate bei rum
ich habe einen oszi versucht zu bauen, 16MHz mega32
bis ADC prescaler 8 ist das ergebnis noch präzise, bei 4 verdoppelt sich die samplerate nichtmehr sondern nur um rund 10% und bei 2 ist garkein unterschied zu 4 mehr zu erkennen
hier mein code
Code:
unsigned char adcval[923];
unsigned char* end;
unsigned char* pos;
ISR(SIG_ADC)
{
*pos = ((unsigned char)(ADC/4))+'!'; //ich reduzier hier auf 8bit um die datenrate zu drücken
//(38.5 kBaud ist die einzige vernünftige baudrate für 16Mhz
pos++;
if (pos > end) { //wenn die tabelle voll ist, gebe ich die werte alle an den computer
ADCSRA &= ~((1<<ADEN) | (1<<ADIE));
pos = adcval;
do {
while (!(UCSRA & (1<<UDRE)));
UDR = *pos;
} while (pos++ < end);
}
}
int main()
{
//Pointer statt indizes damit der arrayzugriff schneller wird
end = &(adcval[922]); //ende festlegen
pos = adcval; //anfang festlegen
UBRRH = 0; //UART initialisieren
UBRRL = 25;
UCSRC = (1<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (1<<URSEL);
UCSRB = (1<<RXEN) | (1<<TXEN);
ADMUX = (1<<REFS0); // AD channel ADC0 und ADC initialisieren
ADCSRA = (1<<ADPS1) | (1<<ADPS0) | (1<<ADEN) | (1<<ADATE);
ADCSRA |= (1<<ADSC); //free runing mode permanentes samplen,
//der interrupt wird über ein befehl über UART eingeschalten
sei();
while(1);
return 0;
}
das mit 4kHz findest du auch im datenblatt
Lesezeichen