AD-Wandler und LDR Sensoren

Gast #3184358
Lesenswert?

Guten Tag alle zusammen,
Ich hab im 5. Prüfungselement des Abiturs die Aufgabe einen Suntracker 
zu bauen mit hilfe von LDRs und einem microcontrollers.
Dazu gehört natürlich auch das einlesen und verarbeiten von analogen 
werten.
Ich hab mich durch dutzende Tutorials geschlagen. Trotzdem weiß ich 
leider nicht wieso mein Programm nicht funktioniert. An PD5 und PD6 sind 
LEDs angeschlossen.

Ich hoffe jemand kann mir vielleicht auf die Sprünge helfen.

Mit freundlichen Grüßen

Adam

#include <avr/io.h>




int main (void)
{
  DDRD=0xFF;
  ADMUX= (1 << REFS1) | (1 << ADLAR);
  ADCSRA= (1 << ADEN)| (1 << ADSC)| (1 << ADIE)| (1 << ADPS2)
        | (1 << ADPS1)| (1 << ADPS0) ;


  while(!(ADCSRA & (1 << ADIF))) {}
  int ch0=ADCH;
  ADCSRA = (1 << ADIF);


  ADMUX= (1 << REFS1) | (1 << ADLAR)|(1 <<MUX0);
  ADCSRA= (1 << ADEN)| (1 << ADSC)| (1 << ADPS2) | (1 << ADPS1)|
        (1 << ADPS0) ;

  while(!(ADCSRA & (1 << ADIF))) {}
  int ch1=ADCH;
  ADCSRA = (1 << ADIF);

  if (ch1<ch0)
  {
    DDRD |= (1 << PD5);
  }
  if (ch0 <=ch1)
  {
    DDRD |= (1 << PD5);
  }


}
Angehängte Dateien:
Gast #3184403
Lesenswert?

Nebenbei bemerkt ohne ins Datenblatt geschaut zu haben:
> (1 << ADEN)| (1 << ADSC)| (1 << ADIE)| (1 << ADPS2)
ADEN dürfte das Enableflag vom ADC sein, das setzt man normalerweise nur 
ein mal bei der Initialisierung. Und IE ist normalerweise ein Interrupt 
Enable, warum setzt du das wenn du keine Interrupts nutzt? (Es würde so 
eh nicht funktionieren weil man noch im SREG was setzen muss, aber wenn 
du das auch noch machst gibt es einen Reset bei jedem Interrupt weil die 
passende ISR fehlt.)
Gast #3184409
Lesenswert?

troll schrieb:
> Nebenbei bemerkt ohne ins Datenblatt geschaut zu haben:
>> (1 << ADEN)| (1 << ADSC)| (1 << ADIE)| (1 << ADPS2)
> ADEN dürfte das Enableflag vom ADC sein, das setzt man normalerweise nur
> ein mal bei der Initialisierung.
Argh, VORSICHT: Du benutzt kein logisches Oder sondern schreibst das 
komplette Register neu, da muss natürlich jedes gesetzte Bit vorkommen 
(also auch ADEN).

Ich würde es eher so machen
1
Init:
2
ADCSRA=(1<<ADEN)|(1<<ADPS2);
3

4
Start:
5
ADCSRA|=(1<<ADSC); <--man beachte das "|" !
6

7
...
Gast #3184790
Lesenswert?

Vielen Dank
für die schnelle antwort.
das mit dem PD5 war ein tippfehler da hast du recht das ist PD6. Auch 
das mit else if habe ich verbessert. Leider komm ich mit der dritten 
aussage nicht ganz zu recht. Meinst du damit das ich den ADC zuerst 
initialisiern und soll und danach die einzelnen umwandlungs Prozesse 
starten soll?

troll schrieb:
> Ich würde es eher so machenInit:
> ADCSRA=(1<<ADEN)|(1<<ADPS2);
>
> Start:
> ADCSRA|=(1<<ADSC); <--man beachte das "|" !
>
> ...
#3184984
Lesenswert?

Ausgabeportbits werden auf 0 oder 1 geschaltet, indem man das PORT 
Register beschreibt und nicht das DDR Register. DDR ist dafür zuständig 
die Richtung (Eingang/Ausgang) festzulegen!

Für ADC-Routinen sieh dir bitte das AVR-GCC-Tutorial an. Da gibt es 
mehr oder weniger fertige. Einzig die Referenzspannung musst du noch 
auswählen, so wie du sie brauchst.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe#Nutzung_des_ADC

1
....
2

3
int main()
4
{
5
  int Channel0, Channel1;
6

7
  DDRD |= (1<<PD5) | (1<<PD6);
8

9
  ADC_Init();
10

11
  while( 1 )
12
  {
13
    Channel0 = ADC_read( 0 );
14
    Channel1 = ADC_read( 1 );
15

16
    if( Channel0 < Channel1 )
17
    {
18
      PORTB |=  (1<<PD5);
19
      PORTB &= ~(1<<PD6);
20
    }
21
    else
22
    {
23
      PORTB &= ~(1<<PD5);
24
      PORTB |=  (1<<PD6);
25
    }
26
  }
27
}

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