
Zitat von
Superhirn
kurz und bündig.
Ob das Geht?
Kleiner Versuch:
Code:
Register:
ADMUX
Bit 7: REFS1
Bit 6: REFS0
Bit 5: ADLAR
Bit 4: -
Bit 3: MUX3
Bit 2: MUX2
Bit 1: MUX1
Bit 0: MUX0
REFS-Bit-Kombinationen wählt die Referenzspannung
(Gut im Asuro ist AVCC)
REFS1 REFS0
0 0 AREF
0 1 AVCC
1 0 Nicht erlaubt
1 1 Interne 2.5V Referenz
ADLAR-Bedeutung
0 ADC-Ergebniss in den Registern ADCL und ADCH steht so:
ADCH: Bits 1 und 0: Höchste Bits der Wandlung
ADCL: Bits 7 bis 0: Die niedriegen Bits der Wandlung
1 In den Registern ADCL und ADCH steht das Ergebniss nun so:
ADCH: Bits 7 bis 0: Die höchsten 8 Bit vom Ergeniss
ADCL: Bits 7 und 6: Die beiden niedrigsten Ergebnissbits
MUX-Bits
0000 wählt ADC-Kanal 0
0001 wählt ADC-Kanal 1
0010 wählt ADC-Kanal 2
0011 wählt ADC-Kanal 3
0100 wählt ADC-Kanal 4
0101 wählt ADC-Kanal 5
0110 wählt ADC-Kanal 6
0111 wählt ADC-Kanal 7
1000
1001
1010
1011
1100
1101
1110 1.23 Volt wird gemessen
1111 0 Volt werden gemessen
Register:
ADCSRA
Bit 7: ADEN
Bit 6: ADSC
Bit 5: ADFR
Bit 4: ADIF
Bit 3: ADIE
Bit 2: ADPS2
Bit 1: ADPS1
Bit 0: ADPS0
ADEN: 1 schaltet den ADC-Wandler erst ein
ADSC: Eine 1 startet die Wandlung, oder das 'freerunning'
ADFR: 1 erlaubt das 'freerunning'
ADIF: Wird von der CPU auf 1 gesetzt, wenn eine Wandlung fertig ist
ADIE: 1 erlaubt der CPU eine Interrupt-Funktion aufzurufen
ADPS2 bis ADPS0: Wählt einen Vorteiler, der die Wandlergeschwindigkeit
und damit allerdings wohl auch die Genauigkeit steuert.
Großer Vorteilerwert ergibt eine langsamere Wandlung. Damit wird
dann aber auch das laufende Programm nicht so häufig unter-
brochen und somit läuft es 'etwas' schneller.
ADPS2 ADPS1 ADPS0
0 0 0 Vorteilteiler 2
0 0 1 Vorteilteiler 2 (Ja, nochmal 2)
0 1 0 Vorteilteiler 4
0 1 1 Vorteilteiler 8
1 0 0 Vorteilteiler 16
1 0 1 Vorteilteiler 32
1 1 0 Vorteilteiler 64
1 1 1 Vorteilteiler 128
Du solltest also immer erst in das Register ADMUX schreiben.
Dann in das ADCSRA-Register schreiben.
z.B.:
ADMUX = 0b01000000; /* AVCC-Referenz; Kanal 0 */
ADCSRA = 0b11101111 /* Enable; ADC-Start; freerunning; Interrupt enable; Vorteiler 128
Um den Interrupt überhaupt nutzen zu können benötigst du eine Funktion.
z.B.
Code:
volatile unsigned int adc_wert;
SIGNAL (SIG_ADC)
{
adc_wert = ADCL + (ADCH << 8);
}
Damit liefert dir der 'freerunning' ADC-Wandler nun automatisch immer den gemessenen Wert vom Kanal 0 in die Variable adc_wert.
Diesen Wert kannst du in deinem Hauptprogramm immer lesen.
P.S.: Kürzer schaffe ich leider nicht
Lesezeichen