Forum: Mikrocontroller und Digitale Elektronik Atmega8A - PWM Erzeugung - Duty_cylcle - Schleife oder ISR


von Peter A. (elkopeter)


Lesenswert?

Guten Tag in die Runde.
Ich bin noch unerfahren im Bereich Mikrocontroller. Ich bin derzeit 
gerade daran Erfahrungen mit der PWM Erzeugung zu sammeln.
Ich verwende das myAVR board mk2 von Conrad und das atmel studio 6.1 zur 
Programmierung des Atmega.

PWM Signale kann ich bereits an beiden Ausgängen via Timer1 über 
Comparematches und zwei for-Schleifen, die meinen Compare-Wert hoch und 
runterzählen erzeugen. Das soll dann von der Grundschwingung her ein 
Sinussignal bilden.

Jetzt meine Fragen:

Ist die Verwendung von ISR, für die Änderung des Duty_cycle-Wertes, 
performancemäßig bzw. allgemein zu bevorzugen?

Wenn ich den Fast-PWM-Modus und zur Duty-Cycle Einstellung eine ISR 
verwende muss ich dann auch auf Schleifen zurückgreifen für den 
Comparewert oder geht das auch anders? - kann man hier die COM1A0 und 
COM1A1 Befehle nutzen um z.B. von Unterschreiten auf Überschreiten des 
Zähler-Comparewertes zu wechseln?

Wie stelle ich sicher, dass zwischen meinen beiden Ausgangssignalen ein 
gewisser zeitlicher Versatz besteht (z.B. benötigt für die Ansteuerung 
einer H-Brücke)? - Verwendet man hierzu einen delay-Befehl oder wie 
würdet ihr das machen?

von c-hater (Gast)


Lesenswert?

Peter A. schrieb:

> PWM Signale kann ich bereits an beiden Ausgängen via Timer1 über
> Comparematches und zwei for-Schleifen, die meinen Compare-Wert hoch und
> runterzählen erzeugen. Das soll dann von der Grundschwingung her ein
> Sinussignal bilden.

PWM-Signale kann man erzeugen, ohne die MCU überhaupt zu behelligen, das 
können die Timer ganz alleine, indem man sie in einem PWM-Modus benutzt.

Für die Modulation der PWM muß man allerdings die MCU und ein Stück 
Programm bemühen.

> Ist die Verwendung von ISR, für die Änderung des Duty_cycle-Wertes,
> performancemäßig bzw. allgemein zu bevorzugen?

Da der Modulationswert ohehin maximal mit der Geschwindigkeit des 
Timerüberlaufs sinnvoll geändert werden kann: natürlich. Ausnahme wären 
sehr hohe PWM-Frequenzen, bei denen die Rechenzeit nicht mehr reicht, um 
den Interrupt-Overhead zu bewältigen. Spätestens dann MUSS man es als 
busy-Loop implementieren. Oder auch dann, wenn der Chip noch weitere 
schnelle Echtzeit-Aufgaben zu erledigen hat und man die Aufgaben von 
Hand trickreich miteinander verschachteln muß.

Das sind dann allerdings fortgeschrittene Programmiertechniken, ganz 
sicher nichts für Anfänger.

> Wie stelle ich sicher, dass zwischen meinen beiden Ausgangssignalen ein
> gewisser zeitlicher Versatz besteht (z.B. benötigt für die Ansteuerung
> einer H-Brücke)? - Verwendet man hierzu einen delay-Befehl oder wie
> würdet ihr das machen?

Das geht mit einem ATMega leider nur auf drei Arten zu realisieren.

1) Man benutzt zwei Timer. Vorteil: man kann die volle Geschwindigkeit 
der Fast-PWM-Betriebsart nutzen. Nachteile: der zweite Timer steht nicht 
für andere Aufgabe zur Verfügung und es ist nur in Assembler zuverlässig 
möglich, die Timer "synchron" zu starten.

2) Man benutzt einen Timer und seine beiden OCnX-Ausgänge und das in 
einer der langsameren PWM-Betriebsarten (die auf Hoch- und Runterzählen 
basieren). Der Nachteil ist halt, daß man nicht so hohe PWM-Frequenzen 
erreichen kann, sondern nur die Hälfte des mit Fast-PWM möglichen.

