Forum: Compiler & IDEs atmega8 - ADC - Problem Vref. bei Vref. umschaltung


von Oliver R. (roliver)


Lesenswert?

Hallo ins Forum,

ja ich schon wieder...

Habe da mal ein Problem/Frage?

zu erst mal Infos...

ich nutze eine Routine zum lesen der ADC im ATMEGA8 und zwar folgende:
1
uint16_t readADC(uint8_t channel, uint8_t power) {
2
  uint8_t i;
3
  uint16_t result = 0;
4
  
5
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
6
  ADMUX = channel | (1<<REFS1) | (1<<REFS0);
7
  if (power == 1) // ref 5V?
8
  {
9
     ADMUX &= ~(1<<REFS1);
10
  }
11
  
12
  ADCSRA |= (1<<ADSC);
13
  while(ADCSRA & (1<<ADSC));
14
  
15
  for(i=0; i<3; i++) {
16
    ADCSRA |= (1<<ADSC);
17
    while(ADCSRA & (1<<ADSC));
18
    result += ADCW;
19
  }
20
  
21
  ADCSRA &= ~(1<<ADEN);
22
  
23
  result /= 3;
24
  if (power == 0) // Umrechnung in Grad von LM35 (23.5C -> 235!)
25
  {
26
      result *= 256;
27
      result /= 100;
28
  }
29
  
30
  return result;
31
}
32
33
void main(viod)
34
{
35
36
  // init alles und mehr...
37
38
while (1)
39
{
40
  uint16_t wert;
41
  if (taste)
42
  {
43
     wert = readADC(3, 0);
44
     ausgabe (wert);
45
  }
46
47
  werte = readADC(0, 1);
48
    
49
  if (werte <= 266)
50
  {
51
   PORTB |= (1 << 0);
52
  }
53
  else
54
  {
55
   PORTB &= ~(1 << 0);
56
  }
57
  
58
  if ((werte >= 246) && (werte <= 522))
59
  {
60
   PORTB |= (1 << 1);
61
  }
62
  else
63
  {
64
   PORTB &= ~(1 << 1);
65
  }
66
 ...

es sollte immer Channel 0 mit 5V ref Vergleich und bei Taste Channel 3 
mit 2,56V. Doch leider ist die ref immer 5V und somit die LM35 Cradzahl 
falsch.
1
werte = readADC(0, 0);
2
if (werte <= 266)
3
...
Wenn ich das ändere ist zwar CH3 mit LM35 OK, aber CH0 nicht.

Woran liegt das? Kann die ref intern nicht so schnell umschalten?
Gibt es da eine lösung? (ausser externe beschaltung)

Gruß

Oliver

von Oliver R. (roliver)


Lesenswert?

...


Darf ich in einem Programm nicht dem ADMUX umstellen?

Habe jetzt zwei read2ADC und read5ADC und darin
1
uint16_t read2ADC(uint8_t channel)
2
{
3
ADMUX = channel | (1<<REFS1) | (1<<REFS0); // intern 2,5V
4
..
5
6
uint16_t read5ADC(uint8_t channel)
7
{
8
ADMUX = channel | (1<<REFS0); // VACC

wenn ich einmal die read5ADC aufrufe, geht auch die read2ADC nur noch 
mit VACC

Warum?

von Stefan E. (sternst)


Lesenswert?

Die interne Referenz ist ziemlich hochohmig. Entsprechend lange dauert 
es, bis der Kondensator an AREF umgeladen wurde.

von Oliver R. (roliver)


Lesenswert?

ach, OK das erklärt einiges...

von Oliver R. (roliver)


Lesenswert?

gelöst ;-)
Spannungsteiler am Rest, und alle laufen jetzt mit 2,5V und gut is!

Gruß

Oliver

PS.: Umladung dauert bei ca. 2 min!!

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.