Forum: Mikrocontroller und Digitale Elektronik Atmega32 + Fotowiderstand


von Karoly Kovacs (Gast)


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

von Justus S. (jussa)


Lesenswert?

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

da zählt gar nichts...

von Karoly Kovacs (Gast)


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

von Karl H. (kbuchegg)


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.
1
uint16_t ReadADC(uint8_t ch) {
2
   ADMUX  = (1<<REFS0) | ch;     // AVCC = ref.
3
   ADCSRA = (1<<ADEN) | 6;
4
5
   ADCSRA |= (1<<ADSC);        // und los gehts
6
   while (ADCSRA & (1<<ADSC))  // und warten ...
7
     ;
8
   return ADC;
9
}

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

Machs gleich.

von Karoly Kovacs (Gast)


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

von Karl H. (kbuchegg)


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-Tutorial#Der_interne_ADC_im_AVR 
), widmen wir uns der Fage:

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

von Michael U. (amiga)


Lesenswert?

Hallo,

PullUp an PA0 versehentlich eingeschaltet?

Gruß aus Berlin
Michael

von Karoly Kovacs (Gast)


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

von Karoly Kovacs (Gast)


Lesenswert?

Hallo Michael,

Gute Idee, ich werde es überprüfen!

Danke,
Karoly

von Karoly Kovacs (Gast)


Lesenswert?

Nein, Michael, es ist leider, nach wie vor, falsch.

Danke aber,
Karoly

von Karl H. (kbuchegg)


Lesenswert?

Probier mal
1
   return ADCW;

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

von Karoly Kovacs (Gast)


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

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.