Ok, kommen wir zum Code.
Ich fange mal mit der adc_init() an:
Code:
ADMUX = 0; // Hast Du ja völlig richtig erkannt.
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1); //Die Bits ADEN, ADPS2 ind ADPS1 o, ADCSRA-Register werden gesetzt.
// ADEN ist nicht zum Triggern der Messung da, sondern schaltet den ADC erst mal generell ein.
// ADPS1 und 2 setzten den Wandlertakt für den Free-Running-Mode. Die Eingestellte Frequenz sagt also aus, in welchen Zeitabständen der ADC seinen Eingang abfragt und sein Ergebnis aktualisiert. Je schneller der Takt, desto genauer wird Dein Signal abgetastet. Allerdings schlägt das dann auch auf die Performance des µP, da er logischerweise weniger Zeit für andere Sachen hat. In diesem Codebeispiel ist der Free-Running-Mode allerdings ausgeschaltet, die eingestellte Frequenz hat also keine Auswirkung. Jede Messung wird manuell gestartet.
SFIOR = 0; //Ist meiner Ansicht nach überflüssig. Die PullUps und auch die anderen Einstellungen im SFIOR haben keine Auswirkung auf den ADC.
So, nun zum Hauptprogramm.
Code:
adc_init(); //Ist ja schon klar.
ADCSRA |= (1<<ADSC); //Startet eine einfache Wandlung.
while (!(ADCSRA & (1<<ADIF)) ) //Fragt das ADIF Bit ab. Solange ADIF nicht 1 ist,
; //wird die leere while-Schleife ausgeführt, also gewartet.
buffer = (ADCH<<8) | ADCL; //hier wird das Wandlungsergebnis in die Variable buffer geschrieben. Da das Ergebnis aus 2 8-Bit Registern besteht (HighByte ADCH und LowByte ADCL) wird zunächst das HighByte um 8 Stellen nach links geschoben und danach mit dem LowByte verknüpft. So steht auf den Bits 0-7 der Inhalt von ADCL und auf 8-15 der Inhalt von ADCH. Somit hat man das ursprünglich zweigeteilte Ergebnis zu einer verwertbaren Zahl zusammengefügt.
So, das war's schon. Ich hoffe, ich konnte Dir weiterhelfen.
askazo
Lesezeichen