Forum: Mikrocontroller und Digitale Elektronik Atmega328 Hilfe mit ADC


von 328_Hilfloser (Gast)


Lesenswert?

Hallo zusammen,

Ich benutze einen Atmega328 und möchte mit dem ADC ein 
Wiederstandsnetzwerk auswerten. Ich benutze den Quellcode aus dem 
AVR-GCC Tut.

Probiere jetzt schon seit 2 Tagen aber komme zu keinem Ergebnis, der 
Wert auf meinem Display zeigt immer 1023. Egal was ich versuche. An 
meiner Schaltung liegt es denk ich nicht.

Am Ausgang meines Netzwerkes liegen wie gewünscht Werte zwischen 0-5V 
an.
Ich Arbeite am mit einem Prozessortakt mit 20000000 Hz und einem ADC 
Vorteiler von 128.

Auf dem Atmega8 lief der Code noch ohne Probleme. Mit der Hilfe des 
Datenblattes komm ich leider auch nicht wirklich weiter. Irgendwas 
übersehe ich noch:( aber was?

1
/*************************************************************************
2
Initialisierung des ADW
3
*************************************************************************/
4
void ADW_int(char rs1, char rs0)
5
{
6
  /*setz Spannungsreferenz*/
7
  ADMUX = (rs1<<REFS1) | (rs0<<REFS0);
8
  /* RS1 RS0  Bedeutung
9
    0 / 0 = Externes AREF
10
    0 / 1 = Internes AVCC - Versorgungsspannung des Atmega
11
    1 / 0 = Reserviert
12
    1 / 1 = Interne Referenzspannung 1,1 V  */
13
  
14
  /* setzen des Frequenzvorteilers*/
15
  ADCSRA = (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);
16
  /*ADPS2  ADPS1  ADPS0  Teilungsfaktor
17
    0    0    0    2
18
    0    0    1    2
19
    0    1    1    4
20
    1    0    0    16
21
    1    0    1    32
22
    1    1    0    64
23
    1    1    1    128  */
24
  
25
  /*muss zwischen 50-200kHz liegen
26
    bei 20Mhz kommt nur 128 in Frage ~ 156kHz*/
27
  
28
  /*ADC aktivieren*/
29
  ADCSRA = (1<<ADEN);
30
  
31
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
32
  also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
33
  ADCSRA |= (1<<ADSC);          // eine ADC-Wandlung ADSC startet die Wandlung
34
  while ( ADCSRA & (1<<ADSC) ) {      // auf Abschluss der Konvertierung warten 
35
  ;}
36
  
37
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen*/
38
  (void) ADC;    
39
  
40
}/*ADW_int*/
41
42
43
/*************************************************************************
44
ADW-Messung
45
*************************************************************************/
46
/* ADC Einzelmessung */
47
uint16_t ADC_Read( uint8_t channel )
48
{
49
  // Kanal waehlen, ohne andere Bits zu beeinflußen
50
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
51
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
52
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
53
  }
54
  return ADC;                // ADC auslesen und zurückgeben
55
}
56
57
/*MUX3...0
58
0000  ADC0
59
0001  ADC1
60
0010  ADC2
61
0011  ADC3
62
0100  ADC4
63
0101  ADC5
64
0110  ADC6
65
0111  ADC7
66
1000  ADC8*/
67
68
/*ADMUX Register
69
7  REFS1  - Referenzspannung
70
6  REFS0  - Referenzspannung
71
5  ADLAR
72
4  -
73
3  MUX3  - Kanalwahl
74
2  MUX2  - Kanalwahl
75
1  MUX1  - Kanalwahl
76
0  MUX0  - Kanalwahl*/
77
78
79
/* ADC Mehrfachmessung mit Mittelwertbbildung */
80
/* beachte: Wertebereich der Summenvariablen */
81
uint16_t ADC_Read_Avg( uint8_t channel, uint8_t nsamples )
82
{
83
  uint32_t sum = 0;
84
  
85
  for (uint8_t i = 0; i < nsamples; ++i ) {
86
    sum += ADC_Read( channel );
87
  }
88
  
89
  return (uint16_t)( sum / nsamples );
90
}




Testweise rufe ich derzeit so die Funktionen auf:
1
int main(void)
2
{
3
  /* Lokale Variablen */
4
  uint16_t adw_result = 0;
5
  /* Konfiguration des LCD */
6
  lcd_init();
7
  /* ADW initialisieren*/
8
  ADW_int(0, 1);
9
  /* Interrupts global an */
10
  sei();
11
  _delay_ms(1000);
12
    while(1)
13
    {
14
15
        /* Überwacht das Umschalten des Drehschalters */
16
        adw_result =  ADC_Read_Avg(0,5);
17
          
18
          
19
        char itoa_buf_text_1[5];
20
          
21
        lcd_clear();
22
        lcd_setcursor(0,1);
23
        lcd_string("ADW - ");
24
25
          
26
        itoa(adw_result, itoa_buf_text_1,10);
27
        lcd_string(itoa_buf_text_1);
28
          
29
        adw_result = 0;
30
        _delay_ms(100);
31
    }
32
}

Ich kann meinen Fehler einfach nicht finden:(
Lg der 328__Verzweifelte

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

328_Hilfloser schrieb:
> ADCSRA = (1<<ADEN);

Hmm, überleg doch mal, was mit den vorher gesetzten Prescaler Bits 
passiert, wenn diese Zeile abgearbeitet wird.

328_Hilfloser schrieb:
> Auf dem Atmega8 lief der Code noch ohne Probleme.

Sicher? Kann ich fast nicht glauben.

: Bearbeitet durch User
von 328_Hilfloser (Gast)


Lesenswert?

Hmmm da bin ich wohl sogar zu blöd für Copy & Paste...
Das wars danke:)
Auch wenn ich nicht so recht verstehe wie das passiert ist xD

LG

von tigi (Gast)


Lesenswert?

Bin momentan beim gleichen Problem...was hast du jetzt also hier 
verändert damit dein Code funktioniert?

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.