Forum: Mikrocontroller und Digitale Elektronik ADC auswerten


von Marcel H. (repac3r)


Lesenswert?

Guten tag liebe com,
ich arbeite mich gerade in das Thema ADC ein. Mein Problem
ist jetzt nur wie kann ich das ADCH register Auswerten und z.B.:
eine Zahl auf ein Dispay ausgeben lassen, wenn ich an meinem Poti drehe 
?

Hier mein bishergier Code:
1
#define F_CPU 3686400UL
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include "lcd-routines.h"
6
7
char itoa_buffer[8];
8
9
ISR(ADC_vect)
10
{
11
  lcd_clear();
12
  lcd_string() <-- ADCH ?
13
}
14
15
int main(void)
16
{  
17
  //LCD
18
  lcd_init();
19
  lcd_clear();
20
  lcd_home();
21
  
22
  //ADC
23
  ADMUX |= (1<<ADLAR);  //8bit, ADC0
24
  ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (1<<ADIE)    //Enable, Single Conversion, Free Running, Interrupt
25
         | (1<<ADPS2) | (1<<ADPS0);              //Prescaler 32
26
       
27
  sei();  //Enable Interrupt
28
    while(1)
29
    {
30
        //TODO:: Please write your application code 
31
    }
32
}

Aber wie kann ich jetzt z.B.: den Wert der in ADCH geschrieben ist
Prozentual von 0-100% berechen ?

von Marcel H. (repac3r)


Lesenswert?

Ok habe zum 'Test' einfach mal die IST ein bisschen geändert
1
char itoa_buffer[8];
2
3
ISR(ADC_vect)
4
{
5
  lcd_clear();
6
  itoa(ADCH, itoa_buffer, 10);
7
  lcd_string(itoa_buffer);
8
  _delay_ms(250);
9
}

Jetzt wird mir konstant der Wert 255 angezeigt, egal wie ich am Poti 
herum drehe.

Wenn ich mal überlege ist der Wert 255 ja 8bit groß, heißt es das sich 
der Wert garnicht ändert wenn der ADC immer 8bit groß ist ?

von .. (Gast)


Lesenswert?

delay in ISR - Todsünde!

von Marcel H. (repac3r)


Lesenswert?

.. schrieb:
> delay in ISR - Todsünde!

Ich weiß, ich wollte auch nur Testen, denn wenn ich das LCD in dieser 
ISR ohne delay anspreche, wird der Text zu schnell geändert, so dass das 
LCD nicht mehr mitkommt ;)

von Hubert G. (hubertg)


Lesenswert?

Wo startest du die Conversion erneut?

von Marcel H. (repac3r)


Lesenswert?

Geschicht das durch die Interrupts nicht automatisch ?

von Michael A. (Gast)


Lesenswert?

Marcel Hoffmann schrieb:
> Ich weiß, ich wollte auch nur Testen, denn wenn ich das LCD in dieser
> ISR ohne delay anspreche, wird der Text zu schnell geändert, so dass das
> LCD nicht mehr mitkommt ;)

Die Formatierung mit itoa() und die LCD-Ausgabe hat in der ISR genauso 
wenig zu suchen, wie ein delay().
In der ISR kannst du ein flag setzen, wenn neue Daten vorhanden sind. 
Die Aufbereitung für das Display passiert in der Hauptschleife, wenn der 
µC Langeweile hat.

von Hubert G. (hubertg)


Lesenswert?

Nein, du hast SingleConversion bei den ADC-Einstellungen ausgewählt. Da 
wird die eine Conversion ausgeführt.
Erneut starten mit ADCSRA |= (1<<ADSC);

von Marcel H. (repac3r)


Lesenswert?

Ok jetzt habe ich mal größtenteils die Befehle in eine Funktion 
eingefügt, mein Problem ist aber jetzt, das kein Wert angezeigt wird.
Ich brauche ja nur aus dem ADCL Register lesen und nicht zusätzlich noch 
aus den ADCH, weil ich ja mit ADMUX |= (1<<ADLAR) gesagt habe das ich 
nur eine Breite von 8Bit haben möchte, ist das richtig ?

Hier mein Code;
1
uint16_t xdata;
2
char buffer[8];
3
4
void show_adc();
5
6
ISR(ADC_vect)
7
{
8
  show_adc();
9
  ADCSRA |= (1<<ADSC);    //neu laden
10
}
11
12
void show_adc()
13
{
14
  xdata = ADCL;
15
  itoa(xdata, buffer, 10);
16
  lcd_clear();
17
  lcd_string(buffer);
18
}

von Dussel (Gast)


Lesenswert?

Hubert G. schrieb:
> Nein, du hast SingleConversion bei den ADC-Einstellungen ausgewählt.

Marcel Hoffmann schrieb:
> ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (1<<ADIE)

Wo ist Single Conversion eingestellt?

von Marcel H. (repac3r)


Lesenswert?

Ok habe es jetzt teilweise geschafft.
Das Display gibt mir jetzt ein Wert von -64 bis - (ca.) -31000 &
(ca.) +31000 bis +64 an. Kann ich das nicht irgendwie darstellen lassen 
dass das ganze ab 0 anfängt, oder muss ich das umrechnen ?

von Dussel (Gast)


Lesenswert?

Marcel Hoffmann schrieb:
> Ich brauche ja nur aus dem ADCL Register lesen und nicht zusätzlich noch
> aus den ADCH, weil ich ja mit ADMUX |= (1<<ADLAR) gesagt habe das ich
> nur eine Breite von 8Bit haben möchte, ist das richtig ?
Das habe ich gerade erst gelesen. Das ist nicht richtig. ADLAR stellt 
nur die Speicherung des Ergebnisses in den beiden Registern ein. Bei 
ADLAR=0 sind die unteren acht Bit zusammen in einem Register (ADCL), bei 
ADLAR=1 die oberen acht in ADCH. Die restlichen beiden Bit sind dann 
jeweils im anderen Register. Du musst also ADCH auslesen.

von Hubert G. (hubertg)


Lesenswert?

Dussel schrieb:
> Wo ist Single Conversion eingestellt?

Man sollte sich nicht auf den Kommentar verlassen, oder zumindest alles 
durchlesen.

von Marcel H. (repac3r)


Lesenswert?

Dussel schrieb:
> Marcel Hoffmann schrieb:
>> Ich brauche ja nur aus dem ADCL Register lesen und nicht zusätzlich noch
>> aus den ADCH, weil ich ja mit ADMUX |= (1<<ADLAR) gesagt habe das ich
>> nur eine Breite von 8Bit haben möchte, ist das richtig ?
> Das habe ich gerade erst gelesen. Das ist nicht richtig. ADLAR stellt
> nur die Speicherung des Ergebnisses in den beiden Registern ein. Bei
> ADLAR=0 sind die unteren acht Bit zusammen in einem Register (ADCL), bei
> ADLAR=1 die oberen acht in ADCH. Die restlichen beiden Bit sind dann
> jeweils im anderen Register. Du musst also ADCH auslesen.

Ok habe ich auch geschafft habe einfach die interne Referenz Spannung 
benutzt. Danke für die Hilfe ;)

von Dussel (Gast)


Lesenswert?

Hubert G. schrieb:
> Dussel schrieb:
>> Wo ist Single Conversion eingestellt?
>
> Man sollte sich nicht auf den Kommentar verlassen, oder zumindest alles
> durchlesen.
Das habe ich jetzt erst auf mich bezogen und gesucht, wo ich da was 
falsch gelesen habe…

Vor Allem, da im Kommentar 'Single Conversion, Free Running' steht.

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.