Atmega32 + Fotowiderstand

Gast #1641296
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
#1641323
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.
Gast #1641348
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
#1641362
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?
Gast #1641382
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

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