mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STK 500 Atmega88 ADC WAndler


Autor: Aron (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jungs
ertsmal möchte ich euch alle schöne Weinachtstage wünschen.
zu meinem Problem, Ich habe ein STK500 mit einem Atmega88, nun möchte 
ich mich mit den Analogen digitalen Wandler vertraut machen.Dazu habe 
ich am Eingang  am Pin C0/ADC0 eine 0,4 V soannung angeschlossen, nun 
möchte ich gerne testen ob diese Spannung gewandlet wurde dazu habe ich 
das folgende Code geschrieben. Ich möchte einfach, dass die LEDS 0 bis 5 
eingeschaltet werden falls die Spannung kleiner 1 V ist.Bei meinem Test 
bleiben die LEDs  leider immer an erst wenn ich die Bedinung von 1  auf 
1000 dann gehen Sie ert aus.
vielleicht kann mir jemand sagen was ich hier falsch mache , oder ein 
typ geben wie ich das am besten testen kann
besten Dank im voraus

#include <avr/io.h>

/* ADC initialisieren */
void ADC_Init(void) {

  uint16_t result;

  ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung 
nutzen // 1,1 V
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren

  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man 
liest
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu 
lassen" */

  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
  while (ADCSRA & (1<<ADSC) );          // auf Abschluss der 
Konvertierung warten
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
     Wandlung nicht übernommen. */
  result = ADCW;
}

/* ADC Einzelmessung */
uint16_t ADC_Read( uint8_t channel )
{
  // Kanal waehlen, ohne andere Bits zu beeinflußen
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
  while (ADCSRA & (1<<ADSC) )     // auf Abschluss der Konvertierung 
warten
    ;
  return ADCW;                    // ADC auslesen und zurückgeben
}


/* Beispielaufrufe: */



int main (void)
{
  uint16_t adcval;
  uint16_t voltage;
  ADC_Init();
 while(1)
 {
  adcval = ADC_Read(0);  // Kanal 0

  //Hier möchte ich den umwandlenden Wert in Spannung Umrechnen

  voltage = adcval*4.883;


  if (voltage <1  )
  {
  DDRB |= 0xFF;
    PORTB |= (1<<PORTB6) | (1<<PORTB7);

  }

 }


}

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Wie kommst du auf die magische Zahl (4.883)? Im Tutorial zu ADC steht 
eine andere Formel mit Referenzspannung und Auflösung des ADC in Bits.

2. Wenn du mit Ganzzahlen statt mit Fliesskomma rechnest, wird dein 
Programm kürzer. Es bietet sich an, in mV statt in V zu rechnen:

  DDRB |= ...; // Ausgänge LED 0-5
  while(1)
  {
    uint16_t millivoltage;
    adcval = ADC_Read(0);  // Kanal 0, interne Referenzspannung 1,1 V
    millivoltage = (adcval * 1100UL) / 1024UL;
    if ( millivoltage < 1000 )
      PORTB |= ...; // LED 0-5 Status hüh
    else
      PORTB &= ~(...); // LED 0-5 Status hott
  }

NB:
C-Code kann man hier im Forum formatieren. Das erhöht IMHO die 
Lesbarkeit.

Autor: AVR-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab ich es überlesen, oder wurde der PinC0 nicht als
Analog-In definiert?

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Hab ich es überlesen, oder wurde der PinC0 nicht als
>Analog-In definiert?

Wozu?

MfG Spess

Autor: Aron (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Danke erstmal für die schnelle Antwort, ich habe es hingekriegt, jetzt 
funktioniert, es war ein variablen Fehler Der Variable voltage war als 
unit16_t deklariert, jetzt habe ich als double deklariert und siehe 
passt.

aber es hat sich einnen andern Problem herrausentwickelt. wenn ich den 
STK500 einschalte un die analoge gemessene Spannung ist unter der "if" 
wert,dann bleiben alle LEDs aus, soweit sogut, erhöhe ich dis Spannung 
über den Schwellwert dann gehen die LED 0 bis 5 an, nun sinke ich die 
Spannung wider unter den Schwellwert bleiben Sie trotzdem an!!!

wo liegt den das Problem, ich hoffe ich langweile euch nicht mit meinen 
Anfängerfragen

int main (void)
{
  uint16_t adcval;
  double   voltage;
  double led; // Variable zum vormerken des Zustand der LED
  ADC_Init();

 led=0;
 while(1)
 {
  adcval = ADC_Read(0);  // Kanal 0

  //Hier möchte ich den umwandlenden Wert in Spannung Umrechnen

  voltage = adcval* 1.1 / 1024.0;


  if (voltage >0.29  )
  {
  DDRB |= 0xFF;

      PORTB |= (1<<PORTB6) | (1<<PORTB7);
  led=1;


  }
  else
      {
    if (led==1 )

      PORTB &= ~( (1<<PB6) | (1<<PB7) );
    led=0;
       }

 }


}

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define LEDS_0_5 ((1<<PB5)|(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0))
  DDRB |= LEDS_0_5;

... 

  if ( voltage > 0.29 )
  {
    PORTB &= ~LEDS_0_5; // active low: LEDs AN
    led = 1;
  }
  else
  {
    if ( led == 1 )
      PORTB |= LEDS_0_5; // active low: LEDs AUS
    led = 0;
  }

Autor: Aron (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Stefan
Habe mein Code umgeschrieben, nach deinem Vorschlag, leider sind die 
LEDs jetzt immer an. Die gehen gar nicht aus.

ich komm leider nicht weiter, ich schmeiss mich gleich vom fahrenden 
Zug:-)

int main (void)
{



 while(1)
 {
   #define LEDS_0_5 
((1<<PB5)|(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0))

   uint16_t adcval;
   double   voltage;
   double led;
   ADC_Init();
   led=0;


   DDRB |= LEDS_0_5;

   adcval = ADC_Read(0);  // Kanal 0

  //Hier möchte ich den umwandlenden Wert in Spannung Umrechnen

   voltage = adcval* 1.1 / 1024.0;

   if ( voltage > 0.29 )
   {
    PORTB &= ~LEDS_0_5; // active low: LEDs AN
    led = 1;
   }
   else
   {
    if ( led == 1 )
      PORTB |= LEDS_0_5; // active low: LEDs AUS
    led = 0;
   }
 }

}

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst halt besser aufpassen, wo du Definitionen und Initialisierungen 
machst. Der AVR ist stur. Der macht was du programmierst, selbst wenn 
das Quatsch ist.

#define LEDS_0_5 ((1<<PB5)|(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0))

int main (void)
{
  uint8_t led = 0;

  DDRB |= LEDS_0_5;

  while(1)
  {
    uint16_t adcval;
    double voltage;

    ADC_Init();
    adcval = ADC_Read(0);  // Kanal 0

    voltage = adcval * 1.1 / 1024.0;

    if ( voltage > 0.29 )
    {
      PORTB &= ~LEDS_0_5; // active low: LEDs AN
      led = 1;
    }
    else
    {
      if ( led == 1 )
        PORTB |= LEDS_0_5; // active low: LEDs AUS
      led = 0;
    }
  }
}

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Habe mein Code umgeschrieben, nach deinem Vorschlag, leider sind die
>LEDs jetzt immer an. Die gehen gar nicht aus.

Du setzt mit 'led=0;' in der Mainloop dein Flag nach jeder Messung auf 
Null.

Nimm den Code um ADC-Init aus der Schleife heraus. Das macht man nur ein 
mal.

MfG Spess

Autor: Aron (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Stefan

bestrn  Dank Stefan  es hat funktioniert, nun bin ich ein stückschen 
weiter mit meinem Grundlagen. Meine Letzte Frage, zumindst für Heute:-)

wenn das eingestellte anlog-wert unter dem Schwellwert ist dann sind die 
LEDs aus, so soll es auch sein,nun schalte ich das STK aus und wider ein 
ohne die analogequelle abzuschalten ,gehen die LEds an obwohl der Wert 
unter den Schwellwert liegt. hast du vielleicht Ahnung was das sein 
kann!!!!

Danke nochmal für euer Mühe

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die LED auf dem STK500 sind active low geschaltet, d.h. wenn der 
PORT-Pin LOW hat, ist die LED an. Der Portpin ist LOW nach der 
Einstellung der Datenrichtung auf Ausgang in dieser Zeile: DDRB |= 
LEDS_0_5;

Wenn du vor dem Einstellen der Datenrichtung die Portpins HIGH setzt, 
sind die LEDs zu Anfang aus:

Statt

  DDRB |= LEDS_0_5;

dann

  PORTB |= LEDS_0_5; // Pullups ein
  DDRB |= LEDS_0_5;  // Datenrichtung Ausgang => active low LEDs AUS

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.