Forum: Mikrocontroller und Digitale Elektronik Atmega32 / Analogwerterfassung /ProgSpra C


von Michael S. (misei_3216)


Lesenswert?

Hallo,

hier wird ein Atmega 32 ins Leben gerufen. Versucht wird den Analogwert 
an ADC7 aus zu lesen. Dazu sollen die Bits im ADMUX Register (MUX 0 - 2 
111) auf logisch eins gesetzt werden. Doch gleich was ich ins MUX 
schreibe wird immer nur der ADC0 Port als Analogwert erfasst. Fehlt hier 
etwas?
Benutz wird das Atmel Studio 6.2 und Programmiert wird in C.

Hier der Codeauszug:

    //Analogwerterfassung und Auswertung
    ADMUX = (1<<MUX0) | (0<<MUX1) | (1<<MUX2) | (0<<MUX3) |(1<<ADLAR) ; 
//Analogwerterfassung an ADC7
    ADMUX = (1<<REFS0) | (1<<REFS1)  ; 
//interne 2,65V Referenzspannung;   //Linksbündige Ausgabe

    ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS2); 
//ADEN - Aktiviert / ADPS1 und ADPS2 ergeben einen teilungsfaktor von 64


    //starte 20 Abfragen
    ADC_result = 0;
    for (unsigned int i=0; i<20; i++)
      {
        ADCSRA|= (1<<ADSC);            //single conversion
        while (ADCSRA & (1<<ADSC));    //warten auf Analogwert
        ADC_result=ADCW;              //übertrage Ergebniss
      }

Muss vielleicht der Port ADDA eine Besondere behandlung bekommen?

Vielen Dank für eure Zeit.

von Klaus W. (mfgkw)


Lesenswert?

Mit:
1
    ADMUX = (1<<MUX0) | (0<<MUX1) | (1<<MUX2) | (0<<MUX3) |(1<<ADLAR) ; 
2
//Analogwerterfassung an ADC7
3
    ADMUX = (1<<REFS0) | (1<<REFS1)  ;

setzt du nur die Bits REFS0 und REFS1.
Die anderen aus der Zeile vorher löschst du damit wieder.

Ist das so beabsichtigt?

von Klaus W. (mfgkw)


Lesenswert?

Abgesehen davon:
Wenn du es schaffst, die MUX... nicht wieder zu überschreiben, dann 
macht es auch keinen Sinn, mehrere davon gleichzeitig zu setzen.
Du kannst nur von einem ADC gleichzeitig wandeln lassen und lesen, und 
welcher das ist, wird im MUX...-Feld gesetzt.
Also z.B.
1
    ADMUX = (1<<REFS0) | (1<<REFS1) | 3;    // für AD3
2
    ADMUX = (1<<REFS0) | (1<<REFS1) | MUX3; // für AD3
oder
1
    ADMUX = (1<<REFS0) | (1<<REFS1) | 2;    // für AD2
2
    ADMUX = (1<<REFS0) | (1<<REFS1) | MUX2; // für AD2

Aber nicht
1
    ADMUX = (1<<REFS0) | (1<<REFS1) | 2 | 3;       // für AD2+3
2
    ADMUX = (1<<REFS0) | (1<<REFS1) | MUX2 | MUX3; // für AD2+3

von Klaus W. (mfgkw)


Lesenswert?

Hintergrund: es gibt zwar mehrere Analogeingänge, aber nur einen 
Wandler.
Mit den MUX...-Werten sagt man, welcher Eingang auf den Wandler gelegt 
wird.
Das geht natürlich nur mit einem gleichzeitig.

Wenn mehrere Analogwerte benötigt werden, muß man die nacheinander 
holen.

von Michael S. (misei_3216)


Lesenswert?

Hallo Herr Wachtler,

vielen Dank für die Antwort.

Klaus Wachtler schrieb:
> setzt du nur die Bits REFS0 und REFS1.
> Die anderen aus der Zeile vorher löschst du damit wieder.

Der Erste Hinweis ist die Lösung. Habe das ADMUX Register nun in einer 
Zeile. Jetzt geht es.


Klaus Wachtler schrieb:
> Abgesehen davon:
> Wenn du es schaffst, die MUX...

