Hallo Leute, ich möchte mit einem Atmega32 eine LED dimmen,. Leider habe
ich dabei einige Startschwierigkeiten. Ich weiß, dass ich PB3 (OC0)
nutzen kann. Diesen muss ich auch als Ausgang schalten, also DDRB=0x07;,
oder?
Was muss ich für Register setzen und wie kann ich das ganze in eine
Endlosschleife einbauen, die schon in meinem Programm existiert? Achja,
mein uC läuft mit 16MHz.
Ja, die Register und das alles steht schon drin...aber ich weiß nciht so
recht wie ich es machen soll. Sagen wir ich habe solch ein
Programmaufbau:
int main(){
//Schreiben der Register
while(1){
//Ermitteln von Helligkeit
//OCR0 = Helligkeit;
//Restlicher Programmablauf
};
};
geht das so?
Ich fürchte du hast gar nicht verstanden, worum es sich bei der
Puls_Weiten_Modulation handelt?
in der Sache geht es darum das die LED ständig an und ausgeschaltet
wird. Das Verhältnis zwischen ein und Ausschaltdauer, Pulsweite bezogen
auf die Zyclendauer bestimmt die Helligkeit der LED.
Hintergrund ist die zeitliche integration des aufgebachten
Eenergieäquivalents einer andauernden Energiezufur mit geringerer
Leistung.
Am einfachsten realsiert du das in dem du nen Timer durchlaufen läst.
immer beim overflow(timmer ==0) schaltet den HP die LED ein wenn der
timer einen wert X erreicht schaltest du die LED aus. so kannst du das
Tastverhähltnis (die relative Pulsweite) bestimmen.
Wenn du das alles verstanden hast kannst du den HW-Timeer auch direkt
für die PWM-Erzeugung benutzen. Dazu must du dessen Steuerregister
entsprechend setzen. so bleibt der prozessor frei für weniger simple
Funktionen.
Beispiel:
TIMER1_CLOCK_SELECT(TIMER1_PRESC_8);
TIMER1_WGM_MODE(TIMER1_PWM10_BIT); //PWM, 10 Bit
OCA1_PIN_CONFIG(TIMER1_OC_PIN_CLEAR); //Clear at Compare Match, Set
at TOP
OCR1A=0x0100; //Compare-Match RegisterA
eine Alternative bietet Der CVAVR compiler
der besitzt eine Codewizard der deneriert dier da s fix und fertig, wenn
du ihm deine Wünsche in denentsprechenden eingabefeldern mitteilst.
Um das für dich zu machen müßte ich den anderen Rechner starten. Hier im
Wohnzimmer ist das nicht installiert.
Aber mehr lernst du durch selber erarbeiten, als wenn du es nur
abschreibst.
Ok, dann probier ichs mal...also, ich denke mal, dass entscheidene
Register is TCCR0.
Also müsste das gaze doch so aussehn:
TCCR0 = (1 << WGM00) | (1 << COM01) | (1 << ...);
oder?
aber wie komme ich nun auf den Clock?
Hmm, wie müsste das mit dem Timer1 denn im konkreten Anwendungsfall
aussehen?
Es ist doch ne 10Bit PWM, oder?
Wie müsste das ganze jetzt im Code aussehn, wenn ich Beispielsweise die
halbe Helligkeit erreichen will?
Nunja, wie das mit der Helligkeit aussieht weiß ich nicht, die LED ist
ja nicht linear, was die Helligkeit betrifft.
Mit dem PWM (dem Tastverhältnis) stellst du den Effektivwert der
Rechteck-Wechselspannung ein. => Frequenz fest, Tastverhältnis variabel
über OCR1A. Bei 10 bit (0..1023) wäre die Hälfte dann logischerweise
512, bei 8 Bit (0..255) dann 128.
> Nunja, wie das mit der Helligkeit aussieht weiß ich nicht, die LED ist> ja nicht linear, was die Helligkeit betrifft.
Die Nichtlinearität einer LED spielt da keine Rolle. Es ist ja nicht so,
dass die LED bei einer 50% PWM irgendwie mit halber Spannung oder so
läuft. Es bedeutet, dass die LED 50% der Zeit ganz an und 50% der Zeit
ganz aus ist. Das Auge (oder genauer das Gehirn) macht daraus dann die
halbe Helligkeit (sofern die Wechsel schnell genug sind). Wenn du also
eine Nichtlinearität zwischen Duty-Cycle und Helligkeit feststellst,
dann liegt diese in deinem Kopf. ;-)
@ Thilo
Das ist ein interrsanter Seiteneneffekt der Dimmung via PWM.
Da die LED aussschlieslich in einem Arbeitspunkt ihrer Kennlinie ein und
ausgeschaltet wird ist die Lichtausbeute (photonemmitting per zeit)
proportional dem Tastverhältnis.
Da unser Auge die Helligkeit integrierend erfasst, erfahren wir eine
proportionale Helligkeitsänderung solange die Impulsfolgefrequenz höher
als unser zeitliches Auflösungsvermögen ist.
Dieses liegt bei ca.25 Hz was man jedoch bei schneller
Auge-Objekt-Bewegung noch als verschieden Lichtquellen wahrnimmt. Erst
ab ca. 100Hz entsteht ein flimmerfreies Bild auch in der Bewegung.
die Frequenz des timers ist um 1/3 höher.
Auf das Tastverältnis hat das keinen Einfluss und somit nicht auf die
Helligkeit. Diese ist lediglich von deinem Vorwiderstand, der LED und
dem Wert in OCR0 abhängig.
Ja, das wusste ich, und es funktioniert auch:) aber leider flimmert das
ganz doch deutlich bei niedrigeren Werten...kann man das irgendwie noch
ändern?
versuchs mal mit den Werten
weniger Vorzähler
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 11059,200 kHz //= Systemclock
// Mode: Phase correct PWM top=FFh
// OC0 output: Inverted PWM
TCCR0=0x71;
TCNT0=0x00;
OCR0=0xA0;
while (1)
{
// Place your code here
delay_ms(20);OCR0++;
};
Die schleife Dient dem sichtbar machen alle 20 ms ein bit hochzählen.
delay_ms(n) ist eine funktion der liberydatei delay.lib des CVAVR hier
must du eine eigene Pausefunktion verwenden/selber schreiben. Im
eifachsten fall verschachtelte while schleifen.
wenn die LED gegen plus geschaltet wird wird sie langsam heller. habe
das hier gerade mal aufgebaut.
Habe dass gerade aufgebaut. Funktioniert.