Forum: Mikrocontroller und Digitale Elektronik ADC auslesen


von Denis (Gast)


Lesenswert?

Moin moin,
habe ein Problem , und zwar möchte ich gerne mein ADC in einem festen 
Intervall von 250ms auslesen , steh aber immoment voll aufm schlauch 
bitte um mithilfe. Habe zuvor schon mein ADC konfiguriert
1
/////////////////////////init_ADC()/////////////////////////
2
3
void init_ADC(void)
4
{
5
  ADMUX |= (1 << REFS0);
6
  ADCSRA |= (1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0); //ADC Prescalar PRESCALAR=FCPU/FADC=80
7
  ADCSRA |=(1 << ADFR); //Free running modus
8
}
9
10
11
/////////////////////////init_LED()/////////////////////////
12
13
14
void init_LED(void)
15
{
16
  DDRB= 0x00;    // PORT B ALS ANSCHLUSS
17
  PORTB= 0x00;  //Alle Leds aus  
18
19
}
20
21
22
23
/////////////////////////start_ADC()/////////////////////////
24
25
void start_ADC(void)
26
{
27
28
  ADCSRA |=(1 << ADEN)|(1 << ADSC); //ADC an und starten der Konversation
29
30
}
31
32
33
/////////////////////////wait_ADC()/////////////////////////
34
35
void wait_ADC (void)
36
{
37
  while(!(ADCSR & (1<<ADIF)));  //Warten auf Ende
38
39
}
40
41
42
/////////////////////////read_ADC()/////////////////////////
43
44
void read_ADC(void)
45
{
46
  unsigned short adcres;
47
48
  adcres=ADC;            //Auslesen
49
50
}

von spess53 (Gast)


Lesenswert?

Hi

>habe ein Problem , und zwar möchte ich gerne mein ADC in einem festen
>Intervall von 250ms auslesen , steh aber immoment voll aufm schlauch
>bitte um mithilfe. Habe zuvor schon mein ADC konfiguriert

Controller?
Neuere AVRs haben mehrere Autotriggerquellen. Dazu gehören auch Timer. 
Und damit lässt dann das Abfrageintervall einstellen.

MfG Spess

von Hannes L. (hannes)


Lesenswert?

Man kann den ADC auch im Free-Run-Mode laufen lassen und im 
Timer-Interrupt nebenher abfragen. Das hat noch den Vorteil, dass man 
nicht prüfen muss, ob der ADC schon fertig ist.

...

von Denis (Gast)


Lesenswert?

Sorry hatte ich vergessen zu erwähnen benutzte einen AVR ATMEGA128

also ich möchte halt das der ADC im intervall von 250ms (delay) 
ausgelesen wird und die eingelesenen wert(8Bits) ausgibt

von ich (Gast)


Lesenswert?

>  ADCSRA |=(1 << ADEN)|(1 << ADSC); //ADC an und starten der Konversation

cool. Du kanst mit deinem ADC erzählen???

von Denis (Gast)


Lesenswert?

Sorry konversion haha =)

von Karl H. (kbuchegg)


Lesenswert?

Denis schrieb:
> Sorry hatte ich vergessen zu erwähnen benutzte einen AVR ATMEGA128
>
> also ich möchte halt das der ADC im intervall von 250ms (delay)
> ausgelesen wird und die eingelesenen wert(8Bits) ausgibt

Ein paar Möglichkeiten wurden dir ja jetzt schon vorgeschlagen.
Und alle drehen sich immer darum, dass du einen Timer für die zeitliche 
Steuerung verwendest.

Woran hakt es denn jetzt?

von Denis (Gast)


Lesenswert?

ehrlich gesagt hackt es immoment an der umsetztung

von Karl H. (kbuchegg)


Lesenswert?

Denis schrieb:
> ehrlich gesagt hackt es immoment an der umsetztung

Das ist mir zuwenig :-)
Wobei konkret?
Welche Teile kriegst du selber hin, bei welchen brauchst du Hilfe?

Für welche Variante hast du dich entschieden, wie willst du das Problem 
angehen? Kriegst du es zb hin, in einem Timerinterrupt alle 250ms eine 
LED umzuschalten? Wenn ja, dann sollte es ja auch kein Problem sein, in 
demselben Timerinterrupt den ADC zu starten und auszulesen.

