Forum: Mikrocontroller und Digitale Elektronik Potentiometer mit Atmega8 ADC verbinden und programieren


von H. Wang (Gast)


Angehängte Dateien:

Lesenswert?

hallo Zusammen,

bin ein Änfanger mit Atmega8 und habe einen Kontroller gebauert mit 2 
analogen Joysticks (jeweils mit 2 Potentiometer X und Y richtungen).

X-Richtung des Joystick 1 ist mit PC0(ADC0) verbunden und Y- Richtung 
mit PC1(ADC1). Um das Ergebnis zu testen habe ich noch eine LED an PC5 
gelötet. Die Spannung bewegt sich zwischen ca. 4.93v und 0.02v , wenn 
ich Joystick nach links oder rechts steuere. Ruhlage liegt bei  ca. 
2,5v.

Ich habe erst mal das Testprogramm für Y-Richtung des Joystick 1 
geschrieben. LED soll leuteten, wenn Wert klein als 50 ist. Aber leider 
funktionniert das nicht. LED bleibt immer „an“, als ich das Programm 
hochgeladen habe, obwohl ich Joystick bewegt habe.

Ich habe mit AVR Studio 4.15 programmiert und mit PonyPorg2000 durch ISP 
das Programm hochgeladen.

------------------------------------------
#include <avr/io.h>
#include <util/delay.h>

void main()
{
  int sample,i,value;

  DDRC |= (1<<5);  //PC5 als Ausgang

  ADMUX=(0<<REFS1)|(1<<REFS0)|(1<<MUX0);  // ADC Ref auf Avcc, PC1 
gewaehlt
  ADCSR=(1<<ADEN)|(0<<ADPS0)|(1<<ADPS1)|(1<<ADPS2); // ADC 
eingeschaltet, 64 Bit Prescale
  while(1)
  {
    sample=0;
    for(i=0;i<64;i++)
    {
      ADCSRA=0b01000000;  //single conversion mode ein
      while(ADCSRA & (1<<ADSC));  //warten bis konvertierung 
abgeschlosen
      sample+=ADCW;  //aufsummierung der samplewerte, ADCW ist Ergebnis
    }
    value=sample/64;  //aritmethisches mittel der samplewerte

    if (value > 50)
      PORTC &= ~(1<<5);  //schaltet LED aus
     else
      PORTC |= (1<<5);  //schaltet LED ein
  }
}

: Verschoben durch User
von Karl H. (kbuchegg)


Lesenswert?

H. Wang schrieb:

>   ADCSR=(1<<ADEN)|(0<<ADPS0)|(1<<ADPS1)|(1<<ADPS2); // ADC

laut meinem Datenblatt hat ein Mega8 gar kein Register ADCSR.
Bitte klären.

Wenn da bei dir in Wirklichkeit ADCSRA steht (so wie es sein sollte), 
dann ...


> eingeschaltet, 64 Bit Prescale
>   while(1)
>   {
>     sample=0;
>     for(i=0;i<64;i++)
>     {
>       ADCSRA=0b01000000;  //single conversion mode ein

... gratuliere. Du hast dir soeben die mühsam eingestellte Konfiguration 
von oben zerschossen

besser
        ADCSRA |= (1<<ADSC);

dann braucht man nicht lange rätseln, was dieses eine Bit sein soll

von AVRuser (Gast)


Lesenswert?

Hallo,

das kann so nicht laufen.

in der "main" schreibst du:

>  ADCSR=(1<<ADEN)|(0<<ADPS0)|(1<<ADPS1)|(1<<ADPS2); // ADC eingeschaltet, 64
>  Bit Prescale

was soweit in Ordnung ist.
In der for-Schleife steht nun:

>  ADCSRA=0b01000000;  //single conversion mode ein

Damit schreibst du alle Bits, die du vorher gesetzt hast, wieder auf 
Null. D.h., der ADC wird abgeschaltet.

Sinnvoll ist, das Bit ADSC zu setzen, zu warten, bis es wider Null ist, 
und dann ADCW zu lesen. So steht es auch hier im ADC-GCC-Tutorial.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Zum Schaltplan:

[KAA-MODUS AN]
Du willst Aref nicht mit Avcc verbinden.
Du willst einen 100nF Kondensator zwischen Aref und GND haben.
Du willst einen 100nF Kondensator zwischen AVcc und GND haben.
[KAA-MODUS AUS]

Hoffentlich ist zwischen nicht eingezeichnetem Vcc und GND der 100nF 
Kondensator vorhanden.

Die Verbindung GND-###->|-PC5 verstehe ich nicht. Wenn das eine LED ist, 
die active high betrieben wird, müsste das so aussehen GND-###-|<-PC5

von H. Wang (Gast)


Lesenswert?

Dank für eure Antworten!

Richtig, ich habe die eingestellte Konfiguration wieder auf 0 gesetzt.

Aber ich meine ADCSRA ist gliech ADCSR, oder?

Zum Schaltplan, habe ich auch falsch gezeichnet, aber ich habe nicht 
falsch gelötet ^_^

Nach der Verbesserung funktioniert das noch nicht so ganz gut. Ich 
bewege Joystick von der Ruhrlage nach unten. Bis ca. 0,25V schalt LED 
an, d.h. bei 0,25V ist der digitale Wert 50. Aber bewege ich den 
Joystick von Ruhrlage nach oben, dann bleibt LED von 2,3v bis 4,9 v 
ganzen Zeit an.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Du hast sample als int definiert. Und du addierst 64 10-Bit 
Einzelergebnisse. Welche Gedanken hast du dir über einen Integerüberlauf 
gemacht? Tipp: Definiere sample mal uint16_t oder verringere die 
Anzahl der Samples auf 32 oder weniger.

von H. Wang (Gast)


Lesenswert?

war meine Fehler. Ich habe vorher über Integerüberlauf keine Gedanken 
gemacht. jetzt habe auf 32 geändert und es funktioniert einwandfrei.

vielen Dank Stefan!!

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.