Attiny 13 ADC Problem

Gast #3207398
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
}
#3207403
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.
Gast #3207628
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?

>  }
>}
Gast #3207779
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
Gast #3207832
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
#3207837
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren