www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega32 + Fotowiderstand


Autor: Karoly Kovacs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe ein Problemchen.

LDR hängt an ADC0 (PA0). Besser gesagt, LDR ist zwischen VCC und ADC0, 
und von ADC0 geht ein 100kOhm an GND.

(Und AVCC = VCC.)

Gemessen wird (an ADC0 Pin) bei Licht ca. 200-600mV, und in Dunkel fast 
VCC, also ich kann sagen, LDR u. Spannungsteiler sind in Ordnung.

Egal, was ich mache, das Programm zählt immer bis 1023!

Das Programmteil:

uint16_t ReadADC(uint8_t ch) {
   ADMUX  = (1<<REFS0) | ch;     // AVCC = ref.
   ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIF) | 6;
   while ((ADCSRA & (1<<ADIF))==0);
   return ADC;
}

Ich weiss, "6" ist ein bisschen unschön, in der entgültigen Version 
werde ich die Kosmetik auch erledigen. :)))

Also "6" heisst: Divider ist 64. Mein AVR läuft mit 11,0592 MHz, es gibt 
dann ca. 173kHz (vorgeschrieben ist zwischen 50 u. 200kHz)

Was mache ich falsch? Habe ich was vergessen/versehen?

Danke für Euere Hilfe,
Karoly

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karoly Kovacs schrieb:
> Egal, was ich mache, das Programm zählt immer bis 1023!
>
> Das Programmteil:

da zählt gar nichts...

Autor: Karoly Kovacs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:)))

OK, wie Du wahrscheinlich siehst, ich bin Ausländer.

Also, ich habe es falsch formuliert, das Programm zählt natürlich 
nichts, sondern der ADC.

Karoly

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

Bewertung
0 lesenswert
nicht lesenswert
Karoly Kovacs schrieb:

> uint16_t ReadADC(uint8_t ch) {
>    ADMUX  = (1<<REFS0) | ch;     // AVCC = ref.
>    ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIF) | 6;
>    while ((ADCSRA & (1<<ADIF))==0);

Was habt ihr nur immer mit dem Interrupt Flag?
Lass das Teil doch in Ruhe.

Du setzt ADSC auf 1 damit der ADC loslegt und wenn er fertig ist, setzt 
er ADSC wieder zurück auf 0.
uint16_t ReadADC(uint8_t ch) {
   ADMUX  = (1<<REFS0) | ch;     // AVCC = ref.
   ADCSRA = (1<<ADEN) | 6;

   ADCSRA |= (1<<ADSC);        // und los gehts
   while (ADCSRA & (1<<ADSC))  // und warten ...
     ;
   return ADC;
}

>    return ADC;
> }
>
> Ich weiss, "6" ist ein bisschen unschön, in der entgültigen Version
> werde ich die Kosmetik auch erledigen. :)))

Machs gleich.

Autor: Karoly Kovacs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, Karl Heinz, hier steht es auch so:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC

Es geht aber doch nicht. :(

So habe ich es dann gemacht (mit der Kosmetik inbegriffen):

uint16_t ReadADC(uint8_t ch) {
   ADMUX  = (1<<REFS0) | ch;     // AVCC = ref.
   ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1);

   ADCSRA |= (1<<ADSC);        // und los gehts
   while (ADCSRA & (1<<ADSC))  // und warten ...
   ;
   return ADC;
}

Karoly

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

Bewertung
0 lesenswert
nicht lesenswert
Karoly Kovacs schrieb:

> Es geht aber doch nicht. :(
>
> So habe ich es dann gemacht (mit der Kosmetik inbegriffen):

OK. Da es dann keinen offensichtlichen Fehler mehr gibt (du könntest 
natürlich ganz einfach auch die ADC routine aus dem Tutorial einfach mal 
1:1 übernehmen 
http://www.mikrocontroller.net/articles/AVR-GCC-Tu... 
), widmen wir uns der Fage:

woher weißt du, dass da immer 1023 raus kommt. Sprich: Was machst du mit 
dem Wert?

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

PullUp an PA0 versehentlich eingeschaltet?

Gruß aus Berlin
Michael

Autor: Karoly Kovacs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So was habe ich gemacht:

int main(void) {
...
uint16_t licht;
...

  licht = ReadADC(0);
  sprintf(wstr,"Lichtwert: %d\n", licht);
  Trace(wstr);

...

Ergebnis (es ist eine Heizungssteuerung per SMS):
...
SendAT: AT+CMGR=15
SendAT: AT+CMGR=6
Lastsms: ON
Licht: 1023
...

Trace ist bei mir ein Prozedur, der die Daten einfach an eine 
Bitbang-UART-Schnittstelle sendet. (Der andere UART ist besetzt.)

Übrigens: Atmega ist in Ordnung, mein Programm läuft tadellos, ich 
wollte es bloss mit diesem Licht-Geschichte erweitern.

Danke,
Karoly

Autor: Karoly Kovacs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michael,

Gute Idee, ich werde es überprüfen!

Danke,
Karoly

Autor: Karoly Kovacs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, Michael, es ist leider, nach wie vor, falsch.

Danke aber,
Karoly

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

Bewertung
0 lesenswert
nicht lesenswert
Probier mal
   return ADCW;

(Auf manchen Prozessoren gibt es irgendwo ein Bit mit dem Namen ADC in 
irgendeinem der Register)

Autor: Karoly Kovacs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Juhhheee! Problem gelöst!

Es war es blöder Kontaktfehler zwischen AREF (Pin32) u. GND (Pin31).
(Es winziger Stück Lötzinn - wie so oft...)

Grrrrr!

Danke aber für Euere Hilfe!

Karoly

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.