www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik viele PWM generieren


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Ich möchte einen PWM-Generator auf Basis eines ATMega169P realisieren. 
Da ich möglichst viele PWM-Ausgänge benötige, die alle auf der selben 
Zeitbasis laufen sollen, wollte ich es über den 16 Bit Timer/Counter 
machen. Die Periodendauer wollte ich über den CTC-Mode einstellen, und 
die Pulsweite an den jeweiligen Ports mit dem Compare Match Interrupt B.

Zweck des ganzen soll sein über die PWM SIgnale "X" LEDs in der 
Helligkeit zu regeln, da sie Produktionstechnisch geringfügigen 
Schwankungen in der Helligkeit unterliegen.

Das Problem an der Sache ist, dass einige PWM-Werte nah aneinander 
liegen könnten. Somit muss ich bei bestimmten (Timer)Interruptevents 
mehrere Pins gleichzeitig Low schalten, da sonst der TImer ein weiteres 
Mal umlaufen müsste bis er das nächste Interruptevent auslöst.

Nun wollte ich mal fragen wie ich das am besten anstelle. Habe noch 
nicht viel Erfahrung mit Mikrocontrollern. Ich würde das ganze gerne in 
C entwickeln.

Danke schonmal im Voraus für Vorschläge
mit freundlichem Gruß Christian

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieviele Leds?
Wie sind sie an den Controller angeschlossen?


CTC Modus. Hmm. Ich sehe noch nicht ganz, wie dir der CTC
Modus da helfen kann. CTC ist super wenn es um 1 Frequenz-
generierung geht (meinetwegen auch 1 PWM). Aber viele davon.

Software-PWM.
Einen Timer im Overflow Modus (oder meinetwegen auch CTC
Modus wenn es ein 16 Bit Timer sein soll) laufen lassen
und über den Interrupt dann die einzelnen PWM Kanäle
abwickeln.
Vom Prinzip her, so wie hier:
http://www.mikrocontroller.net/articles/AVR-Tutori...

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal für die schnelle Antwort ;)

Die Anzahl der LED's soll theoretisch das Maximum an freien IO-Pins 
betragen.
Sie werden wohl über Treibertransistoren + Vorwiderstand betrieben.
Später soll noch ein ADC ein USART und ne Tastaturmatrix-Auswertung 
integriert werden.
Den CTC-Modus wollte ich verwenden um bei einem 8 MHz Quartz die 
Periodendauer auf 5ms zu setzen. (TCtop = (XTAL/1000)*5) Das schwierige 
an der Sache ist nun, dass alle PWM auf der selben Zeitbasis betrieben 
werden sollen... ( aus dem Grund muss ich dann die PWM-Werte der Größe 
nach aufsteigend in einem Array sortieren.) Wenn nun aber mehrere 
gleiche PWM-Werte benötigt werden, muss mann es irgendwie hinbekommen, 
dass dann auch alle mit dem gleichen Wert zu Zeitpunkt X auf LOW gesetzt 
werden und zusätzlich der nächst größere Wert für den nächsten Interrupt 
in das Compare-Register geladen wird. Und da ich die Zeitbasis nicht 
verändern darf muss ich den TC während der ISR weiterzählen lassen. Was 
dazu führen kann, das auch schon nahe beieinander liegende  Werte nicht 
mehr richtig verarbeitet werden.

mfg Christian

Autor: Johannes G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hatte vor kurzem auch ein Problem mit Software PWM.. Aber nun geht 
es ;)
Hier der Code: Beitrag "Re: Software PWM Problem"
Damit kannst du eigentlich (je mach PWM Frequenz) beliebig viele PWMs 
generieren.
Solltest du Fragen zum Code haben: Frag einfach ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian wrote:
> Danke erstmal für die schnelle Antwort ;)
>
> Die Anzahl der LED's soll theoretisch das Maximum an freien IO-Pins
> betragen.

Wieviele sind das ungefähr. 5, 10, 20, 100

> Den CTC-Modus wollte ich verwenden um bei einem 8 MHz Quartz die
> Periodendauer auf 5ms zu setzen. (TCtop = (XTAL/1000)*5) Das schwierige
> an der Sache ist nun, dass alle PWM auf der selben Zeitbasis betrieben
> werden sollen... ( aus dem Grund muss ich dann die PWM-Werte der Größe
> nach aufsteigend in einem Array sortieren.)

Kann man so machen. Muss man aber nicht.
volatile uint8_t PWM1, PWM2, PWM3, PWM4;
uint8_t PWMCount;

ISR( TIMER0_OVF_vect )    // Overflow im Timer 0
{
  PWMCount++;

  if( PWM1 > PWMCount )
    // Led1 ein
  else
    // Led1 aus

  if( PWM2 > PWMCount )
    // Led2 ein
  else
    // Led2 aus

  if( PWM3 > PWMCount )
    // Led3 ein
  else
    // Led3 aus

  if( PWM4 > PWMCount )
    // Led4 ein
  else
    // Led4 aus
}

Den Timer 0 mit Volldampf laufen lassen, den Overflow Interrupt
einschalten und gut ists.
Durch Zuweisen von Werten von 0 bis 255 an PWM1 .. PWM4
kannst du jede LED einzeln dimmen.

