Forum: Mikrocontroller und Digitale Elektronik Atmega8, ADC verständnis, Sprache C,


von Der Lars (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich versuche mir die Sache mit dem Analog Digital Wandler beizubringen. 
Dafür habe ich mir ein kleines Projekt ausgedacht.
Ich habe 5LEDs und möchte durch drehen am Potentionmeter zwischen den 
LEDs hin und her schalten könnten. (Ein Schaltplan hängt der Frage bei.)
Dieses Projekt soll nur zu Übungszwecken dienen und  hat kein richtigen 
Sinn.

Den Code habe ich mit Hilfe des Tutorials selbst zusammen gebastelt und 
sieht nun so aus:
1
#define F_CPU 8000000
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
5
unsigned int result;
6
7
int main()
8
{
9
  DDRB = 0xff;
10
  PORTB = 0x00;
11
12
  
13
    ADMUX = (1<<REFS0) | (1<<ADLAR);
14
    ADCSRA = (1<<ADEN) | (1<<ADFR) | (1<<ADIE);
15
while(1)
16
  {
17
    ADCSRA |= (1<<ADSC);
18
    result = ADCH;
19
    _delay_ms(100);
20
21
    if (result < /* noch undefiniert */)
22
    {
23
      PORTB = (1<<PB1);
24
    }
25
    if (result < /* noch undefiniert */)
26
    {
27
      PORTB = (1<<PB2);
28
    }
29
    if (result < /* noch undefiniert */)
30
    {
31
      PORTB = (1<<PB3);
32
    }
33
    if (result < /* noch undefiniert */)
34
    {
35
      PORTB = (1<<PB4);
36
    }
37
    if (result < /* noch undefiniert */)
38
  }
39
40
}

Wenn jemand einen Fehler in dem Schaltplan oder in dem Code findet oder 
Verbesserungsvorschläge hat bin ich über Kritik sehr dankbar.
Mein Eigentliches Problem ist aber, dass ich nicht weiß, wie das 
eigentliche Ergebnis, Also im Grunde der Wert "ADCH", nachher aussieht.

Ich habe schonmal versucht das herauszufinden indem ich einfach gesagt 
habe:
1
if (result < 100)
2
    {
3
      PORTB = (1<<PB1);
4
    }
5
    if (result > 100)
6
    {
7
      PORTB = (1<<PB5);
8
    }
Das habe ich mit verschiedenen Werten wie
result < 1000 und result > 1000
oder
result < 10 und result > 10
gemacht. aber dadurch bin ich immer nicht schlauer geworden, weil ich 
das Gefühl habe, dass das Ergebnis immer 0 ist.
Kann mir da jemand einen guten Hinweis geben wie ich mein Projekt zum 
Laufen bekomme?

Vielen Dank im Vorraus.
Der Lars

von Karl H. (kbuchegg)


Lesenswert?

Der Lars schrieb:

> Den Code habe ich mit Hilfe des Tutorials selbst zusammen gebastelt und
> sieht nun so aus:

Warum nimmst du dann nicht erst mal die ADC-Routinen aus dem 
AVR-GCC-Tutorial so wie sie sind. Und wenn du dann etwas am laufen hast, 
fängst du vorsichtig an, sie abzuändern.

>     ADCSRA = (1<<ADEN) | (1<<ADFR) | (1<<ADIE);

Gib niemals einen Interrupt frei, wenn du ihn nicht brauchst!

> Mein Eigentliches Problem ist aber, dass ich nicht weiß, wie das
> eigentliche Ergebnis, Also im Grunde der Wert "ADCH", nachher aussieht.

Eine Zahl zwischen (da du ADLAR aktiviert hast) 0 und 255


> aber dadurch bin ich immer nicht schlauer geworden, weil ich
> das Gefühl habe, dass das Ergebnis immer 0 ist.

Da du das Gefühl hast, es also nicht sicher weißt, ist es in ALLEN 
Projekten immer eine extrem gute Idee, sich zuerst mal einen Weg zur 
Ausgabe zu schaffen. Und zwar nicht nur mit einer einzelnen LED, sondern 
im besten Fall einen Weg, an dem du Zahlenwerte direkt ausgeben kannst. 
UART würde sich zb anbieten, weil man dort alles im Klartext ausgeben 
kann. Zur Not gehen auch 8 LED an einem Port, an dem man Zahlen binär 
rausgeben kann. Dann muss man eben selber ein wenig umrechnen.

Aber eine einzelne LED ist für Anfänger kein sehr gutes Debug-Werkzeug. 
Mit ein wenig Erfahrung geht es schon, aber es ist sehr mühsam und 
erfordert eine gut ausgebildete Debug-Strategie.

Und nein: Das schlimmste was du als Beginner annehmen kannst ist, dass 
du auf Anhieb ein fehlerfreies Programm hinkriegen wirst. Egal wie 
einfach die Aufgabe aussieht. Das ist die absolute Ausnahme. Der 
Normalfall ist, dass eben nichts funktioniert. Daher ist es eine gute 
Idee, sich bei einer neuen Thematik, so wie bei dir ADC, sich zunächst 
mal getestete und erprobte Funktionen (wie die vom Tutorial) zu nehmen 
und mit denen zu arbeiten. Hat man dann ein wenig Sicherheit, dann 
ändert man sie ab. Aber: vorsichtig und in kleinen Schritten abändern! 
So dass man jeder Zeit wieder zu etwas Funktionierendem zurück kann, 
wenn man eine Änderung verbockt hat.

von Mathias F. (minglifu)


Lesenswert?

Servus,

also wenn ich mir deinen Schaltplan so ansehe seh ich etwas, das 
warscheinlich dem Mega, den LED´s und zum Schluss dir ^^ nicht allzu gut 
tut!

Kommst du drauf?

Ich sag nur:

-VOH ~ 4,2V
-Vf  ~ 1,5-1,8V
-If  ~ 1-2A

MfG
MingliFu

von Der Lars (Gast)


Lesenswert?

Okay. Vielen Dank erstmal :-)
Ich werd mir das Tutorial nochmal genauer vornehmen.