Tue ich das nicht? Ich habe Mit meiner Eingabe dem Register einen Wert 
(ANALOGEINGANG) zugweisen der Ausgelesen wird.
Mit :

  ADMUX = (1<<REFS0) | (1<<REFS1)  |(1<<MUX0) | (1<<MUX1) | (1<<MUX2) | 
(0<<MUX3) |(1<<ADLAR) ;  lese ich PDC 7 aus.

Was sich mir nicht erschließt ist das ich nun eine Auflösung von vormals 
1023 zu jetzt ca. 65500 erhalte. Kannst du mir sagen wie dies zustande 
kommt?

Noch eine Frage zu diesem Forum. WIe kann ich den CODE TEXT so schöhn 
wie du Hervorheben?

Nochmals vielen Dank.

von [c]C-Code[/c] (Gast)


Lesenswert?

Michael Seibold schrieb:
> Noch eine Frage zu diesem Forum. WIe kann ich den CODE TEXT so schöhn
> wie du Hervorheben?
1
[c]
2
C-Code
3
[/c]

von Karl H. (kbuchegg)


Lesenswert?

Michael Seibold schrieb:

> Was sich mir nicht erschließt ist das ich nun eine Auflösung von vormals
> 1023 zu jetzt ca. 65500 erhalte. Kannst du mir sagen wie dies zustande
> kommt?

Du hast ADLAR gesetzt. Scheinbar ohne zu wissen was das tut.

> Noch eine Frage zu diesem Forum. WIe kann ich den CODE TEXT so schöhn
> wie du Hervorheben?

Über dem Eingabefeld steht wie das geht. "Formatierung"
1
Ich zeig euch mal den Code
2
[c]
3
ADMUX = (1<<REFS0) | (1<<REFS1) | (1<<ADLAR) | 7;
4
[/c]

Atmel hat übrigens die MUX Bits extra so angeordnet, dass man die 
Kanalnummer im Klartext hinschreiben kann. Durch die Veroderung mit zb 7 
werden genau die richtigen MUX Bits gesetzt, so dass man den ADC-Eingang 
7 ausgewählt hat. So ist das ein bischen einfacher zu lesen, als wie 
wenn  man selber die MUX Bits aufdröselt.
Dadurch, dass dann einiges an 'Zeichen-Rauschen' wegfällt, sticht dann 
auch mehr ins Auge, was man in den restlichen Bits eigentlich 
eingestellt hat. Zb. das das ADLAR Bit gesetzt ist.

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

Michael Seibold schrieb:
> Was sich mir nicht erschließt ist das ich nun eine Auflösung von vormals
> 1023 zu jetzt ca. 65500 erhalte. Kannst du mir sagen wie dies zustande
> kommt?

Deine Auflösung wird nicht höher :-)
Aber mit ADLAR werden die 10 Bits vom Wandler um 6 nach links geschoben.

In deiner ersten Version hattest du ADLAR ja mit der zweiten Zuweisung 
wieder gelöscht.

von Michael S. (misei_3216)


Lesenswert?

Klaus Wachtler schrieb:

Karl Heinz schrieb:
> Du hast ADLAR gesetzt. Scheinbar ohne zu wissen was das tut.

Mir liegt zur Hand : ADLAR ADC-Ergebnis welches gesetzt Linksbündig 
ausgegeben wird. Mehr habe ich dazu nicht.


Karl Heinz schrieb:
> Atmel hat übrigens die MUX Bits extra so angeordnet...


Muss dazu vielleicht ein zusätzliches HEADER eingebunden werden? Bei mir 
geht das Nicht. Atmel Studio 6.2
1
#include <avr/io.h>
2
#include <util/delay.h>

von Klaus W. (mfgkw)


Lesenswert?

Michael Seibold schrieb:
> Karl Heinz schrieb:
>> Atmel hat übrigens die MUX Bits extra so angeordnet...
>
> Muss dazu vielleicht ein zusätzliches HEADER eingebunden werden? Bei mir
> geht das Nicht. Atmel Studio 6.2

Um 1, 2, oder 3 zu schreiben, brauchst du keine Headerdatei.
Aber für alle Makros, soweit du sie verwendest.

Michael Seibold schrieb:
> Klaus Wachtler schrieb:
>
> Karl Heinz schrieb:
>> Du hast ADLAR gesetzt. Scheinbar ohne zu wissen was das tut.
>
> Mir liegt zur Hand : ADLAR ADC-Ergebnis welches gesetzt Linksbündig
> ausgegeben wird. Mehr habe ich dazu nicht.

Eben, und wenn 10 Bit in 16 Bit linksbündig ausgegeben werden, sind die 
um 6 nach Links verschoben.

von Michael S. (misei_3216)


Lesenswert?

Klaus Wachtler schrieb


Klaus Wachtler schrieb:
> m 1, 2, oder 3 zu schreiben, brauchst du keine Headerdatei.
> Aber für alle Makros, soweit du sie verwendest.

Guter Tipp. Danke.

Klaus Wachtler schrieb:
> Eben, und wenn 10 Bit in 16 Bit linksbündig ausgegeben werden, sind die
> um 6 nach Links verschoben.

Was soviel bedeutet als dass ich aus 1023 immerhin 65536 Punkte erhalte.


Vielen Dank für deine Zeit und Interesse.

von Klaus W. (mfgkw)


Lesenswert?

fast...
der höchste Wert wird 65535 sein, nicht 65536.

Bei einer kleinen Spannungsänderung wird sich der Wert aber dann 
natürlich nicht um 1 ändern, sondern immer um 64 oder vielfache davon.

von Klaus W. (mfgkw)


Lesenswert?

Quatsch, der höchste Wert ist 65472 ((2^16-64) oder ((2^10-1) << 6)).

Die unteren 6 Bit sind ja 0.

: Bearbeitet durch User
von Hubert G. (hubertg)


Lesenswert?

ADLAR ist dafür vorgesehen das nur 8bit des ADC verwendet werden. Es 
wird dann nur ADCH abgefragt.
Alles andere macht doch keinen Sinn.

von Klaus W. (mfgkw)


Lesenswert?

Hubert G. schrieb:
> ADLAR ist dafür vorgesehen das nur 8bit des ADC verwendet werden. Es
> wird dann nur ADCH abgefragt.

Kann man machen, muß man aber nicht.
Man kann es auch gleich zum Skalieren nutzen, ohne Rechenzeit zu 
verbraten für Shiften oder Multiplizieren.

> Alles andere macht doch keinen Sinn.

hm

von Michael S. (misei_3216)


Lesenswert?

Klaus Wachtler schrieb:
> Quatsch, der höchste Wert ist 65472 ((2^16-64) oder ((2^10-1) << 6)).
>
> Die unteren 6 Bit sind ja 0.

Hallo Klaus
Woher rührt das? Was ist Shiften?

Hubert G. schrieb:
> ADLAR ist dafür vorgesehen das nur 8bit des ADC verwendet werden. Es
> wird dann nur ADCH abgefragt.


Hallo Hubert.
In welchen Anwendungen fragt man denn nur die Oberen 8 bits aus? So aus 
dem Gefühl heraus gehen hier ja Informationen verloren.

LG

von Werner M. (Gast)


Lesenswert?

Michael Seibold schrieb:
> Was ist Shiften?

Das Wort "Shiften" kommt aus dem Englischen und bedeutet auf Deutsch 
"verschieben".

von Hubert G. (hubertg)


Lesenswert?

Michael Seibold schrieb:
> Hallo Hubert.
> In welchen Anwendungen fragt man denn nur die Oberen 8 bits aus? So aus
> dem Gefühl heraus gehen hier ja Informationen verloren.

Wenn du nicht sauber arbeitest, ADC-Eingang und AVCC nicht brumm- und 
rauschfrei sind, ist das niederwertigste Bit ohnehin unbrauchbar.
Ausserdem gibt es genügend Anwendungen bei denen 256 Schritte genug 
sind. Da macht es dann wenig Sinn 10Bit auszulesen und dann doch erst 
wieder zu teilen.
Solange Zeit und Platz keine Rolle spielen, ist es egal wie man es macht 
wenn es den Zweck erfüllt. Wenn eines von beiden mal zwickt, muss man 
halt gut überlegen wie es das Sinnvollste ist.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.