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.
Das habe ich mir schon durchgelesen, nur werde ich nciht so richtig schlau dadraus. Hat jemand ein Beispiel oder nen Tipp für mich?
Was ist denn unklar? Im Tutorial steht eigentlich alles Wissenswerte drin...
In den Datenblättern von Atmel sind (meine ich) kurze Codeschnipsel dabei. Ansonsten Forensuche oder Onkel Google... http://www.mikrocontroller.net/articles/AVR_PWM
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.
Also kann ich nicht einfach einmal Programmablauf den Wert setzen und die Hardware macht das dann alleine?
Doch aber erst wenn du verstanden hast wies geht, das findest du im ausführlichen Datasheet des ATMega32.
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?
Ich hätte auch einen Tipp:
1 | TCCR1A = _BV(WGM10)|_BV(WGM11)|_BV(COM1A1); |
2 | TCCR1B = _BV(CS10); |
3 | TCNT1 = 0; |
4 | |
5 | OCR1A = 0; |
Gilt natürlich für Timer 1. Kannst ja im Datenblatt nachsehen, was die einzelnen Register und Bits machen, OCR1A bestimmt das Tastverhältnis. ;)
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?
im Anhang was der CVAVR generator ausgespukt hat PORTB DDRB und alles zum Timer0 ist zu beachten
OCR0=0xA6; mit dem Wert kanst du spielen um die Helligkeit zu beeinflussen
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.
PORTB=0x00; DDRB=0x08; TCCR0=0x75; TCNT0=0x00; OCR0=0xA6; so müsste das also aussehen? hmm, funktioniert leider nicht:(
Achso, in dem Beispiel is ja der Takt mit ca. 11 MHz an gegeben. Mein Quarz läuft aber mit 16 Mhz. kann das was ausmachen?
> 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?
Ah ok, hat sich erledigt;) is echt nen besseres Gefühl selber was rauszufinden;)
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.