Forum: Mikrocontroller und Digitale Elektronik Software PWM wird zum Ende langsamer


von Kuba (Gast)


Lesenswert?

Hallo, ich wollte PWM über Software erzeugen.

Ich hab mir die einfachste Arte rausgesucht, einfach Ein/Auszeit 
verändert.
Hier bei nehme ich feste 500uS Anzeit und verändere die Auszeit. In 
dieser Zeit-Spanne tritt kein Flimmern auf und die Spannung ist nur 
etwas niedriger als gewollte 15mV aber nicht Schlimm.

Ich habe mir mal die Soft-PWM Einträge angeguckt aber dies war mir fürn 
Anfang zu viel und deswegen wollte ich dies erst mal recht einfach 
lösen, da es mir erst nur ums dunkel und heller machen geht.

Was ist mein Anliegen ? Wie es im Betreff steht, möchte ich die LED 
dunkler machen, wird es zum Ende langsamer dunkel. Beispiel, so bei 4V 
und 3V springt er mit ca. 0.1V Schritten und bei 2V mit ca. 0.01V 
Schritten.

Ich kann die Spannung aber schon genau Einstellen.

Hier mal mein kleiner Code :
1
for (int i=0;i<1500;i++) //Maximale Auszeit
2
    {    
3
    
4
    
5
    for (int i=0;i<10;i++) // Anzeit pro Schritt
6
    {
7
      PORTB = (1<<PB4);
8
      _delay_us(500);
9
      PORTB &= ~ (1<<PB4);
10
      
11
      
12
      if (time==0)
13
      {
14
        _delay_us(0);
15
        
16
      }
17
      
18
      else
19
      
20
      {
21
        
22
        for (int l=0;l<time;l++)
23
        {
24
          _delay_us(1);
25
        }
26
      }
27
          
28
    
29
    
30
    }
31
    
32
    
33
    time++;
34
    
35
    }

von devynf (Gast)


Lesenswert?

Meinst Du die LED wird langsamer dunkler nach einer bestimmten Zeit?
Wenn ja, dann sei Dir bewusst, daß die Helligkeit der LED logarithmisch 
abnimmt. Das musst Du dann natürlich auch im Code abbilden.
Zum Code: warum tust Du Dir das an? PWM mittels Timer setzen ist 
einfacher als die verschachtelten for-Konstrukte zu verwenden!

von Kuba (Gast)


Lesenswert?

Die Spannaung nimmt nach ner Zeit langsamer ab, folglich auch die 
Helligkeit.

Meinen Sie Hardware PWM oder Soft-PWM

Über Hardware-PWM wollte  ich das nicht machen da ich später min. 3 
Anschlüsse ansteuern wollte.

von Skyper (Gast)


Lesenswert?

... die LED verhällt sich von der Helligkeit nicht linear, siehe --> 
http://www.mikrocontroller.net/articles/LED-Fading

von Stefan (Gast)


Lesenswert?

3 Anschlüsse gleichzeitig ansteuern mit Deinem Code wird nicht gehen. 
Dazu musst Du entweder Hardware-PWM oder SW-PWM per Interrupt machen.

Daß die Spannung nicht linear abnimmt, ist logisch. Ist das so von Dir 
gewollt oder verstehst Du nicht, warum das so ist?

Gruß, Stefan

von Vlad T. (vlad_tepesch)


Lesenswert?

dein Problem ist, dass du die Aus-zeit zwar immer verlängerst, aber die 
An-Zeit nicht verkürzt. Deine Zykluszeit wird also immer größer.

dein Code sieht ziemlich unstrukturiert aus.

Ein Zyklus hat 2 Parameter:
 - die Länge
 - das Tastverhältnis

dieser Zyklus wird einfach mehrmals wiederholt, bis man irgendwann die 
Parameter ändert.
1
int  anzahl_Zyklen_je_Wert = 5000:
2
int  dauer_Zyklus_gesamt_us = 1500;
3
4
for( int dauer_an = 0; dauer_an < dauer_Zyklus_gesamt_us; ++i)
5
{
6
  int dauer_aus = dauer_Zyklus_gesamt_us - dauer_an;
7
8
  for( int i=anzahl_Zyklen_je_Wert; i; --i)
9
  {
10
      PORTB = (1<<PB4);
11
      mydelay(dauer_an);
12
      PORTB &= ~ (1<<PB4);
13
      mydelay(dauer_aus);
14
  }
15
}

mydelay muss ne schleife um _delay_us sein, da da nur konstante werte 
reindürfen. Der schleifencode versaut natürlich das Timing massiv, da 
eine µs nicht wirklich viel ist, im vergleich zu der schleife. 
vielleicht sollte man also eine schleife über _delay_us(10) oder so 
implentieren.

