Forum: Mikrocontroller und Digitale Elektronik ADC Schwellwert


von Heinz peter P. (poschi8)


Lesenswert?

Hallo, ich hab hier mal ein kleines Programm zur Schwellwertüberwachung:
1
#include <avr/io.h>
2
3
void main(void)
4
{
5
  DDRD=0xFF;            //PORTD als Ausgang definieren
6
  unsigned int wert1;
7
8
9
10
  while(1)
11
  {
12
    ADCSRA = 0b10000100;    //ADC Aktivieren und Teilungsfaktor 16
13
    
14
    ADMUX = 0b11000001;      
15
    ADCSRA |= (1<<ADSC);       //interne referenz und ADC1
16
  while(ADCSRA & (1<<ADSC));     //Warten auf das Ende der Wandlung
17
    {
18
      wert1 = ADCW;      //Ergebnis in die Variable Wert schreiben
19
    }
20
21
      if (wert1 == 0x00)    //wenn Wert gleich 0 ist dann ist PD5 aktiv
22
      {            //sonst ist PD7 aktiv  
23
        PORTD |= (1<<PD5);
24
      }
25
      else
26
      {
27
        PORTD |= (1<<PD7);
28
      }
29
30
31
  }
32
33
}
Das Problem ist das wenn sich die Spannung verändert, dann tut sich an 
der LED gar nichts.
Wenn ich zum Beispiel am Anfang ADC1 auf GND habe ist PD5 aktiv, wenn 
ich dann aber auf z.B. 5V hänge passiert gar nichts, bzw es sind beide 
aktiv.
Was habe ich falsch gemacht?!

Mit freundlichen Grüßen,
Poschi

von Heinz peter P. (poschi8)


Lesenswert?

Hab das Problem schon gelöst.
Ich musste nur den PORTD wieder zurücksetzten, also nach " ADCSRA |= 
(1<<ADSC); "
gehört noch ein " PORTD = 0x00 "

Mit freundlichen Grüßen,
Poschi

von Helfer (Gast)


Lesenswert?

1) Warum benutzt du für erste Experimente nicht den bewährten Code aus 
dem Tutorial

2) Trenne Initialisierung des ADC von der Messroutine

3) "//wenn Wert gleich 0 ist dann ist PD5 aktiv"

Das wurde bereits in einem Thread gestern als schlechte Idee diskutiert.

0 hat dein ADC Wandler in der Praxis u.U. sehr selten. I.d.R. macht es 
mehr Sinn mit Schwellen und Intervalleb zu arbeiten, so wie in dem 
Thread gestern auch beschrieben wurde.
1
#include <avr/io.h>
2
3
void main(void)
4
{
5
  unsigned int wert1;
6
7
  DDRD = 0xFF; //PORTD als Ausgang definieren
8
9
  // ADC Initialisierung
10
  // (Kryptische Bitwerte aus dem Originalcode sind nicht kontrolliert!)
11
  ADCSRA = 0b10000100; // ADC enablen und Teilungsfaktor 16
12
  ADMUX = 0b11000001;  // Interne referenz und ADC1      
13
  ADCSRA |= (1<<ADSC); // 1. Wandlung starten
14
  while( (ADCSRA & (1<<ADSC)) ) {} //Warten auf das Ende der Wandlung
15
  wert1 = ADCW; // 1. Wandlung verwerfen
16
17
  while(1) {
18
    ADCSRA |= (1<<ADSC); // Wandlung starten
19
    while( (ADCSRA & (1<<ADSC)) ) {} // Warten auf das Ende der Wandlung
20
    wert1 = ADCW; // Ergebnis in die Variable Wert schreiben
21
22
    if( wert1 == 0 ) {            
23
      //wenn Wert gleich 0 ist dann ist PD5 aktiv
24
      PORTD |= (1<<PD5);  // PD5 an
25
      PORTD &= ~(1<<PD7); // PD7 aus
26
    } else {
27
      // sonst ist PD7 aktiv  
28
      PORTD &= ~(1<<PD5); // PD5 aus
29
      PORTD |= (1<<PD7);  // PD7 an
30
    }
31
  }
32
}

von Tip (Gast)


Lesenswert?

Heinz peter Posch schrieb:
> Ich musste nur den PORTD wieder zurücksetzten, also nach " ADCSRA |=
> (1<<ADSC); "
> gehört noch ein " PORTD = 0x00 "

Das hilft zwar in deinem Fall, zerstört aber die Stellung sämtlicher 
anderer Portpins.

Besser wäre

      if (wert1 < SCHWELL)    // wenn Wert unterhalb SCHWELLE
      {
        PORTD &= ~(1<<PD7);   // LED am Pin 7 ausschalten
        PORTD |=  (1<<PD5);   // LED am Pin 5 einschalten
      }
      else
      {
        PORTD &= ~(1<<PD5);   // LED am Pin 5 ausschalten
        PORTD |=  (1<<PD7);   // LED am Pin 7 einschalten
      }

von Heinz peter P. (poschi8)


Lesenswert?

Ok!!!
Danke für die Antworten, werd das gleich mal ausprobieren...

Mit freundlichen Grüßen,
Poschi

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.