Hi,
ich sitze gerade an einem Projekt bei dem ich einen Schrittmotortreiber
mittels PWM ansteuern möchte.
Dazu habe ich verschiedene Modi des Timer 1 eines AT90USB162
ausprobiert. Bisher ist es mir allerdings nur gelungen den Modus 15
(fast PWM) zum Laufen zu bekommen. Nach dem ich das Datenblatt nochmal
genau gelesen habe, erscheint mit der Modus 11 für meine Zwecke
sinnvoller.
Folgende Einstellungen habe ich vorgenommen
Wenn ich das richtig verstanden habe, dann sollte der Timer1 von 0x0000
(BOTTOM) bis zu dem von OCR1A gegebenen Wert zählen. Dabei sollte PIN C6
HIGH sein. Wird OCR1A (TOP) erreicht, dann sollte PIN C6 LOW werden und
der Timer sollte rückwärts auf 0x0000 zählen.
Bei erreichen des TOP-Wertes kann der Compare Match A Interrupt
ausgelöst werden. Bei erreichen des BOTTOM-Wertes kann der Timer1
Overflow ausgelöst werden. Beide Interrupts bräuchte ich für mein
Programm.
Ich habe ein Oszi an den Pin angeschlossen und festgestellt, dass der
PIN C6 lediglich HIGH-Pegel hat. Ändere ich
dann funktioniert die PWM. Allerdings nicht mit der angedachten
Frequenz, aber immerhin mit einem Tastverhältnis von 1:1.
Habe ich da etwas falsch verstanden? Wie sollte der WGM Modus 11 denn
sonst funktionieren?
Hat jemand schonmal diesen Modus genutzt?
Wozu gibt es dann die Optionen aus Tabelle 15-3 auf Seite 130 des
Handbuchs?
"Clear OCnA/OCnB/OCnC on compare match up-counting. Set OCnA/OCnB/OCnC
on compare match when downcounting"
bzw. invers, also setzen bei compare match beim hochzählen (sprich
BOTTOM matched -> Timer Overflow Interrupt wird ausgelöst -> Pin wird
gesetzt) und rücksetzen bei compare match (sprich TOP matched -> Compare
Match A Interrupt wird ausgelöst -> Pin wird zurückgesetzt) beim
runterzählen.
Hast du das mal ausprobiert?
Ich habe beide Interrupt, also Timer Overflow und Compare Match A
aktiviert. Habe Breakpoints in beiden Interruptroutinen gesetzt und weiß
daher, dass Timer Overflow direkt beim starten ausgelöst wird, was ja
Sinn macht, da TCNT1 am Anfang 0 enthält und somit BOTTOM matched.
Leider scheint das Debugging beim AVR Studio 5 noch nicht richtig
ausgereift zu sein. Setze ich in beiden InterruptHandlern einen
Breakpoint, dann wird immer nur einer angesprungen. Lösche einen
beliebigen, wird der noch vorhandene angesprungen ...
Also nochmal für mich zum richtigen Verständnis:
Phase-correct PWM im Modus 11 bedeutet laut Datenblatt, dass der Timer
von 0x0000 bis zum Wert in OCR1A hochzählt. Der Wert in OCR1A muss
mindestens 0x0003 betragen. Hat er den Wert erreicht, dann wird der
Compare Match A Interrupt ausgelöst und der Timer zählt rückwärts bis
0x0000. Dort angekommen wird der Timer Overflow Interrupt ausgelöst und
das Spiel beginnt von vorne.
Über COM1A1 und COM1A0 kann ich wählen ob der PIN C6 bei jedem Match
toggeln soll, oder ob er beim hochählen gesetzt und beim runterzählen
rückgesetzt werden soll bzw. eine dazu inverse Einstellung.
Soweit OK oder Einwände? Falls dies nicht richtig ist, dann wäre es nett
wenn mich jemand erleuchten könnte. Ich würde gerne beim Höchzählen
setzen und beim runterzählen rücksetzen. Wenn das wirklich so nicht
funktionieren sollte, dann werde ich versuchen mit der normalen Port
operation zu arbeiten und den PIN händisch in den entsprechenden
Interruptroutinen setzen.
Schonmal Danke im vorraus.
Gruß
Benny
Benjamin K. schrieb:> Hi,>> ich sitze gerade an einem Projekt bei dem ich einen Schrittmotortreiber> mittels PWM ansteuern möchte.
Wozu brauchst du da einen PWM Modus?
CTC Modus mit Pin toggeln und die Sache ist gegessen. Alles was du
willst ist eine variable Frequenz.
Hi
>Wozu gibt es dann die Optionen aus Tabelle 15-3 auf Seite 130 des>Handbuchs?
Es gibt ja noch andere PWM-Modes, bei denen OCR0A nicht als Top
fungiert. OCR0A kann nur eine Funktion übernehmen, entweder als
Compare-Register oder als TOP-Register. Bei Mode 10 kannst du auch OCR0A
als Compare-Register verwenden.
>Leider scheint das Debugging beim AVR Studio 5 noch nicht richtig>ausgereift zu sein. Setze ich in beiden InterruptHandlern einen>Breakpoint, dann wird immer nur einer angesprungen. Lösche einen>beliebigen, wird der noch vorhandene angesprungen ...
Ist bekannt. Der Simulator funktioniert bei PWM-Modes mit variablen Top
nicht. Steht auch, wenn ich mich nicht irre, in den 'Known Issues' vom
Simulator.
>Über COM1A1 und COM1A0 kann ich wählen ob der PIN C6 bei jedem Match>toggeln soll, oder ob er beim hochählen gesetzt und beim runterzählen>rückgesetzt werden soll bzw. eine dazu inverse Einstellung.
Beim togglen bekommst du im Mode 11 eine CTC und beim Rest entweder L
oder H. Aber in keinem Fall eine PWM.
MfG Spess
Moin,
ich nutze den Simulator nicht, sondern bin mit einem JTAG MK2 auf dem
Controller via DebugWire unterwegs. Im übrigen, kann der Simulator
anscheinend einen AT90USB162 nicht simulieren.
Wieso OCR0A? Ich möchte Timer1 nutzen, wenn dann ist das OCR1A.
OK ich blick es nicht. Das mit Mode 11 und CTC steht in Handbuch anders
...
CTC ist da in Tabelle 15-4 auf Seite 131 entweder Mode 4 oder Mode 12.
In letzterem ist ICR1 dann TOP. Klar dass ich dann OCR1A als Compare
nutzen kann. Der Timer läuft dann von BOTTOM bis zum Wert in ICR1 und
wenn er unterwegs OCR1A matched wird der Pin geschaltet. Anschließend
beim runterzählen und erneutem matchen von OCR1A wird der Pin wieder
geschaltet. Tastverhältnis ist dann nur 1:1 wenn die Werte in ICR1 und
OCR1A geschickt gewählt werden ...
Also meine Frage lautet: Wie funktioniert der Phase Correct PWM Mode?
Wie kann dieser eingeschaltet werden und was macht OC1A dabei?
Ich weiß dass es andere Modi gibt, die für meine Anwendung auch
missbraucht werden können. Ich könnte mir auch eine Karte kaufen die
bereits alles mit einem Schrittmotor macht was ich will ... Dann weiß
ich aber immer noch nicht wieso der Phase Correct PWM Modus bei meinem
AVR nicht funktioniert, bzw. wo mein Fehler liegt ...
Hi
>Ich weiß dass es andere Modi gibt, die für meine Anwendung auch>missbraucht werden können. Ich könnte mir auch eine Karte kaufen die>bereits alles mit einem Schrittmotor macht was ich will ...
Wieso kommt jetzt ein Schrittmotor ins Spiel?
MfG Spess
spess53 schrieb:> Hi>>>Ich weiß dass es andere Modi gibt, die für meine Anwendung auch>>missbraucht werden können. Ich könnte mir auch eine Karte kaufen die>>bereits alles mit einem Schrittmotor macht was ich will ...>> Wieso kommt jetzt ein Schrittmotor ins Spiel?
War es schon immer. :-)
und genau darum ist mir unklar, was da ein PWM Modus überhaupt soll.
Im speziellen bin ich der Meinung, dass der phase-correct Modus sowieso
überbewertet wird. Sinn macht der IMHO nur dann, wenn bestimmte
Phasenbeziehungen zwischen mehreren Timern eingehalten werden müssen.
Ein Fall, den man eher selten hat.
Eine PWM dazu zu benutzen um eine variable Frequenz mit einem PP von 1:1
zu erzugen ist meiner Meinung nach pervers. Dazu war PWM nie gedacht und
man muss höllisch aufpassen, was denn nun genau passiert, wenn der
Compare Wert identisch mit dem Top-Wert ist.
> sts TIMSK1,r16,r16
Was macht der Assembler hiermit?
und hiermit?
> ldi r16,((1 << COM1A1) | (1 << WGM11) | (1 << WGM10))> sts
Was die Wahl des Modus angeht, war die Idee dass die Frequenz sehr
einfach geändert werden kann, nämlich nur durch Ändern eines Registers
OCR1A. Das Tastverhältnis bleibt automatisch erhalten und muss nicht
weiter beachtet werden und die beiden Interrupts gestatten mir das
drumherum einfach zu behandeln. Da der Treiber (Trinamic TMC262) über
eine STEP/DIRECTION Schnittstelle verfügt scheint mir eine PWM durchaus
geeignet.
In den sehr einfachen Interruptroutinen will ich die Schritte bis zur
Zielposition aktualisieren, bzw. prüfen, ob die Zielposition schon
erreicht wurde bzw. ob ich noch beschleunigen oder bremsen muss (->
Frequenzänderung -> Änderung von OCR1A).
Im Falle der Nutzung des CTC Modus ist die eine Interruptroutine dann
etwas komplizierter und ich muss mir auch noch merken ob eine volle
Schrittperiode durchgeführt wurde bevor ich zum Beispiel die Frequenz
ändere.
Benjamin K. schrieb:> Was die Wahl des Modus angeht, war die Idee dass die Frequenz sehr> einfach geändert werden kann, nämlich nur durch Ändern eines Registers> OCR1A.
Und?
Ist beim CTC mit toggeln auch nicht anders.
> Das Tastverhältnis bleibt automatisch erhalten und muss nicht> weiter beachtet werden
auch das ist beim CTC nicht anders
> und die beiden Interrupts gestatten mir das> drumherum einfach zu behandeln.
und wieder: ist beim CTC nicht anders
> Da der Treiber (Trinamic TMC262) über> eine STEP/DIRECTION Schnittstelle verfügt scheint mir eine PWM durchaus> geeignet.
Wozu?
eine PWM nimmst du, wenn die Pulse unterschiedliche
Puls/Pausenverhältnisse haben müssen. Das ist bei dir nicht der Fall.
> Im Falle der Nutzung des CTC Modus ist die eine Interruptroutine dann> etwas komplizierter
bis 2 zählen ist kompliziert?
Aber seis drum: Bei einer Frequenzänderung musst du 2 Register anpassen.
Genausoviele wie zb im FastPWM Modus.
Den Top-Wert und den Compare Match.
Ausser in ganz seltenen Fällen, in denen zb 2 Timer eine bestimmte PWM
Phasenbeziehung einhalten müssen oder es sonstige externe
Symteriebeschränkungen gibt, braucht kein Mensch den phase correct Mode.
Du bellst mit diesem Modus das falsche Pferd an.
Dann habe ich jetzt mal eine Frage:
Wenn der TOP-Wert bei Phase Correct PWM im Modus 11 durch OCR1A
angegeben wird. Welches Register beinhaltet dann den Compare-Wert?
Gruß
Benny
Hi
>Wenn der TOP-Wert bei Phase Correct PWM im Modus 11 durch OCR1A>angegeben wird. Welches Register beinhaltet dann den Compare-Wert?
OCR1B und/oder OCR1C.
MfG Spess
Kannst du mir sagen wo das im Handbuch steht?
Ich habe es jetzt so gelöst, dass ich COM1A1 und COM1A0 auf 0:0 setze.
Dadurch wird OC1A nicht von OCR1A beeinflusst. Ich setze den Pin jetzt
einfach in den beiden Interruptroutinen.
Nochmal Danke für die Hilfe.
Hi
>Kannst du mir sagen wo das im Handbuch steht?
Wenn du drei OC-Register hast und davon mutiert eins zum Top-Register.
Wie viel bleiben dann noch übrig? Steht vielleicht auch irgendwo.
>Ich habe es jetzt so gelöst, dass ich COM1A1 und COM1A0 auf 0:0 setze.>Dadurch wird OC1A nicht von OCR1A beeinflusst. Ich setze den Pin jetzt>einfach in den beiden Interruptroutinen.
Blödsinn. Ich hatte deinen ersten Satz leider überlesen sonst hätte ich
dir auch gleich, wie Karl-Heinz, zu CTC geraten. Also Mode 4. Damit
kannst du eine von OCR1A abhängige Frequenz erzeugen. Ganz ohne
Interrupts und händisches Pin setzten.
MfG Spess
Das ist schon richtig. Es steht aber auch nirgends das der Pin dann
nicht mehr geschaltet werden kann. Es wird ja auch der Compare Match A
Interrupt ausgelöst ...
Wie dem auch sei, zwei Befehle um einen Pin ein und auszuschalten und 1
16-Bit-Register zu beschreiben scheint mir bequemer und weniger Aufwand
zu sein als ständig 2 16-Bit-Register zu setzen zu berechnen wie jetzt
das Compare Register beschrieben werden muss, damit ein Tastverhältnis
von 1:1 erhalten bleibt und dann noch einen Vergleich durchzuführen
damit ich weiß ob ich jetzt gerade mitten im Schritt bin oder doch schon
am Ende, aber das ist nur meine Meinung ;-)
nochmal danke
Hi
> damit ein Tastverhältnis>von 1:1 erhalten bleibt und dann noch einen Vergleich durchzuführen
CTC hat ein Tastverhältnis von 1:1. Darum brauchst du dich nicht
kümmern.
MfG Spess
... und die 'Rechnerei' ist eine Multiplikation mit 2.
Die müsstest du bei deiner phase correct PWM Lösung im übrigen genauso
machen.
Aber was solls. Des Menschen Wille ist sein Himmelreich.
Ich muss nichts rechnen, da ich nur das OCR1A-Register als TOP setze.
Ich habs hier gerade Laufen ...
Ich war, wohl falsch, davon ausgegangen, dass man im Modus 11 einfach
das OCR1A-Register als TOP setzen kann UND die Automatik des OC1A-Pin
setzen nutzen kann. Auf diese Art würde man sich alle Rechnerei einfach
sparen, weil der Pin beim zählen von 0x0000 zu TOP gesetzt und beim
zählen von TOP zu 0x0000 rückgesetzt würde, oder falls benötigt
umgekehrt.
Aufwand in diesem Fall:
1x 16 Bit-Register OCR1A setzen
1x Compare Match A Interrupt Routine mit Schritt zählen
1x Overflow Routine mit Frequenz ändern
Aufwand CTC-Modus:
1x 16 Bit-Register OCR1A setzen
1x Interrupt-Routine (Compare Match A)
1x Vergleich um entweder Frequenz zu ändern oder Schritt zu zählen
1x Register oder Variable um zu merken ob Schritt gezählt werden muss
Aufwand in meiner jetzigen Lösung:
1x 16 Bit-Register OCR1A setzen
1x Compare Match A Interrupt Routine mit Pin setzen (sbi) + Schritt
zählen
1x Overflow Interrupt Routine mit Pin rücksetzen (cbi) + Frequenz ändern
Wenn ICR1 mit einbezogen wird, dann
1x 16 Bit-Register ICR1 setzen (nicht gepuffert!)
1x 16 Bit Division mit 2 (ok einfach, aber doch "Aufwand")
1x 16 Bit-Register OCR1A setzen für 1:1
1x Interrupt Routine (Compare Match A)
1x Vergleich um entweder Frequenz zu ändern oder Schritt zu zählen
1x Register oder Variable um zu merken ob Schritt gezählt werden muss
Wirklich vielen Dank für die Hilfe. Vielleicht ist mir auch einfach
nicht gelungen klar auszudrücken was ich eigentlich wissen wollte...
Gruß
Benny