Forum: Mikrocontroller und Digitale Elektronik Frage ADC Atmega16


von Micha (Gast)


Lesenswert?

Servus AVR-Gemeinde,

hab da mal ne Frage um ADC des Atmega 16.
Habe vor längerer Zeit mal ein Steuergerät für ne Standheizung mit 
Überwachung der Bordspannung programmiert.
Jetzt hab ich mir den Code wiedermal angeschaut und dabei festgestellt, 
das ich den ADC-Wert seltsam berechne.
Erstmal den Code:

Hier wird der ADC gestartet usw. und ausgelesen.
Der Code entspricht ja ungefähr dem, aus dem Tutorial.
1
uint16_t adc_Read_Channel(char mux)
2
{
3
  uint8_t i;
4
  uint16_t result = 0;
5
6
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);
7
8
  ADMUX = mux;
9
10
  ADMUX |=  (1<<REFS0);
11
12
  ADCSRA |= (1<<ADSC);
13
14
  while ( ADCSRA & (1<<ADSC) );
15
16
  for(i=4;i<4;i++);
17
  {
18
    ADCSRA |= (1<<ADSC);
19
    while ( ADCSRA & (1<<ADSC) );
20
21
    result += ADCW;
22
  }
23
24
  ADCSRA &= ~(1<<ADEN);
25
26
  result /= 4;
27
28
  return result;
29
}

Hiermit berechne ich dann den Spannungswert aus dem ADC-Wert:
1
uint16_t adc_Get_Voltage(void)
2
{
3
  uint16_t adc;
4
  uint16_t voltage_1;
5
  uint16_t bat_voltage;
6
  uint16_t reference_voltage;
7
  uint16_t a;
8
  uint8_t R1;
9
  uint8_t R2;
10
11
  #define Vref_halbe  250;              //berechnung mit halber Vref, da sonst werteüberlauf in Variable
12
13
  R1 = 51;
14
  R2 = 11;
15
16
  reference_voltage = Vref_halbe;
17
18
  adc = adc_Read_Channel(0);
19
20
  a = ( (reference_voltage * adc) / 256);
21
  
22
  voltage_1 = a * 2;                  //adc-wert umrechnen
23
24
  bat_voltage = ( voltage_1*(R1+R2) / R2);      //spannungsteiler berechnen
25
26
  return bat_voltage;
27
28
}

Nun ist mir aufgefallen, dass ich eigentlich durch 1024 und nicht durch 
256 teile müsste. Das würde ja aber meine gemessene Spannung vierteln, 
und die stimmt ja aber!
Hab auch mal bissl rumgerechnet und dabei festgestellt, dass im 
ADC-Register auch nur ein Viertel von dem steht, was eigentlich drin 
stehen müsste!
Ich weiß aber auch nicht mehr, wie ich damals auf die 256 gekommen bin!

Hat jemand vielleicht ne Idee, was ich da getrieben hab? Oder besser 
gesagt, warum in meinem ADC-Register genau ein Viertel von dem steht, 
was drin stehen müsste?
Ich komm einfach nicht drauf!

Viele Grüße
Micha

von ... .. (docean) Benutzerseite


Lesenswert?

gefunden:
1
 for(i=4;i<4;i++);
2
  {
3
    ADCSRA |= (1<<ADSC);
4
    while ( ADCSRA & (1<<ADSC) );
5
6
    result += ADCW;
7
  }
8
9
  ADCSRA &= ~(1<<ADEN);
10
11
  result /= 4;

die for schleife läuft nur einmal...

von micha (Gast)


Lesenswert?

Ich falle auf die Knie!!!!
Na so blöde muss man erstmal sein!
Wer richtig abschreiben kann ist klar im Vorteil!

DANKE DANKE DANKE

von Johannes M. (johnny-m)


Lesenswert?

Hmmm, die for-Schleife dürfte eigentlich gar nicht durchlaufen werden. 
Schließlich ist die Bedingung "i < 4" schon bei der Initialisierung 
nicht erfüllt (i = 4)!

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.