ADC auslesen

OP #2908238
Lesenswert?

Hallo zusammen,

ich habe mir die ADC Ansteuerung im Wiki angeschaut und dies auch so 
Programmiert.
Nun msus ich ja nach dem Starten einer Messung warten bis diese 
durchgeführt wurde.
1
 ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
2
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
3
  }
4
  return ADCW;                    // ADC auslesen und zurückgeben

Jedoch bleibt er dann bei mir immer im Programm hängen. Ändere ich es ab 
in
1
 ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
2
  while (!(ADCSRA & (1<<ADSC) )) {   // auf Abschluss der Konvertierung warten
3
  }
4
  return ADCW;                    // ADC auslesen und zurückgeben
funktioniert es wunderbar. Ist hier ein Fehler meinerseits oder ein 
Fehler im Wiki?? Ich steh da gerade im Wald...

Gruß Markus
OP #2908279
Lesenswert?

Also mein Programm sieht so aus:
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/version.h>
4

5

6
int main(void)
7
{
8
  DDRB = 0xff;                    //Definiere Port B als Ausgang
9
  DDRA = 0x00;                    //Definiere Port A als Eingang
10
  PORTB = 0xff;                    //Setze Port B auf 0xff (Alle Ausgänge High = LED´s aus)
11
  uint8_t ad_channel=0,ad_wert=0,ad_ausgabe=0;    //Variablen definieren
12
  ADMUX = (1<<ADLAR);                  //Ausgabe des ADC-Wertes Linksbündig!!
13
  ADCSRA = (1<<ADPS2);                //Teilungsfaktor 32
14
  ADCSRA |= (1<<ADEN);                //ADC Aktivieren
15
  ADCSRA |= (ADMUX & ~(0x1f)) | (ad_channel & 0x1f);  //Setze ADC Kanal (Auswahl durch die Variable "ad_channel")
16
  
17
  ADCSRA |= (1<<ADSC);                //Eine Messung starten
18
  while (!(ADCSRA & (1<<ADSC)))            //Endlosschleife bis ADC Messung fertig
19
    {
20
    }
21
  uint8_t temp = ADCH;                //Lesen des ADC Wertes und verwerfen desselben.
22
  
23
    while(1)
24
    {
25
    ADCSRA |= (ADMUX & ~(0x1f)) | (ad_channel & 0x1f);  //Kanalauswahl
26
    ADCSRA|=(1<<ADSC);                //Messung starten
27
    while(!(ADCSRA & (1<<ADSC))){}          //Endlosschleife bis ADC Messung fertig
28
  //  uint8_t temp3 = ADCL;              //Schreiben der niedristen Bits in Temporäre Variable (Wird verworfen)
29
    ad_wert = ADCH;                  //Schreiben der höchsten 8 Bits in die Variable "ad_wert" zur weiterverarbeitung
30
    
31
    //Hier wird geprüft wie Hoch der ADC Wert ist und dazu passend die Ausgabe für Port B vorbereitet.
32
    if(0 <= ad_wert && ad_wert < 2){ad_ausgabe=0;}
33
    if(2 <= ad_wert && ad_wert < 40){ad_ausgabe=1;}
34
    if(40 <= ad_wert && ad_wert < 70){ad_ausgabe=3;}
35
    if(70 <= ad_wert && ad_wert < 100){ad_ausgabe=7;}
36
    if(100 <= ad_wert && ad_wert < 130){ad_ausgabe=15;}
37
    if(118 <= ad_wert && ad_wert < 160){ad_ausgabe=31;}
38
    if(160 <= ad_wert && ad_wert < 193){ad_ausgabe=63;}
39
    if(193 <= ad_wert && ad_wert < 223){ad_ausgabe=127;}
40
    if(223 <= ad_wert && ad_wert <= 255){ad_ausgabe=255;}
41
    PORTB = ad_ausgabe;              //Hier erfolgt die negierte (da active LOW) ausgabe für die Balkenanzeige.
42
        }
43
}

Ich lese nur ADCH in meinem Programm aus da ich Linksbündig ausgebe auf 
8 bit.  Ich nutze einen ATmega16, laut Datenblatt reicht es ADCH 
auszulesen wenn ich nur 8 bit nutze. Oder ist hier mein Denkfehler?
#2908348
Lesenswert?

Markus S. schrieb:
> Ähm ok da soll natürlich ADMUX stehen.
Dann sollte das auch laufen.

> ADCSRA |= (ADMUX & ~(0x1f)) | (ad_channel & 0x1f);
Und schreib das nicht so kompliziert. Da muß man ja mindestens dreimal 
hingucken, bis man sieht, was das soll.
ADMUX &= ~0x1F;
ADMUX |= ad_channel;
Nur weil es jetzt 2 Zeilen sind, wird das im Code nicht länger. Der 
Compiler kriegt das schon richtig hin.

mfg.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren