Forum: Mikrocontroller und Digitale Elektronik Attiny 13 ADC Problem


von Murock (Gast)


Lesenswert?

Hallo hänge seit Tagen an diesem Problem,
und irgendwie sehen ich nicht wo der Fehler ist.
Das Programm soll regelmäßig den Spannungswert eines Potis abfragen.
Wenn der Spannungswert größer als 1V ist, soll der Ausgang an PINB4 
gesetzt werden.

Ich weiß nicht mehr weiter bitte helft mir.
1
void ADC_Init(void)
2
 {
3
uint16_t result ;
4
ADMUX   |=  (0<<REFS0) | (1<<ADLAR) ;         
5
ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0) ;      
6
ADCSRA |= (1<<ADEN) | (0<<ADATE) ;             
7
ADCSRA |= (1<<ADSC);             
8
  
9
  while (ADCSRA & (1<<ADSC) ) 
10
  {                  
11
  }
12
  result = ADCW ;   
13
}
14
15
uint16_t ADC_Read( uint8_t channel )
16
{
17
ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); 
18
ADCSRA |= (1<<ADSC);
19
while (ADCSRA&(1<<ADSC))             {                
20
  }
21
return ADCW;                   
22
23
24
int main()
25
{
26
  DDRB = (1<<PINB4);
27
  PORTB &= ~(0<<PINB4);
28
  
29
  uint16_t adcval;
30
  ADC_Init();
31
 
32
  while( 1 )
33
   {
34
adcval = ADC_Read(1);              
35
if(adcval >= 0x00C8 )
36
  {
37
    PORTB |= (1<<PINB4)   ;
38
  }
39
  else 
40
          PORTB &= ~(1<<PINB4)   ;
41
    
42
      
43
  _delay_ms(1000)         ;
44
  
45
  }
46
47
}

von 4to Takoe (Gast)


Lesenswert?

Deine Klammersetzung ist falsch.

von Karl H. (kbuchegg)


Lesenswert?

>
1
> uint16_t ADC_Read( uint8_t channel )
2
>{
3
>ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); 
4
>ADCSRA |= (1<<ADSC);
5
>while (ADCSRA&(1<<ADSC))             {                
6
>  }
7
>return ADCW;                   
8
>
9
>
10
>int main()
11
>{
12
>

da fehlt doch eine schliessende }-Klammer.

Rück doch deinen Code mal ordentlich ein, damit man da nicht 
Schnitzeljagd nach Fehlern machen muss, die eigentlich nur zeigen, dass 
dieser Code auf keinen Fall fehlerfrei durch den Compiler gegangen sein 
kann.

von Karl H. (kbuchegg)


Lesenswert?

>   .....  (1<<ADLAR) ;


ADLAR?

So wie du das Ergebnis vom ADC benutzt, ist ADLAR hier eher 
kontraproduktiv.

von Rosa-Kleidchen (Gast)


Lesenswert?

>   ADMUX   |=  (0<<REFS0) | (1<<ADLAR) ;
    ADMUX   |=  (0<<REFS0) | (1<<REFS1) ; ??

>   ADCSRA |= (1<<ADEN) | (0<<ADATE) ;
    ADCSRA |= (1<<ADEN); ??

>   ADCSRA |= (1<<ADSC);
    ????
>uint16_t ADC_Read( uint8_t channel )
>{
>  ...
>  return ADCW;
}
>
>int main()
>{
>  while( 1 )
>  {
>    adcval = ADC_Read(1);
     ADC port 1 angeschlossen?

>  }
>}

von Steve (Gast)


Lesenswert?

Hallo Murock,

Atmel schlägt im Datenblatt vor erstmal deinen ADC kompett zu 
konfigurieren (alle Register einstellen) bevor man den ADC freigibt 
(1<<ADEN). Bei aktivem ADEN können manche Register gesperrt sein und 
deine Änderungen nicht übernhemen.

Somit würd ich bei der initialiserung des ADC als letzter Schritt 
(1<<ADEN) anwenden.

Lies mal das Datenblatt.
Zitat: "Voltage reference and input channel selections will not go into 
effect until ADEN is set."

Sind aber glaube ich noch andere Register betroffen...

Grüße Steve

von Steve (Gast)


Lesenswert?

Nachtrag:

Da du ADLAR auf 1 hast wird dein Wert ja linksbündig abgelegt.

Du musst ADCH abfragen und nicht ADCW (?).

Der ADC hat ein oberes und unteres Byte. (ADCH und ADCL)

Nach abfragen des ADCH wird der ADC wieder freigegeben.
Willst du auch ADCL wissen dann musst du den Wert vor ADCH abholen.


Als kleiner Tipp.


Grüße Steve

von Karl H. (kbuchegg)


Lesenswert?

Einfacher ist es allerdings ADLAR ganz einfach nicht zu benutzen, den 
Rest so zu lassen und damit zu leben, dass der ADC Werte zwischen 0 und 
1023 liefern wird. Muss man halt die Grenze neu berechnen, an der die 
bewussten 1V liegen. Aber bitte nicht wieder als Hex-Zahl im Programm 
angeben. Wenn der errechnete Wert 200 ist, dann darf man ruhig auch

  if( Wert > 200 )

schreiben. Man muss nicht

  if( Wert > 0x00C8 )

schreiben. Keiner ist verpflichtet, den maximal unleserlichsten Codestil 
zu benutzen. Auch wenn das in C möglich ist und diverse C Opponenten 
immer so tun, als ob das so sein muss.

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.