Forum: Compiler & IDEs AD-Wandler und LDR Sensoren


von Adam Bekele (Gast)


Angehängte Dateien:

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);
  }


}

von troll (Gast)


Lesenswert?

1
  
2
  if (ch1<ch0)
3
  {
4
    DDRD |= (1 << PD5);
5
  }
6
  if (ch0 <=ch1)
7
  {
8
    DDRD |= (1 << PD5);
9
  }
Sollte das vielleicht beim unteren Mal PD*6* heissen?

von troll (Gast)


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.)

von troll (Gast)


Lesenswert?

troll schrieb:
>
1
>   if (ch1<ch0)
2
>   {
3
>     DDRD |= (1 << PD5);
4
>   }
5
>   if (ch0 <=ch1)
6
>   {
7
>     DDRD |= (1 << PD5);
8
>   }
9
>
Und weil alle guten Dinge 3 sind: Guck mal in deinem C-Buch nach if 
else.

von troll (Gast)


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
...

von Adam Bekele (Gast)


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 "|" !
>
> ...

von Karl H. (kbuchegg)


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
}

von Rolf M. (rmagnus)


Lesenswert?

Karl Heinz Buchegger schrieb:
> 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!

Es sei denn, man will einen open-drain-Ausgang nachbilden. Dan setzt man 
das PORT-Bit fest auf 0 und schaltet mit DDR um.

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.