3) Man benutzt externe HW-Verzögerungsglieder, um die Lücke zu erzeugen. 
Vorteil: einfach und billich und vereint bezüglich der Timer die 
Vorteile beider oben genannten Optionen. Nachteil: Die Lückenbreite ist 
halt nicht vom Programm aus kontrollierbar. Aber das kann man mit etwas 
mehr (billiger) Hardware auch noch erreichen, 4 Stufen sind mit zwei 
billigen CMOS-Käfern (4030 und 4052) leicht realisierbar.

von Peter A. (elkopeter)


Lesenswert?

Wow danke für die umfangreiche Antwort.
Für das versetzte Schalten würde ich dann Variante 2 und später Variante 
3 bevorzugen, da ich mich mit der Assembler-Programmierung auf dem 
Atmega nicht auskenne und ich zwei PWM Ausgänge benötige.

Allerdings habe ich gerade eine gedankliche Blockade. Wie bewerkstellige 
ich dann das Schalten der einen und der anderen Halbbrücke über die 
beiden OCnx Ausgänge?

Ich kann ja bei der Verwendung des Phase-correct-PWM Modus nur die 
Comareinterrupts verwenden oder? Was muss ich dann in der ISR 
bewerkstelligen?

Setzte ich dann den einen Ausgang in der ISR auf einen Duty-Cycle von 
0%, damit ich nur eine Hälfte der Vollbrücke für die positive Halbwelle 
erzeuge? D.h. wenn ich z.B. einen Sinus mit 50Hz erzeugen will, dann 
Pulse ich die eine Halbrücke mit hoch- und runterlaufendem Comparewert 
für 10ms und die andere entsprechend danach.

Wie inkrementier/dekrementier ich dann den Comparewert in der ISR?
Ich steh grad vom C-Code her aufm Schlauch.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Peter A. schrieb:
> Ich kann ja bei der Verwendung des Phase-correct-PWM Modus nur die
> Comareinterrupts verwenden oder? Was muss ich dann in der ISR
> bewerkstelligen?

Nein, bei Phase Correct PWM ist auch der Timer Overflow Interrupt 
benutzbar und wird gezündet. Das ist ein günstiger Zeitpunkt, um die OC 
Register mit neuen Werten zu beschreiben. Wenn du einen simplen 
Sinusgenerator mit H-Brücke und minimaler Hardware suchst, kannst du dir 
mal mein Projekt mit ATTiny25-85 anschauen:
http://www.schoeldgen.de/avr/
Ganz unten auf der Seite - 'Variable frequency drive with Tiny 25/45/85'

von Peter A. (elkopeter)


Lesenswert?

Matthias Sch. schrieb:
> Peter A. schrieb:
>> Ich kann ja bei der Verwendung des Phase-correct-PWM Modus nur die
>> Comareinterrupts verwenden oder? Was muss ich dann in der ISR
>> bewerkstelligen?
>
> Nein, bei Phase Correct PWM ist auch der Timer Overflow Interrupt
> benutzbar und wird gezündet. Das ist ein günstiger Zeitpunkt, um die OC
> Register mit neuen Werten zu beschreiben. Wenn du einen simplen
> Sinusgenerator mit H-Brücke und minimaler Hardware suchst, kannst du dir
> mal mein Projekt mit ATTiny25-85 anschauen:
> http://www.schoeldgen.de/avr/
> Ganz unten auf der Seite - 'Variable frequency drive with Tiny 25/45/85'

Danke für die Hilfe. Das Projekt sieht super aus. Ich werd mir mal den 
Code anschauen, das hilft mir sicher weiter.

Ich möchte später sowas ähnliches Aufbauen, d.h. Ansteuerung eines 
einphasigen Klauenpolmotors mit einer H-Brücke + Treiber über einen 
Atmel Controller. Die Ausgangsfrequenz möchte ich dann über ein Poti 
einstellen können und diese soll dann über Mux an einer 3-stelligen 
7-Segment-Anzeige angezeigt werden. Außerdem möchte ich wahlweise mit 
der positiven oder negativen Halbwelle den Motor starten. Das soll dann 
über zwei Taster eingestellt werden.
Naja bis dahin ist es noch ein weiter Weg.

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.