Forum: Mikrocontroller und Digitale Elektronik SoftPWM als funktion läuft nicht


von Tobias N. (silberkristall)


Lesenswert?

Hallo,

ich wollte die hier im Tutorial befindliche SoftPWM in einer funktion 
laufen lassen, allerdings geht dann garnichts mehr.

So läuft sie:
1
int main(void)
2
{  
3
 
4
  uint8_t pwm_soll = 100; // gewünschter Dimmerwert 0..100
5
  uint8_t pwm_phase = 0; // Laufwert der Schleife 0..100
6
 
7
  // LED + Widerstand mit PB0 und +5V verbunden
8
  // PB0 o-----|<-----###------o Vcc 5V
9
  DDRB |= (1<<PB1); // Pin PB0 an Port B als Ausgang
10
  // LED ist bereits an
11
 
12
  while(1)
13
  {
14
    if(pwm_soll == pwm_phase)
15
    {
16
      PORTB &= ~(1<<PB1); // active low LED aus
17
    }
18
    pwm_phase++;
19
    if(pwm_phase == 100)
20
    {
21
      pwm_phase = 0;
22
      PORTB |= (1<<PB1); // active low LED an
23
    }
24
  }
25
}

Jetzt dachte ich mir ich erstelle mir eine funktion namens dim() die 
dann den dimwert also pwm_soll enthält, also z.b. dim(20);
1
int dim(int dimwert)
2
{
3
4
  uint8_t pwm_soll = dimwert; // gewünschter Dimmerwert 0..100
5
  uint8_t pwm_phase = 0; // Laufwert der Schleife 0..100
6
7
if(pwm_soll == pwm_phase)
8
    {
9
      PORTB &= ~(1<<PB1); // active low LED aus
10
    }
11
    pwm_phase++;
12
    if(pwm_phase == 100)
13
    {
14
      pwm_phase = 0;
15
      PORTB |= (1<<PB1); // active low LED an
16
    }
17
18
}
19
20
int main(void)
21
{  
22
 
23
  
24
  // LED + Widerstand mit PB0 und +5V verbunden
25
  // PB0 o-----|<-----###------o Vcc 5V
26
  DDRB |= (1<<PB1); // Pin PB0 an Port B als Ausgang
27
  // LED ist bereits an
28
 
29
  while(1)
30
  {
31
    dim(20);
32
  }
33
}

Allerdings leuchtet hier die LED nur garnicht mehr. Komisch ist auch, 
das wenn ich bei dem ersten Code beispiel an das ende der while schleife 
noch was einfüge die LED dann auch nicht mehr leutet, also ich verstehe 
das hier mal rein garnichtmehr. Lasse ich den Code und sonst nichts 
weiteres in einer while schleife laufen oder schreibe ich vor dem pwm 
code was in die while geht alles.

Schreibe ich nach dem pwm code was in die while dann geht der ganze code 
nicht mehr.

Ich hoffe man versteht was ich meine und man kann mir weiter helfen.

Gruß

Tobias

von Eumel (Gast)


Lesenswert?

Wieso steht in den Kommentaren über all PB0 und im Code PB1?
Gewöhn dir mal gewissenhaftes Arbeiten an und liefer nicht so einen 
Pfusch ab.

von Oliver J. (skriptkiddy)


Lesenswert?

Tobias N. schrieb:
> uint8_t pwm_phase = 0; // Laufwert der Schleife 0..100

Diese variable musst du als static deklarieren. Sonst wird sie bei jedem 
Funktionsaufruf neu auf dem Stack erzeugt und mit Null beschreiben.

Gruß Oliver

von Michael (Gast)


Lesenswert?

Wie soll die PWM laufen, wenn du pwm_phase immer wieder auf 0 setzt?

von Tobias N. (silberkristall)


Lesenswert?

Hey, danke jetzt läufts, aber mit einem kleinen Fehler, ich weiss aber 
nicht warum,

hier mal der Code:
1
#include <avr/io.h>
2
static uint8_t pwm_phase = 100;
3
4
int dim(int dimwert, char pwmport)
5
{
6
  int pwm_soll = dimwert;
7
8
  if(pwm_soll == pwm_phase)
9
    {
10
      PORTB &= ~(1<<pwmport);
11
    }
12
    pwm_phase++;
13
    if(pwm_phase == 100)
14
    {
15
      pwm_phase = 0;
16
      PORTB |= (1<<pwmport);
17
    }    
18
  
19
  return 1;
20
}
21
22
int aufdimmen(int dimtime, char pwmport)
23
{
24
  int whiletime=0;
25
  int dimmingtime=0;
26
  int dimval=0;
27
  
28
  while(1)
29
  {
30
    dim(dimval, pwmport);
31
    dimmingtime++;
32
    if (dimmingtime == dimtime)
33
      {
34
        whiletime++;
35
        dimval++;
36
        dimmingtime = 0;
37
      }
38
    if (whiletime == 100) { return 1; break; }
39
  }
40
}
41
42
int abdimmen(int dimtime, char pwmport)
43
{
44
  int whiletime=0;
45
  int dimmingtime=0;
46
  int dimval=100;
47
  
48
  while(1)
49
  {
50
    dim(dimval, pwmport);
51
    dimmingtime++;
52
    if (dimmingtime == dimtime)
53
      {
54
        whiletime++;
55
        dimval--;
56
        dimmingtime = 0;
57
      }
58
    if (whiletime == 100) { return 2; break; }
59
  }
60
}
61
62
int main(void)
63
{  
64
65
 DDRB |= (1<<PB1);
66
67
int ledstatus = 1;
68
69
  while(1)
70
  {
71
  
72
  if (ledstatus == 2)
73
    {
74
      ledstatus = aufdimmen(1000, PB1);
75
    }
76
    else
77
    {
78
      ledstatus = abdimmen(1000, PB1);
79
    }
80
  }
81
}

Also das aufdimmen funktioniert perfekt, beim abdimmen, etwa bei der 
hälfte des dimmvorgangs blitzt die LED einmal kurz auf. Der Code des 
auf-, sowie abdimmens ist ja gleich deswegen verstehe ich das nicht. Es 
gibt auch sicherlich eine elegantere Lösung aber ich bin froh das sie so 
läuft wie es soll, bis auf diesen kleinen Fehler.

Danke euch.

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.