Hallo, ich versuche gerade mittels ADC über PWM eine LED zu dimmen, das
heißt die Helligkeit der LED hängt von der Helligkeit des Umgebungslicht
ab.
Aber irgendwie wie will der ADC nicht so wie ich will. Der PWM
funktioniert, den habe ich schon so getestet, aber der ADC will
anscheinden nicht so.
AREF habe ich mit 100nF nach GND gelegt. Alles dürfte richtig beschaltet
sein. Ich habe auch schon versucht die interne Spannung zu benutzen, hat
aber auch nicht geklappt.
Hier mein Code
ADCW wird erstmal durch 5 geteilt, damit er klein genug ist, um ihn in
OCR1A zu schreiben. Meine Frequenz beträgt 14745600Hz, wenn ich sie
durch 200000Hz teile kommt ~73 raus, wenn ich sie durch 50000 teile,
kommt ~294 raus, da heißt ich kann nur einen Prescaler von 128 benutzen,
oder ?
Hi
>ADCW wird erstmal durch 5 geteilt, damit er klein genug ist, um ihn in>OCR1A zu schreiben.
Wieso durch 5? Du hast eine 8 Bit PWM. Damit der ADC-Wert reinpasst must
du durch 4 teilen. Besser noch ADLAR setzen. Dann kannst du ADCH direkt
in OCR1AL laden.
> Meine Frequenz beträgt 14745600Hz, wenn ich sie>durch 200000Hz teile kommt ~73 raus, wenn ich sie durch 50000 teile,>kommt ~294 raus, da heißt ich kann nur einen Prescaler von 128 benutzen,>oder ?
Du kannst jeden Prescaler benutzen. Mit Vorteile 128 bekommst du bei
8-Bit-PWM ein PWM-Frequenz von 450Hz.
MfG Spess
Da liesst du ADCW natürlich aus, ohne zu prüfen, ob er fertig ist mit
der Wandlung.
pwm_calc_value = adc_value / 5;
Warum /5? Solche krummen Zahlen sind immer schlecht.
Fast-PWM 10 bit ist dein Freund. Da kannst du deinen ADC-Wert direkt
reinschreiben.
Dann setzt du noch ADATE, stellst den Trigger auf Timer1-Overflow, liest
in der Timer-Isr den ADC-Wert und schreibst ihn ins OCR-Register.
Fertig. Ein bisschen konfigurieren, eine Zeile Code(OCR1A = ADCW;).
Den Rest macht der Controller alleine und dein Programm kann Primzahlen
berechnen.
mfg.
Thomas Eckmann schrieb:> Fast-PWM 10 bit ist dein Freund. Da kannst du deinen ADC-Wert direkt> reinschreiben.> Dann setzt du noch ADATE, stellst den Trigger auf Timer1-Overflow, liest> in der Timer-Isr den ADC-Wert und schreibst ihn ins OCR-Register.> Fertig. Ein bisschen konfigurieren, eine Zeile Code(OCR1A = ADCW;).> Den Rest macht der Controller alleine und dein Programm kann Primzahlen> berechnen.>> mfg.
Würde auch der Timer0 oder 2 gehen, denn der timer1 (16bit) ist ja schon
für die PWM verbraucht ?
Ranjid schrieb:> Thomas Eckmann schrieb:>>> Fast-PWM 10 bit ist dein Freund. Da kannst du deinen ADC-Wert direkt>> reinschreiben.>> Dann setzt du noch ADATE, stellst den Trigger auf Timer1-Overflow, liest>> in der Timer-Isr den ADC-Wert und schreibst ihn ins OCR-Register.>> Fertig. Ein bisschen konfigurieren, eine Zeile Code(OCR1A = ADCW;).>> Den Rest macht der Controller alleine und dein Programm kann Primzahlen>> berechnen.>>>> mfg.>> Würde auch der Timer0 oder 2 gehen, denn der timer1 (16bit) ist ja schon> für die PWM verbraucht ?
Du kannst den Timer1 dafür nehmen. Den Overflow erzeugt er auch mit Pwm.
Die Pwm stört das nicht. Die läuft davon unabhängig weiter.
mfg.
Ranjid schrieb:> Okay habe jetzt ADATE in TCCR1A gesetzt und in TCCR1B den Trigger auf> Timer1 overflow aktiviert, zeigt aber keine Wirkung
Huuuch?
ADATE ist nicht in TCCR1A und in TCCR1B gibt es kein Overflow.
Davon, daß der Timer zum Triggern des ADC benutzt wird, kriegt der gar
nichts mit.
Gesetzt wird das im ADCSRA-Register(ADATE) und im ADCSRB wird die
Trigger Source eingestellt(ADTS0 - 2).
mfg.
Thomas Eckmann schrieb:> Gesetzt wird das im ADCSRA-Register(ADATE) und im ADCSRB wird die> Trigger Source eingestellt(ADTS0 - 2).>> mfg.
Sry, das meinte ich, habe nur falsch geschrieben, in meinem Source den
ich gepostet habe, hatte ich es richtig, geht aber trotzdem nicht. Werde
mir nochmal das Dateblatt unter die Lupe nehmen.
Statt ISR(TIMER1_OVF_vect) folgendes benutzen : ISR(ADC_vect). Wenn ich
das Vorhaben richtig verstanden habe ( ADC messen und in OCRA laden
sobald der Wert ermittelt ist).
ADC_vect schrieb:> Statt ISR(TIMER1_OVF_vect) folgendes benutzen : ISR(ADC_vect).> Wenn ich> das Vorhaben richtig verstanden habe ( ADC messen und in OCRA laden> sobald der Wert ermittelt ist).
Habe ich auch schon versucht, jedoch bleibt die LED immer in der
gleichen Helligkeit. Am PWM liegt es nicht, wenn ich ihn "manuel"
verstelle, kann man sie die led steuern, der Fehler ist irgendwo beim
ADC. Ist vielleicht meine Frequenz zu hoch ? Sie liegt nicht in dem
optimalen Bereich von 50 und 200Khz wie Atmel empfielht. Habe leider
keinen anderen Quarz zu hand und zum internet möchte ich ungern
wechseln.
Getestet mit F_CPU = 18,432 MHz und einem 10K-Poti.
Beim Timing ist zu beachten, daß der Timer den ADC nicht triggert, bevor
die Wandlung fertig ist. Sonst fängt er mittendrin wieder von vorne an
und liefert natürlich Unsinn.
mfg.
ADC_vect schrieb:> Statt ISR(TIMER1_OVF_vect) folgendes benutzen : ISR(ADC_vect). Wenn ich> das Vorhaben richtig verstanden habe ( ADC messen und in OCRA laden> sobald der Wert ermittelt ist).
Man kann auch den ADC-Interrupt verwenden. Aber den Timer-Interrupt
braucht man trotzdem, da der Adc nicht durch das Overflow-Flag sondern
durch den Aufruf des Overflow-Interrupts getriggert wird.
mfg.