Hallo,
der Newbie meldet sich auch mal wieder :)
Ich möchte grade einen PWM Übersetzer für einen AtTiny2313 schreiben. An
einem Eingang soll er ein PWM Signal einlesen (Interruptgesteuert) und
soll die Pulsbreite des High-Signals messen und am PWM Ausgang (OC1A) in
Abhängigkeit dieser Pulsbreite ein PWM Signal für eine Motorsteuerung
ausgeben.
Das einlesen der Pulsbreite klappt wunderbar. Der Tiny läuft derzeit auf
internem Oszillator mit 1MHz. Da die PWM am Eingang eine maximale
Pulsbreite von 2ms hat, habe ich den 8Bit Counter0 der die PWM
Pulsbreite zählen soll mit einem Prescaler von 8 zählen lassen.
Nun komme ich zu dem Problem der PWM Generierung.
Ich habe soweit meine Hausaufgaben gemacht, dass ich mich entschlossen
habe eine FastPWM mit Set on Compare Match (also non inverting) auf
Counter1 laufen zu lassen.
Die Anforderungen an mein PWM Ausgangssignal sind: PWM Gesamtlänge 20ms,
Pulsbreite (High) zwischen 0 und 11ms (Pulsbreite je nach
Eingangssignal).
Der Timer hat die Prescaler 8,64,512 und 1024, und das Compareregister
kann entweder 8,9 oder 10 Bit groß sein.
Hab ich das bis hierher erstmal richtig verstanden?!
Wenn ja ist nun meine Frage folgende: welche Frequenz wähle ich nun am
besten aus, um das Ausgangs PWM Signal so exakt wie möglich an meine
Anforderung zu bringen?!.
Ich habe überlegt einen 25MHz Quarz zu benutzen, den Prescaler auf 1024
zu setzen und das 9Bit Compareregister zu nutzen. Damit würde ich dann
eine PWM Pulsbreite von 20,9ms erreichen. Ist das korrekt, oder habe ich
irgendwo einen Denk/Verständnisfehler?!
Stelle ich dann den gesamten AtTiny2313 auf den Takt von 25MHz, oder
hänge ich den Quarz nur an den Clockpin von Counter1?! Was ist
sinnvoller?!
Ich meine, wenn ich den gesamten Tiny auf 25MHz laufen lasse, haut ja
Counter0 mit der EIngangssignalzählung nicht mehr hin richtig?!
Sorry für den langen Post und die Anfängerfragen. Ich will nur kurz
sichergehen, dass ich meine Hausaufgaben auch richtig gemacht habe,
bevor ich Quarze kaufen gehe ;)
vielen Dank schonmal
Um das PWM Signal gut einzulesen wäre die ICP Funktion von Timer 1
ideal. Damit hat man aber bei der Wahl des PWM Kanals ein paar
Einschränkungen: Es geht nur Fast PWM, und PWM-Mode 14 geht auch nicht,
denn der nutzen die ICR Register zum feinen einstellen der PWM Frequenz.
Ein Möglichkeit wäre es 10 Bit fast PWM zu nutzen (WGM Mode 7). Die PWM
Frequenz wird dann durch den Quarz festgelegt. Passend wäre da dann z.B.
Ein Teiler von 64 und ein Takt von 3.2768 MHz.
Der Vorteiler schränkt aber die Genauigkeit ein mit der man das PWM
Signal abtastest. Am flexibelsten wäre WG-Mode 15. Da geht dann
allerdings nicht OC1A, sondern nur OC1B für den PWM Ausgang. Da hat man
mit dem Takt fast freie Wahl und könnte auch den internen 1 MHz Takt
nehmen: Das PWM Signal geht dann bis 20000 Schritte, ohne Vorteiler. Die
PWM Periode kann damit genau 20 ms werden - halt so gut wie der Takt
stimmt.
25 MHz sind einfach zu viel für den µC, auch sollte ein niedrigerer Takt
wie die internen 1 MHz reichen.
Hallo Ulrich, danke erstmal für die Antwort.
Da das einlesen des PWM Signals bisher einwandfrei funktioniert würde
ich das erstmal so lassen wie ich es derzeit habe.
Die Frequenz 3,27MHz hatte ich auch schon ausgerechnet. Ich hab mir eine
Tabelle gemacht um zu schauen, welche Frequenzen ideal sind. Schöner
Wert, aber leider gibts dafür keinen Quarz (jedenfalls nicht da wo ich
immer bestelle).
Einen 6MHz Quarz gäbe es, den ich dann mit nem Prescaler von 256 und dem
9Bit Compareregister verwenden könnte. Dann hätte ich 21,8ms abgedeckt
und würde das in 512 Ticks quantisieren.
20.000 Schritte der Länge 1µs wären natürlich traumhaft, aber wie soll
das gehen?! Um bis zu 20.000 zu zählen brauch ich 15Bit richtig?!
Irgendwie hab ich jetzt das Gefühl, die PWM Generation im µC doch noch
nicht so ganz durchblickt zu haben.
Danke für den Hinweis mit den 25MHz. :)
t0mM3k schrieb:> Die Anforderungen an mein PWM Ausgangssignal sind: PWM Gesamtlänge 20ms,> Pulsbreite (High) zwischen 0 und 11ms (Pulsbreite je nach> Eingangssignal).
Vergiss deine ganze Quarzrechnerei. 20ms. Weisst du, was das für
Ewigkeiten sind? Da hat dein Controller alle Zeit der Welt, das per
Soft-PWM zu erzeugen. Und dann passt das genau.
mfg.
Soft PWM kann man machen, aber nicht so ohne weiteres zusammen mit der
PWM Messung im Interrupt.
Der Timer1 kann aber auch in Hardware PWM mit variabler Periode, bis 16
Bit Breite. Das einzige ist halt das man dazu dann nicht gerade Kanal A
nutzen kann, wenn gleichzeitig noch ICP gehen soll.
Ulrich schrieb:> Soft PWM kann man machen, aber nicht so ohne weiteres zusammen mit der> PWM Messung im Interrupt.
Du kannst das nicht. Für jeden anderen ist das Kinderkram.
mfg.
Richtig, das mit der Soft PWM hab ich schonmal für AtMega8 programmiert
... das war nicht weiter dramatisch. Aber da die Hauptroutine unter
anderem für die Auszählung der Eingangs-PWM genutzt wird, wollte ich
lieber Hardware PWM machen.
Also ich hab nochmal nachgeguckt. Bestelle meine Quarze immer bei
Pollin. Da gibts keinen 3,27MHz Quarz :-/ Wo bestellt ihr eure?!
ICP nutze ich nicht. Ich habe Counter0 mit 1MHz und Prescaler8 starten
lassen, sobald in Interrupt durch eine Rising Edge ausgelöst wird. Wenn
ein Interrupt auf Falling Edge ausgelöst wird, dann stoppt der Timer und
ich zähle die Ticks. 1 Tick = 8µs und ich habe maximal 255 Ticks, also
kann ich sehr gut unterscheiden, ob der Puls 1ms oder 2ms breit war.
Counter1 wollte ich also alleine für den Ausgang nehmen. Wie kann ich
den als 16Bit Counter verwenden? Dann wären ja alle Probleme gelöst :)
Im Datenblatt vom Tiny2313 stehen die 15 PWM Modi ja drin. Da steht dann
immer nur 8 Bit, 9 Bit oder 10Bit.
t0mM3k schrieb:> Im Datenblatt vom Tiny2313 stehen die 15 PWM Modi ja drin. Da steht dann> immer nur 8 Bit, 9 Bit oder 10Bit.
Nö.
Bei Mode 14 und 15 legst du die Auflösung selbst fest.
ICR1 bestimmt in Zusammenhang mit dem Prescaler die PWM-Frequenz.
OCR1A oder B die Pulsbreite. Die geht dann von 0 bis ICR.
Rechne das aus oder spiel solange rum bis das passt.
Den Wert von der Zählung musst du dann entsprechend skalieren.
mfg.
Hi
>Im Datenblatt vom Tiny2313 stehen die 15 PWM Modi ja drin. Da steht dann>immer nur 8 Bit, 9 Bit oder 10Bit.
Mode 14 oder 15. Mit ICR1 bzw. OCR1A bestimmst du den Topwert des
Timers.
MfG Spess
Im Mode 15 legt OCR1A die Periode des PWM Signals und die Auflösung fest
(z.B. 20000 mal 1 µs), und mit OCR1B kann man dann ein PWM Signal
erzeugen. Ein Begrenzung auf 8,9 oder 10 Bit hat man da nicht. Die
Auflösung wird durch OCR1A mit festgelegt und kann bis (fast ?) 16 Bit
gehen.
So viel Auflösung wird man hier nicht brauchen, wenn das Eingangssignal
nur 8 Bit hat, aber stören tut es nicht. Mit ICP könnte man auch zu
einlesen bis 1 Zyklus Auflösung bekommen.
Gleichzeitig Software PWM und das Messen des PWM Signals per IRQ gibt,
wenn auch kleine Störungen beim PWM Signal und ggf. auch beim einlesen
des PWMs. Das Problem ist einfach das der µC nicht 2 Dinge gleichzeitig
machen kann - in der ISR zum Einlesen kann einfach nicht der Ausgang für
Software PWM umgeschaltet werden. Die Auswirkungen kann man klein
halten, aber man kann es nicht ganz vermeiden, wenn die Signale nicht
Synchron sind.
Erst mit merklich höherem Takt kriegt man das beides durch Polling unter
einen Hut - mit 1 MHz Takt aber nicht.
Wenn man zum Einlesen ICP nutzt geht es wohl auch ohne Störungen, ist
aber nicht ganz einfach.