Forum: Compiler & IDEs Software-PWM zu heftig für µC?


von Wolfgang K. (Gast)


Angehängte Dateien:

Lesenswert?

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

von marvin m. (Gast)


Lesenswert?

Wurde in den Fuses auch das externe Quarz angewählt?

von Tim (Gast)


Lesenswert?

Klemm mal den Quarz ab. Wenn der AVR dann immer noch läuft, solltest du 
die Fuses kontrollieren...

von Peter D. (peda)


Lesenswert?

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

von Wolfgang K. (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Tim (Gast)


Lesenswert?

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...

von Wolfgang K. (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
}

von Peter D. (peda)


Lesenswert?

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

von Wolfgang K. (Gast)


Lesenswert?

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

von Tim (Gast)


Lesenswert?

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 :-)

von Karl H. (kbuchegg)


Lesenswert?

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.

von wieda der peda (Gast)


Lesenswert?

>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?

von Wolfgang K. (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von Wolfgang K. (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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
Noch kein Account? Hier anmelden.