Forum: FPGA, VHDL & Co. 8fach PWM Output mit Xilinx FPGA


von Martin K. (mkohler)


Lesenswert?

Hallo zusammen,
Ich will auf einem bestehenden Digital IO Board (Eigenentwicklung) die 8 
digitalen Ausgänge mit PWM ausrüsten.
Bisher können die Outputs per Register ab Mikrocontroller nur ein- und 
ausgeschaltet werden (diese Funktion wird auch beibehalten).

Ich bin mir nun nicht ganz sicher, welchen der beiden Ansätze ich 
implementieren soll, deshalb skizziere ich die Varianten mal in 
Stichworten.

beide Varianten:
- 8Bit PWM-Einstell-Register pro Kanal/Output, so dass insgesamt 256 
PWM-Stufen eingestellt werden können.
- Register=0x00 -> Output=0, Register=0xFF -> Output=1
- Registerwerte 0x00..0xFF stellen Duty Cycle des PWM Signals ein
- Periodendauer des Signals bleibt konstant, ist noch zu definieren
- dem PWM-Signal wird das bisherige ON/OFF Singal nachgeschaltet 
(AND-verknüpft)
- PWM Clock als Mass für einen Auflösungsschritt, Periodendauer des 
PWM-Singals = 256 PWM Clocks

Nun die Ansätze zur Erzeugung der PWM Signale:
Ansatz 1:
- übergeordneter 8Bit Down Counter für alle 8 Outputs, Underrun auf 0xFF
- noch je ein separater PWM Counter pro Output
- Preload aller PWM Counter mit PWM Registerwert bei Underrun des 
übergeordneten Counters
- Output ist eingeschaltet, wenn der Zählerwert != 0 ist
- auf jeden PWM Clock werden alle Zähler dekrementiert
- PWM Counter bleiben bei Erreichen von 0 stehen, Output wird 
ausgeschaltet

Ansatz 2:
- übergeordneter 8Bit Down Counter für alle 8 Outputs, Underrun auf 0xFF
- je ein 8Bit Komparator pro Output
- Einschalten des Outputs, sobald der Counter gleich dem PWM 
Registerwert ist
- Ausschalten des Outputs bei Underrun des Counters

Ich tendiere eher zu Ansatz 2, weil da nur 1 Counter plus 8 Komparatoren 
benötigt werden, (9 Counter bei Ansatz 1).
Das Problem bei beiden Ansätzen sehe ich jedoch noch darin, dass das 
Signal bei Einstellung von 0xFF auf tatsächlich konstant auf 1 bleibt 
und nicht einen 0-Impuls enthält wenn der Counter 0 ist.

Frage: Welchen Ansatz würdet ihr wählen, resp. gibt es noch eine 
schlauere Variante?
Wie lässt sich das 0-Impuls Problem lösen?
Hat evtl. jemand einen copyright-freien Code-Ausschnitt, von dem ich 
"abkupfern" könnte?

Danke für die Antworten!
Gruss, Martin Kohler

Nachtrag: Der Systemclock beträgt 48MHz, bei direkter Verwendung dieses 
Clocks als PWM Clock käme ich auf eine minimale PWM Periodendauer von 
5.33us resp einer PWM Frequenz von 187.5kHz

von Morin (Gast)


Lesenswert?

Kannst du den Master-Counter bei underrun auf 0xFE statt 0xFF setzen? 
Damit müsstest du den 0-Impuls weg kriegen. Dann wäre eine Periode dann 
255 Clocks lang und der 1-Puls wäre der Registerwert in Clocks, also 
auch max. 255.

Ansonsten hast du das Grundsätzliche Problem dass du eine Periode von 
256 Clocks hast und die Pulsdauer von 0 bis 256 variieren willst, was 
insgesamt 257 verschiedenen Werten entspricht und daher nicht in ein 
Byte-Register passt.

von Martin K. (mkohler)


Lesenswert?

Morin wrote:
> Ansonsten hast du das Grundsätzliche Problem dass du eine Periode von
> 256 Clocks hast und die Pulsdauer von 0 bis 256 variieren willst, was
> insgesamt 257 verschiedenen Werten entspricht und daher nicht in ein
> Byte-Register passt.

Missverständnis!
Die Pulsdauer soll von 0x01 = 1 Clock eingeschaltet bis 0xFF = 255 
Clocks eingeschaltet variieren, 0x00 heisst immer ausgeschaltet, die 
Pulsdauer von 255 heisst immer eingeschaltet.
Insgesamt also schon die 256 Zustände (2^8) mit 8Bit Register.

von Martin K. (mkohler)


Lesenswert?

Morin wrote:
> Kannst du den Master-Counter bei underrun auf 0xFE statt 0xFF setzen?
> Damit müsstest du den 0-Impuls weg kriegen. Dann wäre eine Periode dann
> 255 Clocks lang und der 1-Puls wäre der Registerwert in Clocks, also
> auch max. 255.
Du empfiehlst also eher Ansatz 2?

Weitere Meinungen? (gerne auch mit Code-Vorschlag.... ;-)

von Falk B. (falk)


Lesenswert?

@ Martin Kohler (mkohler)

>Die Pulsdauer soll von 0x01 = 1 Clock eingeschaltet bis 0xFF = 255
>Clocks eingeschaltet variieren,

Dann musst du aber einen Zähler mit nur 255, statt 256 Schritten haben.

Also 0,1,2,...254,0,1,2

MFG
Falk

von Kai G. (runtimeterror)


Lesenswert?

Deine Aussagen

>- PWM Clock als Mass für einen Auflösungsschritt, Periodendauer des
>PWM-Singals = 256 PWM Clocks

und

>Pulsdauer von 255 heisst immer eingeschaltet.

ergeben in meinen Augen einen Widerspruch. Bei 255 sind nur 255 von 
256 Takten an. Das ist meines Wissens nach aber auch üblich...

Oder habe ich das was missverstanden?

Wenn es nicht unbedingt PWM sein muss, und es dir nur um den Duty-Cycle 
geht, habe ich evtl. eine für den FPGA einfachere Lösung anzubieten 
(nicht ganz so meine Domäne).

Gruß

Kai

von Rick Dangerus (Gast)


Lesenswert?

@Martin:

Um Code zu finden hilft vielleicht:
http://www.google.com/codesearch?q=lang%3Avhdl+pwm

Rick

von Morin (Gast)


Lesenswert?

Ich hätte jetzt Ansatz 1 genommen, denke aber das ist Geschmackssache 
bzw. hängt im Detail davon ab ob dich ein Mux oder ein Comparator teurer 
zu stehen kommt.

von Martin K. (mkohler)


Lesenswert?

Morin wrote:
> Ich hätte jetzt Ansatz 1 genommen, denke aber das ist Geschmackssache
> bzw. hängt im Detail davon ab ob dich ein Mux oder ein Comparator teurer
> zu stehen kommt.

Woher MUX? Im Fall 1 brauche ich pro PWM Kanal einen Counter, im Fall 2 
je einen Komparator auf Gleichheit.

von Falko (Gast)


Lesenswert?

Du willst die PLL doch sicher auch pulsen und abschalten, oder? Dann hat 
sich das 1-Problem doch gelöst.

von Martin K. (mkohler)


Lesenswert?

Falko wrote:
> Du willst die PLL doch sicher auch pulsen und abschalten, oder?
Es geht um PWM.

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.