Hallo Leute, ich bin gerade dabei mich in die Materie von PWM beim AVR Mega 8 einzuarbeiten. Ziel ist es, zwei Led's unabhängig von einander in 100 1% Schritten zu dimmen (also von 0 bis 100%) So wie ich das jetzt am Anfang sehe, kann ich aber nur in 2er Potenz-Schritten dimmen, also 32,64,128 etc Schritten. Es muß doch irgendwie möglich sein, in 100 (oder 101?) Schritten von 0 auf 100% zu kommen. Ich will nämlich am Display einen Zähler mitlaufen lassen, um die aktuelle Rate zu erkennen. Habe ich da irgendwo einen Denkfehler, oder gehen 100 lineare Schritte wirklich nicht? Besten Dank für anfängerverständliche Hinweise
Mit Software-PWM ist das kein Problem (Zählumfang begrenzen), mit Hardware-PWM habe ich das noch nicht gemacht und das komplette Datenblatt habe ich auch nicht im Kopf...
Hi, von den 255 (256)(8Bit-PWM) schritten irgentwelche zu überspringen, damit es 100 werden ist glaube ich nicht das Problem. Linear wird der helligkeitseindruck sowieso erst mit einer korrektur im untere (dunkleren) Bereich. Wurde schon öfters diskutiert, z.B.: http://www.mikrocontroller.net/forum/read-1-118198.html Grüße Quark P.S. sollte ich solche Antworten, die die Frage nicht richtig beantworten, überhaupt posten?
Hi... Eine Variante: Im Flash eine Tabelle mit 100 (101?) Einträgen einrichten, in denen die gewünschten Stufen (mit übersprungenen Werten, wie Quark meint) für die Timer-Output-Compare-Register abgelegt sind. Wenn man Timer1 nutzt (nur der hat ZWEI Output-Compare-Register mit PWM-Ausgang), sind das dann 16-Bit-Werte (das L-Byte kann aber immer 0 sein, die Tabelle brauch also nur die H-Bytes enthalten). Noch eine Variante: 32, 64, 128 oder 256 Stufen nehmen und in einer Tabelle im Flash die zugehörigen Prozent-Zahlen für die Anzeige ablegen. Weitere Variante: Mittels Timer1-Overflov-Interrupt Timer1 auf einen Startwert 100 (101?) Schritte vor Überlauf setzen. Diesen Wert als Basiswert für die Compare-Register nehmen und die Prozentzahl dazu addieren. Software-Variante: Einen 8-Bit-Timer rundrum klappern lassen und bei Überlauf einen Int auslösen lassen. Im Int (ISR) ein Register als Zähler hochzählen. Ist 101 erreicht, dann Register auf 0 setzen und LEDs einschalten. Ist der Prozentwert der LEDs erreicht (oder überschritten?), dann LED ausschalten. Das geht dann auch mit mehr als 2 LEDs gut. Das Ganze nicht zu schnell, damit noch Rechenzeit für andere Aufgaben übrig bleibt. Vielleicht lässt sich dieser Timer auch gleich für das LCD-Timing missbrauchen. ...HanneS...
Hallo Manu, Ich habe mal einen Auszug aus meinem Programm hier hin geschrieben. (Ich hoffe das die wichtigsten Sachen nicht fehlen) Ich weiß nicht ob es dir weiter helfen kann. In einem Teil des Programms zeige ich den PWM- Wert zwischen 0 bis 100 % auf einem Display an. Ich erhöhe den Wert immer um 5%. Mit dem PWM- Wert wird dann eine 12 Volt Lampe "gedimmt" Ich weiß, das "do-while" das ganze Programm aufhält aber das ist bei meiner Anwendung egal da sonst nichts andres zu laufen braucht. Das Problem ist nur, dass ich es mit "CodeVision AVR" geschrieben habe. Aber ich glaube mit ein bisschen "rumproggen" sollte es mit "WINAVR" oder sonstiges leicht zu ändern sein. Ich benutze den ATMEGA16L. //////////////////////////////////////////////////////////////////// // Die do-while Schleife wird so lange abgearbeitet wie die while- // Bedingung gegeben ist do { delay_ms(80); if(PIND.3 == 0) { port=3;} if(PIND.4 == 0) { port=4;} if((PIND.3)&&(PIND.4)) port = 0; // Wenn keiner der Tasten gedrückt //ist --> port = 0 switch (port) { /////////////////////////////////////////////////////////// // "lcd_anzeigewert" ist für den 0-100 % Wert auf // dem Display /////////////////////////////////////////////////////////// //**** Helligkeit erhöhen ***************** case 3: // |--- mit dem break Befehl // | wird zum Ende der Schleife // | gesprungen und alle anderen // | case- Anweisungen // | nicht mehr abgefragt if(lcd_anzeigewert == 100) break; // der Wert soll nicht größer wie 100 werden lcd_anzeigewert+=5; // Wert um 5 erhöhen break; //***************************************** //**** Helligkeit verringern ************** case 4: if (lcd_anzeigewert == 0) break; // der Wert soll nicht kleiner wie 0 werden lcd_anzeigewert-=5; // immer um 5 erniedrigen break; //***************************************** }// |-- diese Variable gehört zum Timer 0 OCR0 = ((lcd_anzeigewert*25.5)/10); // es wird der "pwm_wert" // aus "lcd_anzeigewert" // errechnet. Hier wird der // Wert zwischen 0 und 255 // erzeugt itoa(lcd_anzeigewert, puffer); // lcd_anzeigerwert in ein String schreiben lcd_gotoxy(13,2); lcd_putsf(" "); // alten Wert überschreiben lcd_gotoxy(13,2); lcd_puts(puffer); lcd_putsf("%"); // |-------------|--- while Bedingung }while (!(mode == 1)); // So lange bis die Taste 0 gedrückt wird OCR0 =0; // PWM wieder auf Null setzen (Lampe ausschalten) } ///////////////////////////////////////////////////////////// Ich weiß das du immer um ein Prozent erhöhen wolltest aber vielleicht konnte ich ja ein wenig helfen. Gruß Marcel
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.