von Flo (Gast)


Lesenswert?

Moin.

Wie schon angedeutet solltest du die dioden nicht ohne vorwiderstand 
treiben.
Weiterhin wird immer das gleiche ergebnis vom AD wandler kommen, da das 
poti nicht als spannungsteiler funktioniert sonder wie ein normaler 
widerstand.

als spannungsteiler:

+5v____
       |
      | |
     <------- zum ADC
      |_|
       |
GND____|

Grusz Flo

von Flo (Gast)


Lesenswert?

edit:

hab noch n passenden link den ich grad natuerlich vergasz...

http://www.dieelektronikerseite.de/Lections/Potentiometer - Alles 
geregelt.htm

Viel erfolg noch, das klappt schon.

von dasrotemopped (Gast)


Lesenswert?

Tach Lars,

in Sachen deinem C-Code :
mit deiner IF Abfrage zum Schalten der LEDs wirst du die LEDs zwar alle 
der Reihe nach einschalten, aber du hast das Ausschalten vergessen.

Gruß,

dasrotemopped.

von Der Lars (Gast)


Lesenswert?

Vielen Dank erstmal an alle.

Die verwendeten LED´s haben einen eingebauten Vorwiderstand, desshalb 
habe ich auch keinen in meinen Schaltplan eingesetzt. Hätte ich 
vielleicht erwähnen sollen. ^^

@dasrotemopped:
Doch die LEDs gehen wieder aus.
Wenn ich erst
PORTB = (1<<PB1);
setze
und später nochmal sage
PORTB = (1<<PB3);
setzt es alle Bits bis auf Bit3 auf 0.

@Flo:
Könntest du mir nochmal den Link raussuchen?
Der von dir angegebene ist nicht gültig. und auf der Seite konnte ich 
nicht genau finden, was du mir damit zeigen wolltest.

von Karl H. (kbuchegg)


Lesenswert?

Der Lars schrieb:

> Könntest du mir nochmal den Link raussuchen?

Da wird nicht viel mehr stehen, als das ein Poti ein Widerstand ist, bei 
dem man auf einer Widerstandsbahn mit dem Abgriff einen Wert abnehmen 
kann.

So wie Flo das ein Posting davor aufgezeichnet hat, so passt das.
Das ist ein Poti, welches als Spannungsteiler vetrieben wird. Durch 
Verdrehen des Potis kann man am Abgriff jede Spannung zwischen 0 und Vcc 
erzeugen.

von Der Lars (Gast)


Lesenswert?

WOOOW, Es funktioniert :-)

Flo, ich hab mir die Geschichte mit diesem Spannungsteiler nun nochmal 
angeschaut. Das war der Knackpunkt, warum es nicht geklappt hat. :-) 
Vielen Dank.

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.