Programm Problem mit ADC ergebniss Attiny13

#4010756
Lesenswert?

Hallo, ich möchte mir nach und nach ein Programm stricken mit dem ich 
einen Laminator auf ca. 200 Grad einregeln kann.
Ich bin grad am versuchen ein Poti auszulesen und über den ermittelten 
Wert eine Diode in der Blink-geschwindigkeit zu regeln.
Das Problem ist hier das ich als Rückgabewert des ADC kein Zahlenformat 
finde das ich in _delay_ms(xxx) eintragen kann ohne eine Fehlermeldung 
zu kriegen.
kann mir da vielleicht mal jemand einen Tip geben?

hier mal der Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
//#define F_CPU = 1200000UL
4
uint16_t leseKanal(uint8_t mux);
5
uint16_t verz=0;
6
int main (void){
7
  DDRB=0x01;
8
  
9
  
10
  while (1){
11
    PORTB ^= 0x01;
12
    verz =  leseKanal(0x21);
13
    verz =verz*3;
14
    _delay_ms(verz);
15
  } return 0;
16
  
17
}
18

19
//Routine zum einlesen eines Kanales
20
uint16_t leseKanal(uint8_t mux)
21
{
22
  uint8_t i;
23
  uint8_t ergebniss;
24
  uint16_t foo;
25
  ADCSRA |= (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1);
26
    //ADC einschalten, Teiler auf 8
27
  ADMUX =mux;
28
  //lerlauf zum syncronisoeren
29
  ADCSRA |= (1<<ADSC);
30
  while (ADCSRA & (1<<ADSC)){
31
    ;
32
  }
33
  foo = ADCW;
34
    
35
  foo = 0;
36
  //eigentlicher Abfragezyklus
37
  for(i=0;i<4;i++){
38
    
39
    ADCSRA |= (1<<ADSC);
40
    while (ADCSRA & (1<<ADSC)){
41
      ;
42
    }
43
    foo +=ADCW;
44
  }
45
  foo = foo/4;
46
  foo += (foo>>2);
47
  ergebniss = (uint8_t)foo;
48
  return ergebniss;
49
  
50
}
#4010762
Lesenswert?

Fritz Bie schrieb:
> Hallo, ich möchte mir nach und nach ein Programm stricken mit dem ich
> einen Laminator auf ca. 200 Grad einregeln kann.
> Ich bin grad am versuchen ein Poti auszulesen und über den ermittelten
> Wert eine Diode in der Blink-geschwindigkeit zu regeln.
> Das Problem ist hier das ich als Rückgabewert des ADC kein Zahlenformat
> finde das ich in _delay_ms(xxx) eintragen kann ohne eine Fehlermeldung
> zu kriegen.

das Problem ist nicht das Zahlenformat. Das Problem ist, dass du bei 
_delay_ms einen konstanten Wert angeben musst.
Du kannst also schreiben
1
  _delay_ms( 50 );
oder auch
1
  _delay_ms( 200 );
da sowohl 50 als auch 200 konstante Werte seind.
Du kannst aber nicht schreiben
1
  int zeit;
2

3
  ...
4
  _delay_ms( zeit );
weil zeit eine Variable ist und keine Konstante.
Hintergrund: _delay_ms erfordert vom Compiler einiges an Aufwand. Er 
ermittelt aus der Zahl ein Schleifenkonstrukt, dass so oft durchlaufen 
wird, dass die angegebene Zeit ziemlich genau erreicht wird.
Das geht aber nur dann gut, wenn der Compiler die angestrebte Zeit als 
Zahlenwert auch tatsächlich kennt! Denn nur dann kann der Compiler all 
die Zwischenberechnungen rausoptimieren, so dass im Endeffekt nur das 
Schleifenkonstrukt mit genau diesem Zeitverhalten entsteht.

Daher die Einschränkung.

Aber:
Wenn man 50 Zeiteinheiten warten will, dann kann man auch 50 mal 1 
Zeiteinheit warten. Das ist im Endergebnis fast das selbe. Will man x 
Zeiteinheiten warten, dann kann man auch x mal 1 Zeiteinheit warten.

Anstatt einem nicht korrekten
1
  _delay_ms( zeit );
kann man zb ein
1
   for( i = 0; i < zeit; i++ )
2
     _delay_ms( 1 );
machen und ist damit auch (fast) dort, dass man eine vorher nicht näher 
bestimmte Zeit abwarten kann. Die Zeiten werden nicht ganz genau 
stimmen, weil ja das for-Konstrukt auch seine Zeit braucht, aber 
meistens ist das nicht so schlimm. Wir reden da über ein paar 
Zehntel-Prozent, die die Zeit deswegen abweichen wird.
#4011372
Lesenswert?

Das Blinken funktioniert jetz! Aber ich kann den Blinkrütmus im Bereich 
von 0V bis Vcc 4 mal über den Bereich verändern. das heist das der 
Zyklus bei Vcc langsam ist und er sich bis zu einem Spannungsabfall von 
ca 1.2V immer Scneller wird um danach beim weiteren drehen am Poti 
wieder schlagartig langsam und dann beim weiterdrehen wieder schneller 
zu werden. Dieser  Zyklus Wiedrholt sich 4 mal bis ich bei Null V bin.
kann mir mal jemand erklären woran das liegt? hab ich was falsch 
programmiert?
Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
//#define F_CPU = 1200000UL
4
uint16_t leseKanal(uint8_t mux);
5
uint16_t verz=0, i;
6
int main (void){
7
  DDRB=0x01;
8
  
9
  
10
  while (1){
11
    PORTB ^= 0x01;
12
    verz =  leseKanal(0x03);
13
    for ( i=0;i<=verz;i++){
14
      _delay_ms(2);
15
    }
16
  } return 0;
17
  
18
}
19

20
//Routine zum einlesen eines Kanales
21
uint16_t leseKanal(uint8_t mux)
22
{
23
  uint8_t i;
24
  uint8_t ergebniss;
25
  uint16_t foo;
26
  ADCSRA |= (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1);
27
    //ADC einschalten, Teiler auf 8
28
  ADMUX =mux;
29
  //lerlauf zum syncronisoeren
30
  ADCSRA |= (1<<ADSC);
31
  while (ADCSRA & (1<<ADSC)){
32
    ;
33
  }
34
  foo = ADCW;
35
    
36
  foo = 0;
37
  //eigentlicher Abfragezyklus
38
  for(i=0;i<4;i++){
39
    
40
    ADCSRA |= (1<<ADSC);
41
    while (ADCSRA & (1<<ADSC)){
42
      ;
43
    }
44
    foo +=ADCW;
45
  }
46
  ergebniss = foo/4;
47
  ergebniss = (ergebniss>>2);
48
  return ergebniss;
49
  
50
}

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