Forum: Mikrocontroller und Digitale Elektronik ADC und Atmega


von Hunt W. (hunt_work_er)


Lesenswert?

hallo,
es geht um das Auslesen einer Spannung am internen ADC des mega8.
ich möchte den Wert einlesen und abhängig davon 5 LED`s ansteuern (1/5 
von Aref -> eine led an, 2/5 -> twei led´s an...)
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
5
int main(void)
6
{
7
   
8
   DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4);
9
   uint16_t result;
10
11
   ADMUX = 0;  //Kanal 0
12
   ADMUX |= (0<<REFS1) | (0<<REFS1); //externe referenzspannung
13
14
   ADCSRA = (1<<ADPS2); //frequenzvorteiler auf 16
15
   ADCSRA |= (1<<ADEN); //ADC Aktivieren
16
   ADCSRA |= (1<<ADFR); //ADC in free run
17
18
19
   while(1)
20
   {      
21
      result = ADCW;
22
23
      If (result < 204)
24
      {
25
         PORTB |= (1<<PB0) (0<<PB1) (0<<PB2) (0<<PB3) (0<<PB4);
26
      }
27
      else if (result >= 204 && result < 409)
28
      {
29
         PORTB |= (1<<PB0) (1<<PB1) (0<<PB2) (0<<PB3) (0<<PB4);
30
      }
31
      else if (result >= 409 && result < 614)
32
      {
33
         PORTB |= (1<<PB0) (1<<PB1) (1<<PB2) (0<<PB3) (0<<PB4);
34
      }
35
      else if (result >= 614 && result < 819,2)
36
      {
37
         PORTB |= (1<<PB0) (1<<PB1) (1<<PB2) (1<<PB3) (0<<PB4);
38
      }
39
      else
40
      {
41
       PORTB |= (1<<PB0) (1<<PB1) (1<<PB2) (1<<PB3) (1<<PB4)
42
      }
43
44
   return 0;
45
   }
46
   
47
}

es geht darum, dass AVR-Studio bei einem klick auf build folgende fehler 
anzeigt:

c:24: warning: implicit declaration of function 'If'
c:25: error: expected ';' before '{' token

die Fehler beziehen sich auf diese Zeilen:
1
If (result < 204)
2
{

von F. R. (freiling)


Lesenswert?

versuch mal if( kleinzuschreiben
und beim letzten else fehlt ein semikolon am Ende
mfg

von Hunt W. (hunt_work_er)


Lesenswert?

vielen dank ich hätte nie daran gedacht, dass es daran ligen könnte, 
aber jetzt funktioniert es!
außerdem habe ich die | vergessen.
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
5
int main(void)
6
{
7
   
8
   DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4);
9
   uint16_t result;
10
11
   ADMUX = 0;  //Kanal 0
12
   ADMUX |= (0<<REFS1) | (0<<REFS1); //externe referenzspannung
13
14
   ADCSRA = (1<<ADPS2); //frequenzvorteiler auf 16
15
   ADCSRA |= (1<<ADEN); //ADC Aktivieren
16
   ADCSRA |= (1<<ADFR); //ADC in free run
17
18
   while(1)
19
   {      
20
      result = ADCW;
21
22
      if (result < 204)
23
    {
24
         PORTB |= (1 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
25
      }
26
      else if (result >= 204 && result < 409)
27
      {
28
         PORTB |= (1 << PB0) | (1 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
29
      }
30
      else if (result >= 409 && result < 614)
31
      {
32
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (0 << PB3) | (0 << PB4);
33
      }
34
    else if (result >= 614 && result < 819,2)
35
      {
36
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (0 << PB4);
37
      }
38
    else
39
    {
40
       PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4);
41
    }
42
43
   return 0;
44
   }
45
   
46
}

von Karl H. (kbuchegg)


Lesenswert?

Hier
1
      if (result < 204)
2
    {
3
         PORTB |= (1 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
4
      }
5
      else if (result >= 204 && result < 409)
6
      {
brauchst du nicht mehr testen, ob result >= 204 ist. result MUSS >= 204 
sein, ansonsten würde dieses if überhaupt nicht mehr 'befragt' werden, 
weil der erste if schon zugeschlagen hätte. Detto für alle anderen else 
if

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
    else if (result >= 614 && result < 819,2)

compiliert zwar, macht aber nicht das was du willst :-)

De facto steht da
1
    else if (result >= 614 && result < 2)

und das kann per Definition nie true sein. Eine Zahl kann nicht 
gleichzeitig größer 614 und gleichzeitig kleiner 2 sein :-)


In Programmiersprachen gibt es nur ganz selten ein Dezimal-'Komma' und 
wenn, dann sind das verhunzte Programmiersprachen, die auf Teufel komm 
raus ins Deutsche übersetzt wurden.
In Programmiersprachen hat man praktisch immer einen Dezimal-'punkt'.
Allerdings erhebt sich hier die Frage, warum du mit 819.2 vergleichen 
willst :-)

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:
> Das hier
>
>
1
>     else if (result >= 614 && result < 819,2)
2
>
>
> compiliert zwar, macht aber nicht das was du willst :-)
>
> De facto steht da
>
>
1
>     else if (result >= 614 && result < 2)
2
>
>
> und das kann per Definition nie true sein. Eine Zahl kann nicht
> gleichzeitig größer 614 und gleichzeitig kleiner 2 sein :-)

Mein Fehler.
De facto steht da
1
    else if ( 2 )

der Komma Operator hat die niedrigste Priorität aller Operatoren

von Karl H. (kbuchegg)


Lesenswert?

1
   return 0;
2
   }
3
}

was sucht das return innerhalb der while-Schleife?

Wenn du Einrückungen ernst nimmst, dann kann so etwas nicht auftreten! 
Es ist völlig unmöglich, dass eine Anweisung in einem Block an derselben 
Spalte beginnt, wie die }, die den Block schliesst.

von Bitte einen Namen eingeben (Gast)


Lesenswert?

Das
1
return 0;
muss auch aus der while-Schleife raus. Der letzte Teil des Programm 
sollte so aussehen
1
  else
2
  {
3
   PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4);
4
  }
5
 }
6
 return 0;
7
}

MfG

von Hunt W. (hunt_work_er)


Lesenswert?

o.k vielen dank schon mal
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
5
int main(void)
6
{
7
   
8
   DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4) | (1 << DDB5);
9
   uint16_t result;
10
11
   ADMUX = 0;  //Kanal 0
12
   ADMUX |= (0<<REFS1) | (0<<REFS1); //externe referenzspannung
13
14
   ADCSRA = (1<<ADPS2); //frequenzvorteiler auf 16
15
   ADCSRA |= (1<<ADEN); //ADC Aktivieren
16
   ADCSRA |= (1<<ADFR); //ADC in free run
17
18
   while(1)
19
   {      
20
      result = ADCW;
21
22
      if (result < 204)
23
    {
24
         PORTB |= (1 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
25
      }
26
      else if (result < 409)
27
      {
28
         PORTB |= (1 << PB0) | (1 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
29
      }
30
      else if (result < 614)
31
      {
32
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (0 << PB3) | (0 << PB4);
33
      }
34
    else if (result < 819)
35
      {
36
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (0 << PB4);
37
      }
38
    else
39
    {
40
       PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4);
41
    }
42
43
      PORTB |= (1 << PB5);
44
45
   }
46
   
47
}

funktioniert aber trotzdem nicht. ich hab auch noch eingestellt, dass er 
den PIN5 von PORTB aktivieren soll, aber das macht er nicht.
Wo liegt hier noch der Fehler?
Es wird auch ohne Fehler und Warnungen erstellt und gebrannt, aber auf 
dem Board tut sich nichts.

von Karl H. (kbuchegg)


Lesenswert?

Hunt Worker schrieb:

> Wo liegt hier noch der Fehler?

Tu dir selbst einen Gefallen und benutze zunächst die ADC Routine aus 
dem Tutorial. Die geht immer noch schnell genug, dass du Schwierigkeiten 
haben wirst, den LED zu folgen.

> Es wird auch ohne Fehler und Warnungen erstellt und gebrannt,

Das heist nicht viel.

"Das Segelboot durchflog die Gabel." ist ein deutscher Satz, der alle 
Regeln der deutschen Sprache einhält. Kein Duden-Mitarbeiter könnte 
irgendetwas dagegen einwenden.
Trotzdem ist er sinnlos.

von Hunt W. (hunt_work_er)


Angehängte Dateien:

Lesenswert?

so,
ich habe jetzt auch noch ein Display angeschlossen, um den Wert 
angezeigt zu bekommen.

nachdem ich den Artike über Festkommaarithmetik gelesen und 
angewendet habe bekomme ich das angezeigt:
<Spannung: > komisches Zeichen < V>
Das komische Zeichen siet so aus:
# # #   #
# # # # #
#   # # #
# # #
# # #   #
# # # # #
#   # #
#   # # #

kann mir jemand weiter helfen?

von Jörg G. (joergderxte)


Lesenswert?

Das
> uint32_t spannung
plus das
> itoa(spannung, Buffer, 20);
Funktioniert nicht, ("int to ascii", nicht uint32_t) und der dritte 
parameter ist auch verkehrt.

So waere es etwas besser:
1
uint16_t spannung;
2
//...
3
spannung = result * 5000UL /1024;
4
//                      ^^
5
//...
6
itoa(spannung, Buffer, 10);
7
//                 Das ^^ ist die Basis, _nicht_ die Laenge
hth, Jörg

ps.: dein C-Buch weiß das auch alles

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.