Forum: Mikrocontroller und Digitale Elektronik AVCC -> falsche Spannungen


von anonymus (Gast)


Lesenswert?

Guten Abend,

ich wollte mit dem Atmega8 eine Spannung an Pin PC4 (ADC4) auslesen.
Daher habe ich zwischen PIN PC5 und PC4 einen Potentiometer geklemmt.

Leider liefert mir der Pin PC5 nicht die volle Spannung. Es liegt nur 
zirka ein drittel an.

Weiß jemand woran das liegen kann?

Code:
//----------------------------------------------------------------------
#define   F_CPU 3686400     // Taktfrequenz des myAVR-Boards
#include  <avr\io.h>        // AVR Register und Konstantendefinitionen
#include <inttypes.h>    //Datentyplib
//----------------------------------------------------------------------
uint16_t readADC(uint8_t channel)
{

  //Avcc auf 4,5 V
  //AREF auf 4,5 V; Damit obere Messgrenze auf 4,5 V gelegt
  //GND zu GND
  //Funktion läuft über Avcc!!!!!

  uint8_t i;
  uint16_t result = 0;

  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);            //Den ADC 
aktivieren /Teilungsfaktor auf 64 stellen
  ADMUX = channel | (0<<REFS1) | (1<<REFS0);              //Avcc als 
Spannungsquelle verwenden /ADC4 messen

  ADCSRA |= (1<<ADSC);                        //ADC initialisieren 
/Dummyreadout machen
  while(ADCSRA & (1<<ADSC));

  for(i=0; i<3; i++)
  {
    ADCSRA |= (1<<ADSC);
    while(ADCSRA & (1<<ADSC));

    result += ADCW;
  }

  ADCSRA &= ~(1<<ADEN);

  result /= 3;

  return result;
}
//----------------------------------------------------------------------

int main (void)
{
  DDRB  = 0xff;
  DDRD  = 0xff;
  //DDRC  &= ~(0xff);
  DDRC = 1,1,1,1,1,0;

  while(1)
  {
    PORTC = (1<<PC5) | (0<<PC4);            //Eingang und Ausgang 
schalten

    uint16_t result = readADC(00100);          //ADC auslesen für Pin 
PC4 /ADC4

    if (result < 400)
    {
      //ADC auswerten
      PORTD = (1<<PD5) | (1<<PD6) | (1<<PD7);
    }
    //ADC auswerten
    if (result > 800)
    {
      //ADC auswerten
      PORTD = (1<<PD5) | (0<<PD6) | (0<<PD7);
    }
    //ADC auswerten
    if ((result < 801) and (result > 399))
    {
      //ADC auswerten
      PORTD = (1<<PD5) | (1<<PD6) | (0<<PD7);
    }
    //ADC auswerten

  }

  /* wird nie erreicht */
  return 0;
}

//----------------------------------------------------------------------

von (prx) A. K. (prx)


Lesenswert?

Kann es sein, dass dein VCC 5V beträgt und AVCC 4,5V?
Wäre keine gute Idee.

von holger (Gast)


Lesenswert?

>  DDRC = 1,1,1,1,1,0;

Was ist das denn?

> uint16_t result = readADC(00100);          //ADC auslesen für Pin

Da übergibst du 100 und nicht 4.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

anonymus schrieb:
> Leider liefert mir der Pin PC5 nicht die volle Spannung. Es liegt nur
> zirka ein drittel an.
Was für ein Poti?

> Weiß jemand woran das liegen kann?
> DDRC = 1,1,1,1,1,0;
Was willst du damit bewirken?
Da steht länger geschrieben sowas:
DDRC = 1;
1;
1;
1;
1;
0;

holger schrieb:
>> uint16_t result = readADC(00100);          //ADC auslesen für Pin
> Da übergibst du 100 und nicht 4.
Da übergibst du eine oktale (!) 100, also mithin dezimale 64 ... :-o

von (prx) A. K. (prx)


Lesenswert?

holger schrieb:

> Da übergibst du 100 und nicht 4.

Weder noch. 00100 = 0x40 = 64.

von anonymus (Gast)


Lesenswert?

Veränderte Version mit selben Ergebnis:

//----------------------------------------------------------------------
#define   F_CPU 3686400     // Taktfrequenz des myAVR-Boards
#include  <avr\io.h>        // AVR Register und Konstantendefinitionen
#include <inttypes.h>    //Datentyplib
//----------------------------------------------------------------------
uint16_t readADC(uint8_t channel)
{

  //Avcc auf 4,5 V
  //AREF auf 4,5 V; Damit obere Messgrenze auf 4,5 V gelegt
  //GND zu GND
  //Funktion läuft über Avcc!!!!!

  uint8_t i;
  uint16_t result = 0;

  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);            //Den ADC 
aktivieren /Teilungsfaktor auf 64 stellen
  ADMUX = channel | (0<<REFS1) | (1<<REFS0);              //Avcc als 
Spannungsquelle verwenden /ADC4 messen

  ADCSRA |= (1<<ADSC);                        //ADC initialisieren 
/Dummyreadout machen
  while(ADCSRA & (1<<ADSC));

  for(i=0; i<3; i++)
  {
    ADCSRA |= (1<<ADSC);
    while(ADCSRA & (1<<ADSC));

    result += ADCW;
  }

  ADCSRA &= ~(1<<ADEN);

  result /= 3;

  return result;
}
//----------------------------------------------------------------------

int main (void)
{
  DDRB  = 0xff;
  DDRD  = 0xff;
  //DDRC  &= ~(0xff);
  DDRC = (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | 
(0<<PC5);

  while(1)
  {
    PORTC = (1<<PC5) | (0<<PC4);            //Eingang und Ausgang 
schalten

    uint16_t result = readADC(4);          //ADC auslesen für Pin PC4 
/ADC4

    if (result < 400)
    {
      //ADC auswerten
      PORTD = (1<<PD5) | (1<<PD6) | (1<<PD7);
    }
    //ADC auswerten
    if (result > 800)
    {
      //ADC auswerten
      PORTD = (1<<PD5) | (0<<PD6) | (0<<PD7);
    }
    //ADC auswerten
    if ((result < 801) and (result > 399))
    {
      //ADC auswerten
      PORTD = (1<<PD5) | (1<<PD6) | (0<<PD7);
    }
    //ADC auswerten

  }

  /* wird nie erreicht */
  return 0;
}

//----------------------------------------------------------------------

von Karl H. (kbuchegg)


Lesenswert?

anonymus schrieb:

> Leider liefert mir der Pin PC5 nicht die volle Spannung. Es liegt nur
> zirka ein drittel an.


>   DDRC = (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) |
> (0<<PC5);


Ähm.
Pins 1 bis 4 sind hier auf Ausgang geschaltet. Pin PC5 auf Eingang.

Bist du sicher, dass du nicht erst mal im Tutorial vorne anfangen 
solltest?

von (prx) A. K. (prx)


Lesenswert?

anonymus schrieb:

>   DDRC = (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) |
> (0<<PC5);

PC4 = raus,
PC5 = rein.

>     PORTC = (1<<PC5) | (0<<PC4);            //Eingang und Ausgang
> schalten

PC5 = raus?

>     uint16_t result = readADC(4);          //ADC auslesen für Pin PC4
> /ADC4

PC4 = rein.

von Gregor B. (gregor54321)


Lesenswert?

0xff | (0<<PIN5)
Ergebnis: 0xff

0x00 | (0<<PIN5)
Ergebnis: 0x00

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.