Forum: Compiler & IDEs PWM - Dringende Hilfe


von PWMmann (Gast)


Lesenswert?

Hallo Leute!

Ich habe mir als Aufgabe gestellt, eine einzige LED, welche an den PIN 
OC/0 angeschlossen ist (PIN-B 3) mittels PWM die Helligkeit in zwei 
Stufen zu regeln.
Einfach nur die LED folgendermaßen schalten:

Ganz hell -> warte x Zeit -> Halb hell ....und wieder von vorne....
Es funktioniert aber nicht :(

Hier mein Code:

//--------------------------------------------------------------------
#include <iom16.h>
#include <intrinsics.h>


int main (void)
{
  for(;;)
  {
    DDRB_DDB3 = 1;     //LED-Ausgang
    TCCR0 = (1<<WGM01|1<<WGM00|0x02<<COM00|0x04<<CS00);     //Fast-PWM
    OCR0 = 128;                                             //PWM 
High-Low-Verhältnis
    __delay_cycles(16*15000000ul);
  }

}




Vielen dank

von Johannes M. (johnny-m)


Lesenswert?

1.: iom16.h wird nie direkt eingebunden. Immer nur die io.h einbinden 
und den Controllertyp im Makefile einstellen.

2.: Eine intrinsics.h gibt es in der AVR-libc nicht.

3.: Du änderst nirgends das Tastverhältnis.

4.: Ich hab die Priorität der Operatoren jetzt nicht im Kopf, aber die 
Klammerung in der Zeile, in der Du TCCR0 beschreibst, solltest Du Dir 
nochmal durch den Kopf gehen lassen.

5.: ...tbc...

von PWMmann (Gast)


Lesenswert?

also es ist folgendermaßen: Wir haben zur zeit einen C-Kurs für AVR, wo 
wir ein Programm namens IAR nutzen. Dieses Programm hat verschiedene 
header, die die avrlibc nicht unterstützt. Ich kann es ja mal kurz 
umschreiben, damit es für AVR studio verständlich ist.

Wie ändere ich dann das Tastverhältnis? Du kannst mir gerne auch den 
Code in AVR studio standard schreiben, ich komme damit eh besser zurecht 
als mit dem komischen IAR.


Danke!

von Antworter (Gast)


Lesenswert?

Ohne dass ich die PWM beim AVR kenne....

Ich sehe nirgends, dass Du in Deiner Loop die PWM änderst
pro Durchlauf. Also wie sollte sich da die Helligket ändern?

Joachim

von PWMmann (Gast)


Lesenswert?

Kann mir jemand dann bitte mal einen BeispielCode für mein Vorhaben 
schreiben?


Einfach eine LED 2 sec. Hell, 2 sec. dunkel, die an den OC/0 
angeschlossen ist.


Danke!

von Johannes M. (johnny-m)


Lesenswert?

PWMmann wrote:
> Wie ändere ich dann das Tastverhältnis?
Du solltest Dir dringendst die Funktionsweise der Timer und 
Compare-Einheiten anschauen, z.B. im AVR-Tutorial oder im 
AVR-GCC-Tutorial bzw. unter AVR-Tutorial: PWM und/oder 
AVR PWM.

> Du kannst mir gerne auch den
> Code in AVR studio standard schreiben,
AVRStudio hat nichts mit C zu tun. Vermutlich meinst Du den 
AVR-GCC-Compiler bzw. WINAVR. Und mit den Informationen auf dieser Seite 
solltest Du auch selbst nach kurzer Zeit in der Lage sein, 
herauszufinden, was Sache ist. Es ist sicherlich nicht Sinn eines 
C-Kurses, Dir von anderen Leuten Code schreiben zu lassen.

Für Warteschleifen muss übrigens noch die util/delay.h eingebunden 
werden. Außerdem gibt es da keine Funktion "__delay_cycles".

von PWMmann (Gast)


Lesenswert?

Habe jetzt folgendes Programmiert:



#include <iom16.h>
#include <intrinsics.h>


int main (void)
{
DDRB_DDB3 = 1;

  TCCR0 = (1<<WGM00|1<<COM01|1<<CS02|1<<CS00);
  PORTB_PORTB3 = 1;
  OCR0 = 128;

}


Aber die LED flackert noch sehr schnell und nicht im sekunden Takt.
Wie kann ich (da ich den Prescaler schon auf 1024 gestellt habe) die 
Frequenz noch verringern?

Danke

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

PWMmann wrote:

> Wie kann ich (da ich den Prescaler schon auf 1024 gestellt habe) die
> Frequenz noch verringern?

Das geht mit einem 8-Bit-Zähler nicht.  Der hat per definitionem
eine Zählweite von 256, sodass die Frequenz minimal 1/256 Ki des
CPU-Takts sein kann, bei 1 MHz CPU-Takt also ca. 4 Hz.

Bist du dir sicher, dass du richtig verstanden hast, wie eine PWM
funktioniert?  Normalerweise ist es nicht das Ziel, die PWM-Frequenz
so niedrig wie möglich zu machen, denn diese stellt nur eine
Hilfsfrequenz dar.

Du kannst dir das einfache Demo der avr-libc mal angucken, dort wird
eine LED in der Helligkeit auf- und abgesteuert:

http://www.nongnu.org/avr-libc/user-manual/group__demo__project.html

Da du im GCC-Forum gefragt hast, musst du wohl oder übel damit leben,
dass die Antworten GCC-spezifisch sind.  Die IAR-Anpassung musst du
selbst vornehmen, die sollte aber so schwer nicht sein.  Du musst das
Beispiel ohnehin auf den von dir gewünschten Timer 0 umschreiben.

von PWMManni (Gast)


Lesenswert?

Kann das sein, dass durch das von mir oben genannte Programm 
Fuse-/Lockbits gesetzt werden??

Denn nun habe ich keinen Zugriff mehr auf mein Board :-( (serielle 
Schnittstelle) über den PonyProg


Danke

von Johannes M. (johnny-m)


Lesenswert?

PWMManni wrote:
> Kann das sein, dass durch das von mir oben genannte Programm
> Fuse-/Lockbits gesetzt werden??
Nö. Kein Programm ist in der Lage, Fusebits zu setzen. Die 
Programmierung der Fusebits ist unabhängig vom Programm. Wenn Du die 
Fusebits nicht explizit programmiert hast, dürfte sich da nichts 
geändert haben.

von PWMmanni (Gast)


Lesenswert?

Hallo!


Ich habe jetzt den ganzen heutigen Tag nur vor dem Datenblatt des 
ATmega8 gesessen und komme einfach nicht auf einen grünen Zweig.

Ich würde mich wirklich sehr freuen, wenn mir jemand wenigstens einen 
Ansatz für meine einzige LED, die an PB3 angeschlossen ist, gibt, um sie 
abwechselnd heller und dunkler leuchten zu lassen.
Es klappt einfach Nix!

Vielen dank!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Zeig doch mal bitte deinen Code, den du aus dem avr-libc-Demo
geschneidert hast.

von PWMmanni (Gast)


Lesenswert?

#include <avr/io.h>




int main ()
{


TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1);
TCCR1B = (1<<CS10);  // Vorteiler von 1024
OCR1A = 128; // Vergleichswert
DDRB |= (1<<PB3);
}

von PWMmanni (Gast)


Lesenswert?

sry in meinem geschriebenen Code ist der Prescaler-Kommentar falsch.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich hatte dich darum gebeten, dir das avr-libc-Demo vorzunehmen und
dieses anzupassen.  Wenn du mit ,,nichts will funktionieren'' nur
deinen eigenen (völlig unzulänglichen) Experimente meinst und entweder
nicht gewillt oder in der Lage bist, dir auch mal was anderes anzusehen
und für deine Zwecke anzupassen (damit du wenigstens überhaupt
verstehst, wie die PWM denn funktionieren soll), sorry, dann ist
dir nicht zu helfen.

Wir sind doch kein Verein zum Lösen irgendwelcher Hausaufgaben.

von Falk B. (falk)


Lesenswert?

@  PWMmanni (Gast)

>Ansatz für meine einzige LED, die an PB3 angeschlossen ist, gibt, um sie
>abwechselnd heller und dunkler leuchten zu lassen.

Soft-PWM

Sogar wesentlich mehr als du brauchst.

MFG
Falk

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Solange er noch nicht verstanden hat, dass die PWM eine Art DAC
ist und dass deren Frequenz nicht seine Blinkfrequenz ist,
brauchst du glaub ich nicht mit Soft-PWM anfangen...

von PWMmanni (Gast)


Lesenswert?

Es ist doch immer wieder schön, wie freundlich einem in dem Forum 
geholfen wird.

Vielen Dank!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Es wird dir freundlich geholfen, wenn du einen wenigstens minimalen
Anteil an Eigeninitiative zeigst.  Wenn du aber nach einem ganzen
Tag mit X Postings und Y Leuten, die sich mit dir befassen, noch
nichtmal ein winziges Stückchen weiter gekommen bist mit deinem
Verständnis, was sollen wir dann noch tun?

Vielleicht beginnst du einfach erstmal, dir das AVR-Tutorial dieser
Seite durchzuarbeiten um zu wissen, was die PWM überhaupt macht und
wie sie funktioniert?  Wenn du denn deine LED vorübergehend nochmal
an einen anderen Pin klemmen kannst, kannst du auch das PWM-Demo
der avr-libc 1:1 ausprobieren und zu verstehen versuchen.  (Dort
wird der Timerkanal 1 statt 0 benutzt.)  Wenn du dir nicht erst ein
WinAVR/AVR-GCC installieren willst, hier das Hexfile für einen
ATmega16:

:100000000C942A000C9447000C9447000C94470071
:100010000C9447000C9447000C9447000C94470044
:100020000C9449000C9447000C9447000C94470032
:100030000C9447000C9447000C9447000C94470024
:100040000C9447000C9447000C9447000C94470014
:100050000C94470011241FBECFE5D4E0DEBFCDBF16
:1000600010E0A0E6B0E0EEE3F1E002C005900D92F2
:10007000A036B107D9F710E0A0E6B0E001C01D92AC
:10008000A336B107E1F70E9494000C949E000C94F3
:1000900000001F920F920FB60F9211242F933F93DF
:1000A0008F9380916000882339F08130B9F02091DE
:1000B00061003091620021C02091610030916200A6
:1000C0002F5F3F4F309362002093610083E02F3F0A
:1000D000380799F481E0809360000FC0209161009F
:1000E00030916200215030403093620020936100D3
:1000F0002115310511F4109260003BBD2ABD8F918E
:100100003F912F910F900FBE0F901F90189583E88D
:100110008FBD8EB581608EBD1BBC1ABC80E281BBD9
:1001200084E089BF789408950E94870085B7806431
:0E01300085BF889585B78F7B85BFF8CFFFCF41
:00000001FF

Die LED muss dabei an PD5 angeschlossen werden (OC1A).

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.