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
:)))
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
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_tReadADC(uint8_tch){
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
returnADC;
9
}
> return ADC;> }>> Ich weiss, "6" ist ein bisschen unschön, in der entgültigen Version> werde ich die Kosmetik auch erledigen. :)))
Machs gleich.
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
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?
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
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