www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC und Atmega


Autor: Hunt Worker (hunt_work_er)
Datum:

Bewertung
0 lesenswert
nicht 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...)
#include <avr/io.h>
#include <stdint.h>


int main(void)
{
   
   DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4);
   uint16_t result;

   ADMUX = 0;  //Kanal 0
   ADMUX |= (0<<REFS1) | (0<<REFS1); //externe referenzspannung

   ADCSRA = (1<<ADPS2); //frequenzvorteiler auf 16
   ADCSRA |= (1<<ADEN); //ADC Aktivieren
   ADCSRA |= (1<<ADFR); //ADC in free run


   while(1)
   {      
      result = ADCW;

      If (result < 204)
      {
         PORTB |= (1<<PB0) (0<<PB1) (0<<PB2) (0<<PB3) (0<<PB4);
      }
      else if (result >= 204 && result < 409)
      {
         PORTB |= (1<<PB0) (1<<PB1) (0<<PB2) (0<<PB3) (0<<PB4);
      }
      else if (result >= 409 && result < 614)
      {
         PORTB |= (1<<PB0) (1<<PB1) (1<<PB2) (0<<PB3) (0<<PB4);
      }
      else if (result >= 614 && result < 819,2)
      {
         PORTB |= (1<<PB0) (1<<PB1) (1<<PB2) (1<<PB3) (0<<PB4);
      }
      else
      {
       PORTB |= (1<<PB0) (1<<PB1) (1<<PB2) (1<<PB3) (1<<PB4)
      }

   return 0;
   }
   
}

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:
If (result < 204)
{

Autor: F. Reiling (freiling)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
versuch mal if( kleinzuschreiben
und beim letzten else fehlt ein semikolon am Ende
mfg

Autor: Hunt Worker (hunt_work_er)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>
#include <stdint.h>


int main(void)
{
   
   DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4);
   uint16_t result;

   ADMUX = 0;  //Kanal 0
   ADMUX |= (0<<REFS1) | (0<<REFS1); //externe referenzspannung

   ADCSRA = (1<<ADPS2); //frequenzvorteiler auf 16
   ADCSRA |= (1<<ADEN); //ADC Aktivieren
   ADCSRA |= (1<<ADFR); //ADC in free run

   while(1)
   {      
      result = ADCW;

      if (result < 204)
    {
         PORTB |= (1 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
      }
      else if (result >= 204 && result < 409)
      {
         PORTB |= (1 << PB0) | (1 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
      }
      else if (result >= 409 && result < 614)
      {
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (0 << PB3) | (0 << PB4);
      }
    else if (result >= 614 && result < 819,2)
      {
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (0 << PB4);
      }
    else
    {
       PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4);
    }

   return 0;
   }
   
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier
      if (result < 204)
    {
         PORTB |= (1 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
      }
      else if (result >= 204 && result < 409)
      {
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hier
    else if (result >= 614 && result < 819,2)

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

De facto steht da
    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 :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Das hier
>
>
>     else if (result >= 614 && result < 819,2)
> 
>
> compiliert zwar, macht aber nicht das was du willst :-)
>
> De facto steht da
>
>
>     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 :-)

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

der Komma Operator hat die niedrigste Priorität aller Operatoren

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
   return 0;
   }
}

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.

Autor: Bitte einen Namen eingeben (Gast)
Datum:

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

MfG

Autor: Hunt Worker (hunt_work_er)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
o.k vielen dank schon mal
#include <avr/io.h>
#include <stdint.h>


int main(void)
{
   
   DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4) | (1 << DDB5);
   uint16_t result;

   ADMUX = 0;  //Kanal 0
   ADMUX |= (0<<REFS1) | (0<<REFS1); //externe referenzspannung

   ADCSRA = (1<<ADPS2); //frequenzvorteiler auf 16
   ADCSRA |= (1<<ADEN); //ADC Aktivieren
   ADCSRA |= (1<<ADFR); //ADC in free run

   while(1)
   {      
      result = ADCW;

      if (result < 204)
    {
         PORTB |= (1 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
      }
      else if (result < 409)
      {
         PORTB |= (1 << PB0) | (1 << PB1) | (0 << PB2) | (0 << PB3) | (0 << PB4);
      }
      else if (result < 614)
      {
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (0 << PB3) | (0 << PB4);
      }
    else if (result < 819)
      {
         PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (0 << PB4);
      }
    else
    {
       PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4);
    }

      PORTB |= (1 << PB5);

   }
   
}

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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hunt Worker (hunt_work_er)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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?

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht 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:
uint16_t spannung;
//...
spannung = result * 5000UL /1024;
//                      ^^
//...
itoa(spannung, Buffer, 10);
//                 Das ^^ ist die Basis, _nicht_ die Laenge
hth, Jörg

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.