Zeig das was du hast. Sag wobei du 'konkret' ein Problem hast und Leute 
werden dir helfen. Aber für dich ein Programm schreiben wird hier 
niemand. Nicht bei einer derartigen Standardaufgabe.

von Denis (Gast)


Lesenswert?

mit welchen befehl lese ich denn ein ADC aus?

also ich würde einfach eine funktion my_delay programmieren die 250 ms 
wartet. und dann eine funktion die den ADC ausliest mit ner for schleife 
zum beispiel und dann noch das delay einbinden

von Karl H. (kbuchegg)


Lesenswert?

Denis schrieb:
> mit welchen befehl lese ich denn ein ADC aus?

Mit gar keinem.
Schau bitte ins Tutorial. Da findest du auch eine vernünftige, 
anfängergerechte Funktion.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial


> also ich würde einfach eine funktion my_delay programmieren die 250 ms
> wartet.

Schon falsch.

von Denis (Gast)


Lesenswert?

1
/////////////////////////read_ADC()/////////////////////////
2
3
void read_ADC(void)
4
{
5
  unsigned short adcres;
6
7
  adcres=ADC;            //Auslesen
8
9
}
10
11
12
13
/////////////////////////out_LED()/////////////////////////
14
15
void out_LED(void)
16
{
17
  DDRB=0xff;    //POTRTB als Ausgang
18
  PORTB= 0xff;
19
}
20
21
22
23
24
/////////////////////////test()/////////////////////////
25
26
void test(void)
27
{
28
  read_ADC();
29
  _delay_ms(250);
30
  out_LED();
31
32
  return;
33
34
}

von Denis (Gast)


Lesenswert?

so würde er mir ja alles ausgeben?!

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:
>> also ich würde einfach eine funktion my_delay programmieren die 250 ms
>> wartet.
>
> Schon falsch.

Das nehme ich zurück.
Fürs erste kann man das so machen.
Aber es ist kein besonders guter Stil und je nachdem was man mit dem 
Wert weiter machen will, manövriert man sich damit ganz schnell in 
Schwierigkeiten.

von Karl H. (kbuchegg)


Lesenswert?

Denis schrieb:
> so würde er mir ja alles ausgeben?!

Nö.
Du holst zwar hier den Wert

void read_ADC(void)
{
  unsigned short adcres;

  adcres=ADC;            //Auslesen

}

aber du machst nichts damit.

von Denis (Gast)


Lesenswert?

Dann bitte ich um einen kleinen anschub!?

von Torsten G. (wawibu)


Lesenswert?

Denis schrieb:
1
> /////////////////////////test()/////////////////////////
2
> 
3
> void test(void)
4
> {
5
>   read_ADC();
6
>   _delay_ms(250);
7
>   out_LED();
8
> 
9
>   return;
10
> 
11
> }

Und warum willst Du hier den Wert auslesen (ohne ihn als Rückgabe zu 
erhalten), dann 250ms warten, um dann alle LEDs zur Anzeige zubringen?

Was soll denn mit dem ADC Wert passieren?

von Denis (Gast)


Lesenswert?

1
/////////////////////////out_LED()/////////////////////////
2
3
void out_LED(void)
4
{
5
  DDRB=0xff;    //POTRTB als Ausgang
6
  PORTB= 0xff;
7
  
8
  PORTB = ADCH;
9
}
10
11
12
13
14
/////////////////////////test()/////////////////////////
15
16
void test(void)
17
{
18
  read_ADC();
19
  _delay_ms(250);
20
  out_LED();
21
22
  return;
23
24
}

von Denis (Gast)


Lesenswert?

also der ADC soll ausgelesen werden 250ms intervall und die eingelesenen 
werte die unteren 8bit auf den leds angezeigt werden

von Denis (Gast)


Lesenswert?

Also noch ma ganz in Ruhe ich lese als ersten mein adc aus das geschieht 
ja schon hier bei mir
1
 /////////////////////////read_ADC()/////////////////////////
2
3
void read_ADC(void)
4
{
5
  unsigned short adcres;
6
7
  adcres=ADC;            //Auslesen
8
9
}

so jetzt möchte in werte einlesen und auf die leds ausgeben und da 
hängts

von Denis (Gast)


Lesenswert?

