Forum: Mikrocontroller und Digitale Elektronik Atmega168 und ADC -> so richtig ?


von Sven W. (sven_w18)


Lesenswert?

Hallo !

Ich möchte vom PINC4 (ADC4) ein analoges Signal eines Sensors abfragen.

Da ich in meinem Programm keine Warteschleifen gebrauchen kann, habe ich 
mich für den "Free Running"-Modus entschieden.
Und die positive Betriebsspannung als Referenz, da das Ganze mit 
Batterien betrieben werden soll.

Ist der "Programmfetzen" so richtig?
Muss ich noch Hardwaremäßig noch etwas beschalten, ausser Sensorsignal 
an PIN C4? (mal abgesehen von allem was nötig ist um den Controller 
laufen zu lassen)
1
...
2
uint16_t adc_result;
3
4
  ADMUX |= (1<<REFS0);         //AVCC Referenzspannung
5
  ADMUX |= (1<<ADLAR);         //ADC Left Adjust Result
6
  ADMUX |= (1<<MUX2);          //ADC4, PIN C4
7
8
  ADCSRA |= (1<<ADSC);                // Auto Trigger, Start Conversion
9
  ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);   // Frequenzvorteiler 128
10
  ADCSRA |= (1<<ADEN);                // ADC aktivieren
11
12
...
13
14
adc_result = ADCH;
15
16
...

Schon mal Danke für Eure Antworten !!!!

von Michael M. (eos400dman)


Lesenswert?

Du musst den ADC aktivieren bevor du eine Wandlung startes und den 
Prescaler solltest du besser auch vorher einstellen. Also so ist auf 
jeden Fall mein Wissensstand.

Gruß Michael

von spess53 (Gast)


Lesenswert?

Hi

>Da ich in meinem Programm keine Warteschleifen gebrauchen kann, habe ich
>mich für den "Free Running"-Modus entschieden.

Dazu muss man den Free Running MOde auch einschalten:  ADATE in ADCSRA: 
ADC Auto Trigger Enable.

Wenn du nicht warten willst, dann lies den ADC-Wert im 
AD-Complete-Interrupt aus.

MfG Spess

von Sven W. (sven_w18)


Lesenswert?

Hi, Spess !

Also dann so:
1
  ADMUX |= (1<<REFS0);         //AVCC Referenzspannung
2
  ADMUX |= (1<<ADLAR);         //ADC Left Adjust Result
3
  ADMUX |= (1<<MUX2);          //ADC4, PIN C4
4
  
5
  ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);   // Frequenzvorteiler 128
6
  ADCSRA |= (1<<ADEN);                // ADC aktivieren
7
  ADCSRA |= (1<<ADATE) | (1<<ADSC);          // Auto Trigger, Start Conversion


Warten ist jetzt relativ, ich kann im Programmablauf keine 
Zeitvertrödelung gebrauchen; also warten auf ein Ergebnis ist nicht 
möglich.

von Bananen Joe (Gast)


Lesenswert?

Aber warten du musst, kleiner Jedi....

Die erste Umwandlung braucht erstmal længer als die folgenden und die 
brauchen dann auch ein paar ADC-Takt-Zyklen (steht im Datenblatt).
Jetzt kannst du entweder auf das "ADC-Data-Ready"-Flag pollen oder einen 
Interrupt ausløsen lassen der dir deinen gespeicherten ADC-Wert 
aktualisiert.

von Sven W. (sven_w18)


Lesenswert?

Also habe ich die Wahl, einfach die "Verzögerung" der ersten Messung zu 
akzeptieren oder nach der Initialisierung

while (ADCSRA & (1 << ADSC));

abzuwarten.

Aber nichts desto trotz, kann ich doch in meiner Programmschleife den 
Messwert abfragen und müsste doch bei "Free Running" einfach den zuletzt 
gemessenen Wert erhalten. Oder liege ich jetzt da falsch ?
1
....
2
while(1)
3
{
4
...
5
adc_result = ADCH;
6
...
7
}

von Karl H. (kbuchegg)


Lesenswert?

Sven W. schrieb:
> Also habe ich die Wahl, einfach die "Verzögerung" der ersten Messung zu
> akzeptieren oder nach der Initialisierung
>
> while (ADCSRA & (1 << ADSC));
>
> abzuwarten.
>

Man kann die Dinge aber auch umdrehen.
Sagt ja kein Mensch, dass man in der Zeit, in der der ADC arbeitet nicht 
etwas anderes tun darf.


Man kanns ja auch so machen
1
  ....
2
  while(1)
3
  {
4
    ...
5
    if( ADC ist fertig )
6
    {
7
      Messwert vom ADC holen
8
      Neue Messung am ADC anstossen
9
10
      Messwert verarbeiten
11
      ....
12
    }
13
14
    ...
15
  }

je nachdem, wieviel in den ... Phasen zu tun ist, kann man auch auf die 
if Abfrage komplett verzichten, weil man ja weiß, wieviele Takte der ADC 
für eine Wandlung benötigt. Benötigen alle Prgrammteile vom Starten des 
ADC bis zum Holen des Ergbnisses mehr Takte, dann ist sichergestellt, 
dass der ADC tatsächlich zu diesem Zeitpunkt fertig ist. Allerdings 
schadet der if wahrscheinlich auch nicht wirklich der Laufzeit.

von Ingo (Gast)


Lesenswert?

... Wenn man richtig viel in den ... hat dann ist das Ergebnis der 
Wandlung nicht aktuell.

Ingo

von Sven W. (sven_w18)


Lesenswert?

Danke, Karl Heinz Buchegger. So oder ähnlich hatte ich mir das auch 
schon gedacht.

Was für Vor-/Nachteile haben denn "Free Running" und der wiederkehrenden 
Messanstoß mit Warten ?

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.