Autor: Johannes G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:P ich war eine minute schneller

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Start:

    Wert aus Timer auslesen
    mit allen Grenzwerten vergleichen und die Vergleichsergebnisse in 
Bitpatterns schieben
    alle bitpatterns direkt hintereinander an die Ports senden

und zurück


Du kannst damit zwar nicht die vollen 16-Bit Auflösung auskosten (10 
oder 11 Bits maximal bei 30 Kanälen) und dein Programm hat auch nicht 
mehr viel Freizeit vorzuweisen, funktionieren tut das aber wunderbar.

Mit Assembler und einiges an Arbeit gehen auch volle 16 Bits bei 60 
Kanälen am ATMega16 (2x multiplex) und der hat noch einiges an Zeit 
übrig. Ansonsten reichen die obigen Programme auch für gute Ergebnisse.

Siehe auch: Beitrag "Philosophiestunde Konstantstromquelle"

Gruß

Kai

ps: nicht zu vergessen Soft-PWM

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmals danke für die fixen Antworten .. ( echt der Hammer dieses Forum 
)

hmm also ein TC generiert dann sozusagen die ganze Zeit Interrupts und 
in der Routine werden dann einfach seriell alle PWM ausgewertet .....

Mir ist nur noch nicht ganz klar aus welchen Einstellungen sich dann die 
Periodendauer ergibt. Und zusätzlich sind die PWM Werte dann ja 8Bit von 
der Auflösung sozusagen ti zwischen 0x00 bis 0xFF. Das müsste sich ja 
dann auch auf 16 Bit ummünzen lassen oder ?

mfg Christian

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Mir ist nur noch nicht ganz klar aus welchen Einstellungen sich dann die
>Periodendauer ergibt.

Die PWM-Frequenz ist CPU-Takt geteilt durch Counter-Limit durch Anzahl 
der Takte pro Counter-Inkrement. Beispiel:
- CPU-Takt 16 MHz
- Counter-Limit bei 65536
- 1 Takt pro Inkrement
PWM-Frequenz = 16000000 Hz / 65536 / 1 = 244,1 Hz
Periodendauer = 1 / PWM-Frequenz = 4,096 ms
Takte pro Periode = Counter-Limit * Takte pro Inkrement = 65536

>Und zusätzlich sind die PWM Werte dann ja 8Bit von
>der Auflösung sozusagen ti zwischen 0x00 bis 0xFF. Das müsste sich ja
>dann auch auf 16 Bit ummünzen lassen oder ?

Die Frage verstehe ich irgendwie nicht...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian wrote:

> der Auflösung sozusagen ti zwischen 0x00 bis 0xFF. Das müsste sich ja
> dann auch auf 16 Bit ummünzen lassen oder ?

Vom Prinzip her: ja.
Aber ehe du jetzt losjubelst solltest du erst mal deinen
Taschenrechner anwerfen und ausrechenen, was dir dann noch
als PWM Frequenz übrig bleibt.

Ausserdem: Eine noch feinere PWM wirst du nicht brauchen.
Selbst wenn du nur 64 PWM Stufen hast, dann sind die Helligkeits-
abstufungen im hellen Bereich bereits so fein, dass man von
einer Stufe zur nächsten kaum noch einen Unterschied merkt.
Richtig brutal sind diese Stufen aber im dunklen Bereich.
Da du aber sowieso nur mehrere Leds in der Helligkeit angleichen
willst, ist das für deine Zwecke perfekt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian wrote:
> Mir ist nur noch nicht ganz klar aus welchen Einstellungen sich dann die
> Periodendauer ergibt.

Ich gehe jetzt mal von der primitiven Overflow Methode aus:

Was muss denn alles passieren, bis der PWM Counter in meinem
Beispiel einmal rum und wieder bei 0 angelangt ist? Denn dann
hat er genau einen PWM Zyklus hinter sich gebracht.

Nun der Timer muss einmal durchzählen.
Und der PWM Counter muss einmal von 0 bis 255 durchgezählt
haben.

Wie schnell zählt der Timer?
So schnell wie der CPU Takt vorgibt, geteilt durch den eingestellten
Vorteiler.
Wenn der Timer also einmal rum ist, erfolgt ein Overflow.
Und es muessen 256 Overflows erfolgen, damit der PWM Counter
einmal rumgeht.

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es dir wirklich nur um einen Angleich der Helligkeiten von 
einfarbigen LEDs geht und du nicht dimmen willst reichen 8 bit-Stufen 
auf jeden Fall. Probier's einfach mal aus.

Der Unterschied zwischen den hellsten beiden Stufen beträgt bei 8 Bit 
Auflösung für das Auge nur noch schlappe 0,18 %

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Kai Giebeler (runtimeterror)

>Mit Assembler und einiges an Arbeit gehen auch volle 16 Bits bei 60
>Kanälen am ATMega16 (2x multiplex) und der hat noch einiges an Zeit
>übrig.

Was ich nach wie vor bezweifle . . .

MFg
Falk

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hehe... da isser wieder ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.