Das lässt aber auch offensichtlich werden, dass es nicht sinnvoll ist 
eine PWM mittels delay zu bauen.

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

i   Anzeit   Auszeit  PWM

   0   500     0     100%
 100   500   100      83%
 200   500   200      71%
 300   500   300      62%
 400   500   400      55%

 500   500   500      50%
 600   500   600      45%
 700   500   700      41%
 800   500   800      38%
 900   500   900      35%
1000   500  1000      33%
1100   500  1100      31%
1200   500  1200      29%
1300   500  1300      27%
1400   500  1400      26%
1500   500  1500      25%

Was Du für eine LED eher willst, ist ein logarythmischer PWM-Verlauf. 
Das wirst Du mit einer konstanten Anzeit aber nicht errechen.

Gruß, Stefan

von Vlad T. (vlad_tepesch)


Lesenswert?

Stefan schrieb:
> i   Anzeit   Auszeit  PWM
>
>    0   500     0     100%
>  100   500   100      83%
>  200   500   200      71%
>  3 ...

Das ist aber keine PWM. Eine PWM hat eine feste Frequenz.
Bzw es ist ungewöhnlich das Tastverhältnis durch eine Änderung der 
Frequenz anzupassen.

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

@ Vlad Tepesch:
1
i   Anzeit   Auszeit  Das An/Aus-Verhältnis, das die 
2
                      obige Software (ca.) liefert
3
4
   0   500     0     100%
5
 100   500   100      83%
6
 200   500   200      71%
7
 300   500   300      62%
8
 400   500   400      55%
9
10
 500   500   500      50%
11
 600   500   600      45%
12
 700   500   700      41%
13
 800   500   800      38%
14
 900   500   900      35%
15
1000   500  1000      33%
16
1100   500  1100      31%
17
1200   500  1200      29%
18
1300   500  1300      27%
19
1400   500  1400      26%
20
1500   500  1500      25%
So zufrieden? ;-)

: Bearbeitet durch User
von Kuba (Gast)


Lesenswert?

ok, vielen Dank jetzt leuchtet es mir ein, das es so nich funktioiert.

Werde mich jetzt wohl an SOFT-PW ran bewegen. Mein Mega32 hat leider nur 
1 PWM Ausgang.

von Vlad T. (vlad_tepesch)


Lesenswert?

Kuba schrieb:
> Mein Mega32 hat leider nur
> 1 PWM Ausgang.

aha

von Peter D. (peda)


Lesenswert?

Kuba schrieb:
> Mein Mega32 hat leider nur
> 1 PWM Ausgang.

Das Datenblatt ist da anderer Meinung:
– Four PWM Channels

von Kuba (Gast)


Lesenswert?

Entschuldigung...

Hab jetzt mal den Timer2 und Timer0 genommen.

Timer0 funktioniert einwandfrei, allerdings nur wenn Timer2 nicht läuft.
Timer2 kann ich OCR2 werte geben und er gibt es richtig aus (0 bis 255).
Aber möchte ich nun von 0 bis 255  hoch zählen und meine LED heller 
werden lassen, dauert dies eine Ewigkeit. Timer0 macht es ganz normal, 
aber wenn ich beide parallel laufen lasse brauchen beide eine Ewigkeit.
Hoffe ich hab mich einigermaßen ausgedrückt..und jemand kann mir helfen

Hier mal der Code
1
void PWM_Int(){  
2
  
3
  TCCR0 = (1<<WGM01) | (1<<WGM00) | (1<<CS00) | /*(1<<CS02) |*/ (1<<COM01); //Fast PWM //Zählt von 0 bis OCR0
4
  
5
6
TCCR2 = (1<<WGM21) | (1<<WGM20)  | (1<<COM21) |(1<<CS20) ;
7
}
8
9
10
//Wert: Zwischen 0 - 255
11
12
//0= 0%
13
14
//255= 100%
15
  
16
//      Wert
17
//Vout=  ------ x 5v
18
//        255
19
20
void PWM_Output(uint8_t wert){
21
     OCR0=wert;  
22
     OCR2=wert;
23
}
24
25
//_____________
26
27
   while (1)
28
     {
29
       
30
       
31
       for (Brightness=0;Brightness<255;Brightness++)
32
       {
33
         
34
         PWM_Output(Brightness);
35
         
36
         _delay_ms(50);
37
       }
38
       
39
       _delay_ms(5000);
40
       
41
       for (Brightness=255;Brightness>0;Brightness--)
42
       {
43
         
44
         PWM_Output(Brightness);
45
         
46
         _delay_ms(50);
47
       }
48
         
49
      _delay_ms(5000);
50
              
51
       
52
       
53
     }

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.