Hallo! Bei diesem Source-Code-Teil hab ich Probleme mit der Geschwindigkeit, wie schnell er abgearbeitet wird. Habe einen ATMega 8. Der ganze andere Source-Code ist deaktiviert, es läuft nur mehr dieser Programmabschnitt. Es ist eine Software-PWM mit der eine LED gedimmt wird. Ich muss eine Software-PWM nehmen, da ich 3 PWM's parallel laufen lassen will und jede ist anders, darum nicht den Hardware-Timer. Die Variable i_Fussraum_Glow gibt an, wie weit die pwm insgesamt hochzählt. Ich kann sie aber bis max. ca. 150 zählen lassen, bei einem höheren Wert sieht man, dass die LED zu flackern beginnen, d.h. µC arbeitet den Code dann nicht mehr schnell genug ab. Am Anfang war ein 4MHz Quarz drin, bin auf 8 und jetzt 16MHz gegangen (ist ja ein ATMega 8-16PI). Es hat sich aber nichts daran geändert, kann trotzdem nicht über ca. 150 gehen. Ist der µC nicht schneller geworden? Hab auch den define für f_CPU und das makefile auf 16MHz umgestellt. mfg Wolfgang
Wolfgang K. wrote: > Bei diesem Source-Code-Teil hab ich Probleme mit der Geschwindigkeit, > wie schnell er abgearbeitet wird. ??? Ich sehe nirgends einen compilierbaren und kommentierten Source-Code! Source Code heißt entweder *.asm oder *.c. Nie aber *.txt, *.doc, *.bmp oder andere Verrücktheiten. Wenn Du Hilfe willt, mußt Du schon was vernünftiges posten. Für ne PWM braucht man als allererstes einen Timerinterrupt. Da kommt dann nur das für die PWM unbedingt notwendige rein, der Rest kommt ins Main. Peter
habe den source-code aus meinem rauskopiert, da ich das problem durch aus-kommentieren die geschwindigkeitsbremse auf die software-pwm eingegrenzt habe. wie gesagt kann keinen timer nehmen, da ich 3 pwms gleichzeitig laufen lassen will. aber das problem ist gefunden. wie ihr gesagt habt ist der intere oszillator eingestellt. nur wie stelle ich die fuse-bits um? normalerweise ja durch erhöhte spannung und programmierung über die parallele schnittstelle. habe aber keine parallele. benutze einen myAVR programmer über usb. wie kann ich dann die fuse-bits einstellen? oder geht es nur über die parallele? mfg
Wolfgang K. wrote: > habe den source-code aus meinem rauskopiert, da ich das problem durch > aus-kommentieren die geschwindigkeitsbremse auf die software-pwm > eingegrenzt habe. Ich sehe da nirgends die PWM, nur nen riesigen Wust an irgendwelchen Vergleichen. > wie gesagt kann keinen timer nehmen, da ich 3 pwms > gleichzeitig laufen lassen will. Na dann verrate mir mal, wie Du ohne Timer ne PWM hinkriegen willst. Du brauchst eine Compareinterrupt und in dem Interrupthandler hast Du für 3 PWMs genau 3 Vergleiche drin und eine Zählvariable, mehr nicht. Peter
Die Fuses lassen wie das Flash schreiben, geht problemlos über die ISP Schnittstelle. Must halt nur deiner Flashsoftware sagen das sie Fuses entsprechend deinen Wünschen schreiben soll. Aber voher die neue Einstellung 2x prüfen, da man sich mit den Fuses auch mal ganz schnell selbst aussperren kann :-) PS: Der Code sieht in der tat etwas Komisch aus...
Mit WinAVR die Fuses programmieren geht nicht oder? Muss ich nach einem anderen Prog mich umsehen. Mein ATMega hat ja nur 2 Timer. Wie soll ich damit 3 PWM's gleichzeitig laufen lassen, die aber alle verschieden sind? Wenn die eine PWM am Anfang ist, ist die andere schon bei der Mitte, usw. Der "komische" Code ist einfach nur eine Variable die hochzählt und bei einem Überlauf neu anfängt (i_Fussraum_Glow). Dieser Wert mit einem anderen Wert (iii_Fussraum_Glow) verglichen, bei Gleichstand wird ein Wechsel zwischen High-Low durchgeführt. Die Variable ii_Fussraum_Glow ist nur da, damit ich die Geschwindigkeit der Änderung der einzelnen Helligkeitsstufen der LED regeln kann. Ich finde das ist eine sehr primitive Software-Methode um eine PWM zu realisieren. mfg
Und als nächstes siehst du dir in deinem C-Buch mal den Abschnitt über Arrays an und überlegst dir mal, wie man ein Array anstelle dieser perversen if-else Orgie einsetzen könnte um die Werte für das Ein und Aus-Faden zu erreichen.
Wolfgang K. wrote:
> Mein ATMega hat ja nur 2 Timer.
Und?
Einer reicht bereits völlig aus um damit mehrere PWM zu
erzeugen. Nicht in Hardware, aber in Software.
Das PWM-Prinzip dürftest du ja verstanden haben.
Mach dir einen Timer, der in regelmässigen Abständen einen
Overflow Interrupt auslöst.
In der zugehörigen ISR
1 | uint8_t PWM_Counter; |
2 | uint8_t PWM1; |
3 | uint8_t PWM2; |
4 | uint8_t PWM3; |
5 | |
6 | ISR( .... ) |
7 | {
|
8 | PWM_Counter++; |
9 | |
10 | if( PWM_Counter < PWM1 ) |
11 | LED1_ausschalten; |
12 | else
|
13 | LED1_einschalten; |
14 | |
15 | if( PWM_Counter < PWM2 ) |
16 | LED2_ausschalten; |
17 | else
|
18 | LED2_einschalten; |
19 | |
20 | if( PWM_Counter < PWM3 ) |
21 | LED3_ausschalten; |
22 | else
|
23 | LED3_einschalten; |
24 | }
|
Wolfgang K. wrote: > Mein ATMega hat ja nur 2 Timer. Also bei mir steht im Datenblatt: 3 Timer und 3 PWM-Ausgänge Brauchst also garkeine SW-PWM. > Wie soll ich damit 3 PWM's gleichzeitig > laufen lassen, die aber alle verschieden sind? Wenn die eine PWM am > Anfang ist, ist die andere schon bei der Mitte, usw. Du bringst da wohl PWM mit Dimmen durcheinander. Die PWM bestimmt die Helligkeit und da muß die Frequenz hoch sein, damits nicht flackert, also Timerinterrupt. Das Dimmen soll nur den Helligkeitswert ändern und das schön langsam, kann man also bequem im Main machen. Damit aber gleichmäßig gedimmt wird, sollte man dazu nen 2. Timer als Takt nehmen. > Ich finde das ist eine sehr primitive Software-Methode um eine PWM zu > realisieren. Ich verstehe sie leider überhaupt nicht. Wenn Du es nächstes mal als *.c postest, kann man es sich wenigstens formatiert ansehen, das macht es lesbarer. Peter
Die perverse if-else orgie wird später durch ein array ersetzt, war nur zum probieren schnell geschrieben (bzw. zeilen kopiert). das mit dem timer ist einleuchtend, werd das gleich mal abändern. thx mfg
Winavr nutzt doch avrdude zum Flashen, oder? Und avrdude kann die Fuses schreiben, muss halt nur entsprechend aufgerufen werden. Wie und wo du das beim WinAvr machen musst weiss ich aber nicht (arbeite hier unter Linux :-)
Falls das nicht klar herausgekommen ist: Durch zuweisen von Werten an PWM1, PWM2 und PWM3 setzt du die jeweilige LED auf einen bestimmten Helligkeitswert. Die LED leuchtet dann, dank Timer und ISR ganz von alleine auf diesem Helligkeitswert. An anderer Stelle im Programm hast du dann alle Zeit der Welt in beliebiger Reihenfolge irgendwelche Werte (zb. welche die einen Helligkeitsanstieg bewirken) an diese Variablen zuzuweisen. Bei einer PWM geht es erstmal nur darum, dass die LED nicht nur 2 Helligkeitsstufen kennt, sondern mehrere. Nicht mehr und nicht weniger. Eine andere Geschichte ist dann Dimmen.
>Ich sehe da nirgends die PWM, nur nen riesigen Wust an irgendwelchen >Vergleichen. Das aber nicht daran, daß in dem Code nicht der Versuch zu erkennen wäre, eine PWM zu schreiben, als vielmehr an der dir eigenen Beschränktheit. Und du solltest endlich damit aufhören, deine Beschränktheit den Hilfesuchenden anzulasten. Wenn du die Fragen nicht schnallst, halte dich doch einfach mal zurück, ja?
Das mit dem Timer ist schon klar, danke nochmals. Bezüglich dem Wort "Dimmen": Dachte mit einer PWM kann man auch dimmen? Also das Dimmen das ich drunter verstehe (weniger hell leuchten), und das funktioniert ja bei led's nur mit einer pwm (bei µC, geht ja auch mittels stromregelung). mfg
Wolfgang K. wrote: > Dachte mit einer PWM kann man auch dimmen? Also das Dimmen das ich > drunter verstehe (weniger hell leuchten), und das funktioniert ja bei > led's nur mit einer pwm (bei µC, geht ja auch mittels stromregelung). Mein Fehler: Ja klar: Dimmen ist ja eine stufenlose Einstellbarkeit. Meinte: Fading Als das langsame Ein- oder Aus-dimmen.
wieda der peda wrote: >>Ich sehe da nirgends die PWM, nur nen riesigen Wust an irgendwelchen >>Vergleichen. > > Das aber nicht daran, daß in dem Code nicht der Versuch zu erkennen > wäre, eine PWM zu schreiben, als vielmehr an der dir eigenen > Beschränktheit. Und du solltest endlich damit aufhören, deine > Beschränktheit den Hilfesuchenden anzulasten. Wenn du die Fragen nicht > schnallst, halte dich doch einfach mal zurück, ja? Ich glaub eher, dass er den Threadopener darauf hinweisen sollte, mal ein paar Erklärungen zum Code abzugeben, den Code formatiert anzuhängen, oder erstmal die Struktur des Programms überdenken sollte, bevor man hier weiter macht.
Es war eine sehr unübliche Methode, eine PWM zu erzeugen. Und da ich eine kleine Erklärung am Anfang abgegeben habe, dachte ich schon, dass es kein Problem ist, den Code zu verstehen. Sind ja nur 3 Variablen. Dass der Code durch die txt-Endung schlechter lesbar ist, ist mir jetzt auch klar. Hab den Code einfach schnell rauskopiert, d.h. wenn man die Endung der Datei auf .c ändert, müsste ein formatierter Code rauskommen. Aber ist ja jetzt egal, beim nächsten Mal weiss ich es und es wird nicht mehr passieren. mfg
Wenn man genauer hinblickt, sind die obersten 2 Zeilen die PWM der ganze Rest ist das Fading (Dimmen). Und damit, daß Du das Fading mit in die PWM reinmanschst, klaust Du Dir massig Performance und es kann schnell flackern. Auch wenn es mit nem 16MHz Quarz etwas besser wird, muß man trotzdem nicht die CPU-Zeit mit Gewalt vernichten. Wenn bei der PWM mal ein Impuls 1ms länger dauert, flackert das merklich. Wenn dagegen das Fading mal 100ms später den neuen Helligkeitswert an die PWM übergibt, merkt das keine Sau. Trenne die PWM vom Fading und schon gehts viel besser. Selbst wenn Du auf ne 16-fach PWM aufrüsten willst, ist das dann kein Problem mehr. Auch in der Softwareentwicklung gilt nämlich die alte Devise: "Teile (die Aufgaben) und herrsche!" Es ist auch nicht leserlich, wenn man die Variablen nur an der Anzahl der 'i' unterscheiden kann. Wenn Dir nichts besseres einfällt, dann nimm wenigstens a,b,c,... Peter
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.