Forum: Mikrocontroller und Digitale Elektronik Attiny85 ADC


von Teslafan (Gast)


Lesenswert?

Hallo miteinander,

ich bin am verzweifeln. Ich habe mir das Tutorial für die ADC Wandlung 
angesehen, und den folgenden Code geschrieben für einen Attiny85 
geschrieben. Jedoch reagiert er einfach nicht wenn ich 5V an den Eingang 
lege. Ich wäre für jeden Tip dankbar.



#define F_CPU 1000000UL


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

#define OUTPUT_PIN  PB1
#define INPUT_PIN  PB3



void initADC(){

  // Set the ADC input to PB2, left aligned result
  ADMUX |= (1 << MUX0);
  ADMUX |= (1 << ADLAR);

  // Set the prescaler to clock/8 (125kHz) & enable ADC
  ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}


int readADC(){
      // Start the conversion
      ADCSRA |= (1 << ADSC);

      // Wait for it to finish
      while (ADCSRA & (1 << ADSC));

      return ADCH;
}

int main(void)
{

  DDRB |= (1 << OUTPUT_PIN);
  initADC();
  int analogInput=0;

    while(1)
    {
    _delay_ms(10);
    analogInput=readADC();
    if(analogInput > 128){ PORTB |= (1<<OUTPUT_PIN); }
    else{PORTB &= ~(1<<OUTPUT_PIN); }
    }
}

von Karl M. (Gast)


Lesenswert?

Hallo Teslafan,

hast Du dir auch das Datenblatt zum Attiny85 angesehen ?

Nicht dass da Bits in anderen Registern zu finden sind.

Wie sieht die Außenbeschaltung des Attiny85 komplett aus ?

Ich würde beim Init über initADC() noch eine ADC-Wandlung starten und 
das Ergebnis dann verwerfen.
Aber das ist für einen einfachen Test - geht / geht nicht - nicht so 
wichtig.

Als Erweiterung im Code für einen realen Einsatz, stelle ich an den 
passenden Bits im DIDR0 – Digital Input Disable Register 0.

Also in deinem Beispiel:
DIDR0 |= (1<<ADC1D);

von Holger L. (max5v)


Lesenswert?

Versuch bitte mal diese Zeile
Teslafan schrieb:
> while (ADCSRA & (1 << ADSC));

durch diese zu ersetzen.
 while (ADCSRA & (1 << ADSC)) {}

Die Register \ Code scheinen in Ordnung zu sein, das einzige was mir 
noch auffällt ist der unbvenutzte #define INPUT_PIN  PB3 wenn der für 
den ADC eingang stehen sollte hast du es vermutlich an dem falschen Pin 
angeschlossen. Der richtige wäre Pin7 (PB2)

von Teslafan (Gast)


Lesenswert?

Danke schonmal für eure Hilfe!

Habe alle Register nochmal gecheckt und die Zeilen angepasst. Die 
Schaltung ist trivial, an PB2 habe ich testweise 5V und an PB3 hängt 
eine LED, welche auch entsprechend ohne ADC angesteuert und getestet 
ist. Aber der ADC will nicht.
Ich habe mal getestet, ob der ADC an PB5 funktioniert. Da leuchtet die 
LED immer, und geht nur aus, wenn ich den ADC PB5 auf Masse lege. Das 
ist wenigstens ein Fortschritt. Könnte vielleicht ein Pull-up helfen, 
oder ist das nicht üblich. Der aktuelle Code:

#define F_CPU 1000000UL


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

#define OUTPUT_PIN  PB1


void initADC(){

  // Set the ADC input to PB2/ADC1, left aligned result
  ADMUX |= (1 << MUX0);
  ADMUX |= (1 << ADLAR);

  DIDR0 |= (1<<ADC1D);

  // Set the prescaler to clock/8 & enable ADC
  ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}


int readADC(){
      // Start the conversion
      ADCSRA |= (1 << ADSC);

      // Wait for it to finish
      while (ADCSRA & (1 << ADSC)) {}

      return ADCH;
}

int main(void)
{

  DDRB |= (1 << OUTPUT_PIN);

  initADC();
  int analogInput=0;

    while(1)
    {
    _delay_ms(10);
    analogInput=readADC();
    if(analogInput > 200){ PORTB |= (1<<OUTPUT_PIN); }
    else{PORTB &= ~(1<<OUTPUT_PIN); }
    }
}

von Karl M. (Gast)


Lesenswert?

Holger,

kannst Du bitte erläutern, warum er das umschreiben sollte ?
Das ist doch Syntaktisch das gleiche.

Holger L. schrieb:
> Versuch bitte mal diese Zeile
> Teslafan schrieb:
>> while (ADCSRA & (1 << ADSC));
>
> durch diese zu ersetzen.
>  while (ADCSRA & (1 << ADSC)) {}

von Peter D. (peda)


Lesenswert?

Füge mal ne SW-UART ein und laß Dir den ADC-Wert ausgeben.

von luis (Gast)


Lesenswert?

Teslafan schrieb:
> Ich habe mal getestet, ob der ADC an PB5 funktioniert. Da leuchtet die
> LED immer, und geht nur aus, wenn ich den ADC PB5 auf Masse lege. Das
> ist wenigstens ein Fortschritt. Könnte vielleicht ein Pull-up helfen,
> oder ist das nicht üblich. Der aktuelle Code:

Na ja, PB5 ist RESET. Damit ist bewiesen, daß der RESET geht ;-)

Pullup an einem ADC Eingang ist nicht üblich aber vorstellbar. Würde dir 
aber hier vermutlich nicht helfen.

von Thomas E. (thomase)


Lesenswert?

Holger L. schrieb:
> durch diese zu ersetzen.
>  while (ADCSRA & (1 << ADSC)) {}

Welchen Sinn soll das haben?

Teslafan schrieb:
> Die Schaltung ist trivial

Scheinbar nicht, denn das Programm läuft.

Teslafan schrieb:
> Könnte vielleicht ein Pull-up helfen, oder ist das nicht üblich.

Wenn der Eingang offen ist, hast du einen undefinierten Zustand. Da der 
Controller damit aber nichts anfangen kann, denkt er sich irgendwas aus. 
Was in aller Regel Blödsinn ist.
Das gilt besonders für einen Analogeingang.

mfg.

von Holger L. (max5v)


Lesenswert?

>> durch diese zu ersetzen.
>>  while (ADCSRA & (1 << ADSC)) {}

Ich habe es nur mit geschweiften klammern gelernt, daher.

von luis (Gast)


Lesenswert?

Möglicherweise hast du dir auch einen Schluß zu einem anderen Pin zB zu 
Vcc reingebastelt.

von Thomas E. (thomase)


Lesenswert?

luis schrieb:
> Möglicherweise hast du dir auch einen Schluß zu einem anderen Pin zB zu
> Vcc reingebastelt.

Oder den Programmer nicht abgezogen.

mfg.

von Teslafan (Gast)


Lesenswert?

Danke nochmal für die viele Hilfe, ihr seid echt super!

Ich habe jetzt noch PB4 ausprobiert, also den ADC2, der funtioniert. 
Wenn ich die Spannung jedoch wegnehme flackert die LED am Ausgang noch 
etwas, das habe ich mit dem Pull-up auf Masse unterbunden. Denke das 
reicht mir als Lösung.

von Thomas E. (thomase)


Lesenswert?

Teslafan schrieb:
> das habe ich mit dem Pull-up auf Masse unterbunden. Denke das
> reicht mir als Lösung.

Das nennt sich dann Pull-Down. Aber Hauptsache, es geht jetzt soweit.

mfg.

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.