Forum: Mikrocontroller und Digitale Elektronik Hilfe bei PWM Code benötigt


von Christian E. (ultraschall81)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte auf einem Atmega8 eine PWM zur Dimmung für 
Konstantstromquellen verwirklichen.
Dabei soll bei einem kurzen Tastendruck die PWM bei ca. 70% laufen.
Wenn das Licht an ist und die Taste erneut gedrückt wird, soll das licht 
entweder heller oder dunkler werden.
Habe dazu ein kleines Program in C geschrieben aber es funktioniert 
nicht wie es soll. (Bin kein C Experte. Hatte es mal vor ein paar Jahren 
in der Schule :-( )

Wenn ich das mit AVR Studio simuliere, funktioniert wenigstens die PWM 
"Veränderung". Aber die Abfrage der Variable "Richtung" wird immer 
übersprungen (letztes "if" in der Funktion) Weiß echt nicht warum. 
Dadurch würde die Heller / Dunkler Geschichte nicht wirken, sondern es 
wird bei längerem Testendruck immer nur heller.

Habe das dann mal auf den Atmel gebrannt. Da funktioniert noch weniger. 
Nach dem Reset ist der Portpin auf low. Drücke ich die Taste (egal wie 
lang und wie oft) geht der port von low auf high und bleibt da.

Kann mir da einer weiterhelfen?

Danke schonmal.

von Karl H. (kbuchegg)


Lesenswert?

Christian E. wrote:

> Wenn ich das mit AVR Studio simuliere, funktioniert wenigstens die PWM
> "Veränderung". Aber die Abfrage der Variable "Richtung" wird immer
> übersprungen (letztes "if" in der Funktion) Weiß echt nicht warum.

Hmm. Dachte nicht, dass dein Compiler das raufindet :-)

Schau dir mal an, was mit der 'Richtung' in deiner Funktion weiter 
passiert. Du gibst sie aus der Funktion heraus zurück. An wen? An den 
Aufrufer. Der kriegt den Wert und könnte damit etwas machen.

Was macht er wirklich damit?
1
  if (PIND & (1<<PIND2))   //Wenn Taste gedrückt
2
    pwm_t1a (Richtung);    //PWM timer 1A aufrufen

Nichts!

Wenn also der Aufrufer nichts damit macht, ist es auch sinnlos einen 
Returnwert zurückzuliefern. Einen Returnwert der zurückgeliefert werden 
soll, braucht man auch nicht manipulieren.
Also ist der ganze Teil
1
  if (Richtung==1)    //Richtung wird invertiert
2
    Richtung=0;     //dass bei jedem längeren Tastendruck
3
  else              //das Licht heller oder
4
    Richtung=1;     //dunkler wird

für die Katz und kann entfallen.

Alternativ könnte man auch sagen. Die Umschaltung von Richtung in der 
Funktion interessiert die Variable Richtung in main nicht die Bohne.

1
  if (PIND & (1<<PIND2))   //Wenn Taste gedrückt
2
    Richtung = pwm_t1a (Richtung);    //PWM timer 1A aufrufen

PS: Eine Variable kann man auch zwischn 0 und 1 hin und her schalten 
lassen mittels
1
   Richtung = 1 - Richtung;

Ist vielleicht einfacher als dieses if-else Konstrukt

von Christian E. (ultraschall81)


Angehängte Dateien:

Lesenswert?

Hallo,

Danke erstmal für die schnelle Antwort. Leider habe ich nicht soviel 
Zeit für das Projekt.




Karl heinz Buchegger wrote:
>
> Schau dir mal an, was mit der 'Richtung' in deiner Funktion weiter
> passiert. Du gibst sie aus der Funktion heraus zurück. An wen? An den
> Aufrufer. Der kriegt den Wert und könnte damit etwas machen.
>
> Was macht er wirklich damit?
>
>
1
>   if (PIND & (1<<PIND2))   //Wenn Taste gedrückt
2
>     pwm_t1a (Richtung);    //PWM timer 1A aufrufen
3
>
>
> Nichts!
>
> Wenn also der Aufrufer nichts damit macht, ist es auch sinnlos einen
> Returnwert zurückzuliefern. Einen Returnwert der zurückgeliefert werden
> soll, braucht man auch nicht manipulieren.
> Also ist der ganze Teil
>
>
1
>   if (Richtung==1)    //Richtung wird invertiert
2
>     Richtung=0;     //dass bei jedem längeren Tastendruck
3
>   else              //das Licht heller oder
4
>     Richtung=1;     //dunkler wird
5
>
>
> für die Katz und kann entfallen.


Das Hauptprogramm soll den geänderten Wert eigenlich nur 
"zwischenspeichern" und beim nächsten Funktionsaufruf übergeben.
Anscheinend macht es das aber nicht.
Habe es mal ins main geschoben, das hat leider zur Folge, das die 
Richtung bei jedem Tastendruck geändert wird. Die Richtung soll sich 
aber nur ändern, wenn man vorher "gedimmt" hat. Beim normalen Ein-und 
Ausschalten soll sie sich nicht ändern, damit man nach dem Einschalten 
immer zuerst "hochdimmt". Somit muss das eigentlich in die Funktion und 
zwar so, dass sich das main die "Richtung" merkt und beim nächsten 
Funktionsaufruf die "neue" Richtung übergibt. Aber wie????

>
> PS: Eine Variable kann man auch zwischn 0 und 1 hin und her schalten
> lassen mittels
>
>
1
>    Richtung = 1 - Richtung;
2
>
>
> Ist vielleicht einfacher als dieses if-else Konstrukt


Das habe ich mal ausprobiert, funktioniert super und ist einfacher als 
meine if-then-Prozedur.

Habe den geänderten Code mal angehängt.

Vielleicht hat ja jemand eine Idee.

Danke schonmal

Gruß

Christian

von Christian E. (ultraschall81)


Lesenswert?

Habe gerade noch ein bisschen gegoogelt. Wenn ich die Richtungsänderung 
wieder in die Funktion schiebe und die Funktion folgendermaßen aufrufe, 
sollte es doch funktionieren, oder?

Richtung = pwm_t1a (Richtung) ;

Oder darf der Übergabewert nicht gleich dem Rückgabewert sein???

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.