Ich baue ein Hobby-Oszilloskop auf ATmega16. Ich teste den ADC, indem ich eine Rechteckwelle bei 2 kHz mit kleiner Amplitude erzeuge und sie über einen kapazitiven Eingang mit einem Spannungsteiler an den ADC-Pin anlege, um den Nullpegel zu verschieben.
So sieht das Signal nach der Abtastung durch ADC aus:
Es sieht gut aus, aber nachdem ich anfange, den Nullpegel durch Einstellen des Potentiometers zu verschieben, bekomme ich diese seltsamen Spitzen:
Nachdem ich den Pegel etwas höher verschoben habe, sieht es wieder gut aus:
Und dann wiederholt sich das Muster:
Insgesamt erhalte ich 3 Bereiche, in denen die Spitzen erscheinen.
ADMUX = (1 << REFS0); // AVCC with external capacitor at AREF pin
ADCSRA = (1 << ADEN)
| (1 << ADIE)
| (1 << ADATE)
| (1 << ADPS0)
| (1 << ADPS1)
| (1 << ADPS2); // Division factor = 128
MCUCR |= 1 << SM0;
MCUCR |= 1 << SE; // Sleep-mode enabled
ADCSRA |= (1 << ADSC);
volatile uint8_t adcLow;
volatile uint8_t adcHigh;
int main(void) {
....
while (1) {
if (ADCSRA != 0x00) {
USARTSendByte(adcLow);
USARTSendByte(adcHigh);
}
}
}
ISR(ADC_vect) {
adcLow = ADCL;
adcHigh = ADCH;
}
Die Spitzen schneiden eindeutig auf ganz bestimmte Werte ab (wahrscheinlich eine Zweierpotenz) oder Sie verwenden vorzeichenbehaftete Ganzzahlen, die zu klein sind, um den gesamten Wert zu enthalten.
Sie haben keinen vollständigen Quellcode angegeben, also vermute ich hier. Sie versuchen wahrscheinlich, den gemessenen Wert in eine zu kleine ganze Zahl einzupassen. Machen Sie einen Speicherauszug aus den Werten, die Sie erhalten, und finden Sie die Spitzen darin. Sehen Sie sich dann die binäre Darstellung dieser Zahlen an und sehen Sie, ob Sie Gemeinsamkeiten finden können.
Bei schneller Schätzung beträgt der Abstand zwischen zwei Spitzen etwa 1,28 V, etwas zu zufällig nahe an der Größe einer vorzeichenbehafteten 8-Bit-Ganzzahl.
Ich empfehle, Typdefinitionen wie int8_t
[-128:127], uint8_t
[0:255], int16_t
[-32768:32767], uint16_t
[0:65535], int32_t
[-2147483648:2147483647] und uint32_t
[0:4294967295] zu verwenden, was deutlich zeigt, wie groß ist die Variable.
adcLow
und adcHigh
sind vom uint8_t
Typ, sodass die Größe ausreicht, um ADC-Werte zu speichern.int value = (buffer[i + 1] << 8 | (buffer[i] & 0xFF))
in Java.
Ignacio Vazquez-Abrams
Ashton H.
Tom L.
Jippie
uint16_t adcValue = ADC;
Ashton H.
Ashton H.
Jippie