ich habe ein buchstaben eingelesen
1
/////////////////////////my_getch()/////////////////////////
2
3
char my_getch(void)
4
{
5
  int pruefung = 0;
6
  char buchstabe = 0;
7
8
9
    while(((pruefung = my_status()) == 0 ))// warten bis zeichen kommt
10
    
11
  buchstabe = UDR0;                      // Abrufe des Datenregisters
12
    return buchstabe;  
13
14
}
und direkt wieder als echo ausgegeben

es ist ein potentiometer (0-5V) an PortF angeschlossen und nun möchte 
ich die niederwertigen 8bits des eingelesenen wertes auf die leds 
ausgeben

von Karl H. (kbuchegg)


Lesenswert?

Denis schrieb:
> Also noch ma ganz in Ruhe ich lese als ersten mein adc aus das geschieht
> ja schon hier bei mir
1
> /////////////////////////read_ADC()/////////////////////////
2
> 
3
> void read_ADC(void)
4
> {
5
>   unsigned short adcres;
6
> 
7
>   adcres=ADC;            //Auslesen
8
> 
9
> }
10
>
>
> so jetzt möchte in werte einlesen und auf die leds ausgeben und da
> hängts

Dann ändere als erstes einmal diese Funktion so um, dass die den 
ausgelesenen Wert auch an den Aufrufer zurückgibt
1
unsigned short read_ADC(void)
2
{
3
  return ADC;            //Auslesen
4
}

als nächstes verpasst du der out_Led Funktion ein Argument, damit du 
dieser Funktion auch sagen kannst, was sie ausgeben soll
1
void out_LED( unsigned short Wert )
2
{
3
  DDRB = 0xff;    //POTRTB als Ausgang
4
  PORTB = Wert;
5
}

und dann verknüpfst du die beiden Funktionen, indem du den Wert, den du 
von der einen Funktion bekommst in die andere Funktion hineinstopfst
1
void test(void)
2
{
3
  unsigned short Wert;
4
5
  start_ADC();
6
  wait_ADC();
7
  Wert =  read_ADC();
8
  out_LED( Wert );
9
  _delay_ms(250);
10
}

und als nächstes besorgst du dir ein C-Buch.

von Florian T. (fthevissen)


Lesenswert?

> mit welchen befehl lese ich denn ein ADC aus?

Ein C Buch, und ne Stunde oder Zwei um das Datenblatt des uCs genau zu 
studieren.

Ist das uebrigens "Alles" was der uC machen soll? Also nur den ADC lesen 
und irgendwas mit dem Ergebnis anstellen?

Dann kommst du um timer und interrupts naemlich herum, kommst aber in 
die Bredouille dass jeder Befehl selber noch ein paar Zyklen, und somit 
Zeit, beansprucht.

Wenn es dann ganz genau (!) 250ms werden sollen musste dir das 
Disassembly Listing anschauen, das der Compiler von deinem C code 
erzeugt hat und rausfinden wie lange das Alles wirklich dauert. C ist 
nunmal leider nur eine Abstraktion.

von Hannes L. (hannes)


Lesenswert?

> Wenn es dann ganz genau (!) 250ms werden sollen musste dir das
> Disassembly Listing anschauen, ...

Das mag für Warteschleifen (Delay-Funktion) gelten, aber nicht für den 
Timer-Interrupt. Dem ist es nämlich egal, ob er per C oder ASM 
initialisiert wurde, der schlägt im exakten Takt zu. Und dem ist es auch 
egal ob eine C-Zuweisung (portx=adcl) oder eine ASM-Codesequenz
(in r0,adcl; out portx,r0) das Ergebnis abholt.

Alle meine bisherigen Programme kommen zwar ohne C aus, die meisten von 
ihnen aber nicht ohne Timer-Interrupt.

...

von Florian T. (fthevissen)


Lesenswert?

> "Der timer laeuft unabhaengig von dem was die CPU grade anstellt; nur
> die Initialisierung kostet Zeit"
(Mal von dem Aufruf der ISR abgesehen und wie geschickt man sich in der 
ISR anstellt, das kann auch Zeit kosten)

Oehm, sag' ich doch?

von Hannes L. (hannes)


Lesenswert?

> Oehm, sag' ich doch?

Ja sicher doch, aber manchmal versteht es der (nicht übermäßig 
motivierte) Anfänger besser, wenn er es auf verschiedene Arten erklärt 
bekommt.

;-)

...

von Florian T. (fthevissen)


Lesenswert?

Also bei dem Stuss wirds mir schwindlig.

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.