Forum: Compiler & IDEs PWMs mit AT90PWM316


von Rachid (Gast)


Lesenswert?

Hallo,

ich möchte mit einem at90pwm316 µC drei fast PWMs ausgeben, von denen 
ich das Dutycicle im Programm einzeln verändern kann. Die Frequenz der 
PWMs soll bei allen drei gleich sein.
Ich habe schon sehr lange versucht es alleine hinzubekommen und bin zu 
keinem Ergebniss gekommen. Ich habe auch Beispielprogramm gefunden, das 
mir weiter helfen konnte. Mein einziger Fortschritt ist es, dass ich es 
geschafft habe ein eine Fast PWM zu erzeugen.
Ich wäre euch für jede Hilfe dankbar, die ihr mir geben könnt.

Viele Grüße,

Rachid

von Rachid E. (rachid_e)


Angehängte Dateien:

Lesenswert?

Ich hab mal meinen Code eingefügt, mit dem ich versucht habe zwei PWMs 
raus zu bekommen. Vielleicht kann mir einer helfen und sagen, was bei 
mir falsch ist. Ich habe versucht als zu machen, was im Datenblatt 
steht.
Ich währe euch sehr Dankbar für eure Kommentare. Ich komme alleine 
leider nicht weiter.

von Karl H. (kbuchegg)


Lesenswert?

> void timer_init(void)
>    {
>
>      sei();

einen sei macht man erst dann, wenn alles fertig eingerichtet ist.
Also alle Hardwarekomponenten sind konfiguriert, alle Variablen haben 
ihre initialien Werte. Am besten kommt der sei in main() und zwar als 
letzte Anweisung vor die obligate Hauptschleife

>      SREG |= 0b10000000;

Das SREG lässt du mal schön in Ruhe. Dieses Register geht dich nichts 
an. Darum kümmert sich der Compiler bzw die Funktionen sei() und cli()


>      TCCR0A |= ((1<<COM0A1) | (1<<COM0A0) | (1<<COM0B1) | (1<<COM0B0) |
(1<<WGM01) | (1<<WGM00)); //COM0A1 COM0A0 COM0B1 COM0B0 – – WGM01 WGM00

Schau: Der Kommentar hier bringt dir genau gar nichts.
Was ist an dieser Stelle für den Leser des Codes interessant:
Welcher Modus wird am Timer eingestellt und wie schnell soll der Timer 
laufen. Auch was du mit den Ausgangspins vor hast. Sollen die vom Timer 
geschaltet werden? Wenn ja wie?

Das sollst du kommentieren.
Wenn du ganz lieb bist, dann schreibst du eventuell noch im Kommentar 
dazu, aufgrund welcher Tabelle im Datenblatt (Seitenangabe) du die 
Einstellung gemacht hast. Dann kann jemand anderer (oder du) das 
schneller verifizieren, ob du da irgendwo einen Fehler gemacht hast.

>      TCCR0B |= ((0<<WGM02) | (1<<CS02) | (1<<CS01) | (1<<CS00)); //FOC0A FOC0B – 
– WGM02 CS02 CS01 CS00 letzten drei Bits für den Teiler

>      TIFR0 |= ((1<<OCF0B) | (1<<OCF0A) | (1<<TOV0));
kann man machen. muss man aber nicht. In deinem speziellen Fall sind 
keine INterrupts beteiligt. Der Timer erzeugt die PWM ganz von alleine. 
Man muss ihm da nicht mit einem Interrupt unter die Arme greifen.

>Y      TIMSK0 |= ((1<<OCIE0B) | (1<<OCIE0A) | (1<<TOIE0));

No. Man gibt keine Interrupts frei, für die man keine Handler-Funktion 
hat. Niemals!
Du brauchst ausserdem keine Interrupts. Der Timer erzeugt die PWM ganz 
alleine. Völlig ohne Hilfe einer Interrupt-Funktion.


>    }

> void timer_interrupt(void)

So geht das nicht. Du kannst nicht einfach eine Funktion hernehmen und 
glauben, die würde Interrupts behandeln. Eine Interrupt Funktion muss 
einen speziellen Aufbau/Namen haben.

Aber wie gesagt: Du brauchst sie gar nicht.

AVR-GCC-Tutorial

von Rachid E. (rachid_e)


Angehängte Dateien:

Lesenswert?

Vielen Dank, dass du mir so unter die Arme greifst. Ich habe versucht 
den Code etas übersichtlicher zu Machen.

Der µC soll erstmals die zwei PWMs am Ausgang ausgeben. Ich werde mit 
den Ausgängen später einen Treiber ansteuern. Jetzt habe ich an den 
Ausgängen OC0A und OC0B eine Oszilloscope angeschlossen. Die Frequenz 
mit der die PWMs laufen sollen, steht noch nicht fest. Sie soll dann im 
kHz-Bereich liegen. Mit diesem Code bekomme ich an den Ausgängen noch 
kein Signal raus.

von Rachid E. (rachid_e)


Lesenswert?

Ich muss mich korrigieren: OC0A liefert ein PWM Signal (4 kHz) doch OC0B 
liefert eine Dreiecksspannung mit einer Frequenz von 16MHz 
(Quartzfrequenz).

von Karl H. (kbuchegg)


Lesenswert?

Deine Timer Initialisierung ist jetzt nachvollziehbar und schaut gut 
aus.

Das hier
  DDRE = DDRE&0x2;  //OC0B
schaltet allerdings keinen Pin auf Ausgang.

  DDRE = DDRE | 0x2;  //OC0B


laut Simulator müüstesst du an PD3 das Signal vom A-Kanal des Timers 
schon sehen (den Pin hast du richtig auf Ausgang gesetzt). UNd mit der 
Änderung müsste auch an PE1 das PWM-Signal vom B-Kanal vorhanden sein.
Im Simulator zumindest ist es da.

von Rachid (Gast)


Lesenswert?

Vielen Dank, ich bin dir echt dankbar. Das hat jetzt super geklappt. Ich 
brauche wohl noch eine Weile bis ich es selber drauf hab.

Viele Grüße,

Rachid

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.