PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] PWM: Frequenz auf 0 - ca. 200Hz einstellen



01.06.2004, 20:18
hi,
ich verwende für die steuerung eines schrittmotors die bausteine l297 / l298. der l297 besitzt einen clockeingang, der die geschwindigkeit des schrittmotors steuert.

diesen eingang möchte ich mit einem pic ansteuern. damit der pic nicht nur mit dem erzeugen eines taktsignals beschäftigt ist, dachte ich an das pwm-modul. leider sind pwm-frequenzen von mehreren kHz etwas zu schnell. der gewünschte bereich liegt zwischen 1Hz und ca 200Hz.
in der AN564 - Using the PWM
(http://www.microchip.com/stellent/idcplg?
IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011094) steht auf seite 5, erster
satz: "...timebase for the pwm outputs can be software selected to operate from an external clock source. this allows a lower frequency to be achieved. ...".
In der PICmicro MID-RANGE MCU FAMILY Reference
(http://ww1.microchip.com/downloads/en/DeviceDoc/33023a.pdf) steht unter section 13 - timer2 - 13.3 Timer Clock Source
"The Timer2 module has one source of input clock, the device clock (FOSC/4)." in dem datenblatt des pic 16f870 steht unter timer2 auch nichts von einer externen taktquelle.
es hat den anschein als könnte nur für den timer0 (und vielleicht auch den
timer1) eine externe taktquelle angegeben werden, aber nicht für den timer2, der für die pwm verwendet wird.

eine möglichkeit wäre wohl für jeden schrittmotor einen timer zu verwenden und in der isr des timers das zugehörige bit 2x zu invertieren (clk des l297 ist flankengesteuert). ich weiss allerdings nicht was passiert wenn gerade die interruptserviceroutine des zb timers1 ausgeführt wird und der timer2 überläuft. ich vermute wenn eine isr ausgeführt wird sind alle anderen interrupts gesperrt. damit wäre ein schritt des anderen motors (timer2) verloren !?
gibt es eigentlich bausteine(wenn ja wie heißen die?), die über einen zb 8bit-wert gesteuert ein pwm signal erzeugen (niedere frequenz)?

eine interessante analoge möglichkeit liefert der ic 4046. er enthält einen vco (spannungsgesteuerten oszillator). der frequenzbereich ist über einen widerstand und einen condensator einstellbar und lässt sich über einen weiteren widerstand noch verschieben. über einen digital-analog-konverter könnte ein vom pic ausgegebener wert in eine spannung umgesetzt werden und vom vco in eine frequenz gewandelt werden. umständlich wäre dann wohl die schrittanzahl zu bestimmen.

kennt jemand eine möglichkeit ein langsames taktsignal zu erzeugen ohne dabei den pic mit toggeln eines pins und warten zu beschäftigen?
können vielleicht die atmel's ein langsameres taktsignal erzeugen?

mfg sibi

Dino Dieter
01.06.2004, 20:46
Hallo

Was willst du mit den Schrittmotoren denn machen ? Nur laufen lasen oder willst du auch wissen, wo sie stehen und entsprechend setzen können? Dann fällt eine PWM eh eher flach, da du die Schritte ja zählen mußt.

Wenn du nur eine langsame PWM haben willst, könnte man an den PWM Ausgang einen 8 Bit Zähler anschliessen, der teilt dann sauber deine Frequenz runter, wie du sie brauchst.

MFG
Dieter

seven
01.06.2004, 22:59
ich verwende 2 schrittmotoren für den antrieb meines bots.
an das problem mit dem zählen der schritte hatte ich noch nicht gedacht. außerdem habe ich gerade gelesen dass zwei pwms (zwei motoren) in einem pic nur mit der gleichen frequenz betrieben werden können. da der bot nicht nur geradeaus fahren soll, scheidet die pwm wohl endgültig aus. die idee mit dem zähler hört sich gut an - einen programmierbaren microcontroller mit zusätzlicher hardware auszustatten mache ich allerdings nur ungern.

ich möchte jeden einzelnen motor manuell über ein poti (schiebepoti) steuern können (der bot soll erst später autonom werden). die spannung am poti soll mit einem adc gewandelt werden und in eine frequenz umgesetzt werden. bei 5v versorgungsspannung heißt das zb 0v -> rückwärts, schnellste geschwindigkeit; 2,5v -> motor aus; 5v -> vorwärts, schnellste geschwindigkeit. der geschwindigkeitsanstieg soll dabei nicht linear sein. der pic muss also zwei spannungen messen, zwei (evtl. unterschiedliche) frequenzen erzeugen und noch andere aufgaben erledigen wie zb sensoren abfragen (weitere ad-wandlungen) und die ergebnisse verarbeiten. dies verlangt eigentlich nach einem multitasking betriebssystem. da ich nicht besonders geübt im assemblerprogrammieren bin, stelle ich es mir eher schwierig vor zwei variierende frequenzen zu erzeugen und gleichzeitig dem pic etwas intelligenz einzubrennen ;-)

das ganze läuft wohl auf mehrere pics hinaus:
eine zentrale einheit:
- einlesen der potis für geschwindigkeit der motoren -> zb die 4 höherwertigen bits des ergebnisses (8 geschwindigkeitsstufen pro fahrtrichtung) der ad-wandlung an port anlegen,
und für jeden motor einen weiteren pic, der aus den übergebenen werten (4bit + weitere signale) die signale erzeugt (drehrichtung, taktsignal, usw). die zentrale einheit weiß damit allerdings nicht wieviel schritte die motoren gemacht haben. dazu müssten die pics (der motorsteuerung) pro schritt ein signal an den zentralpic senden, welches an einem pin einen interrupt-on-change auslöst. (für mich hört sich das irgendwie nach fehlerquelle an ;-) )
meine frage ist eigentlich: wie steuer ich zwei schrittmotoren (ic L297) mit einem microcontroller?

interessiert mich sehr wie andere das problem gelöst haben

ps: hab mich jetzt eingeloggt

mfg sibi

Marvin
02.06.2004, 00:13
Hi seven,
ich dachte zuerst auch,dass mein AVR voll mit Pulsemachen beschäftigt ist und keine Zeit mehr für was anderes hat. Nach einigen klasse Tips hier aus dem Forum war mir dann klar, das eine timergesteuerte Interruptroutine eine gute Lösung des Problems ist.
Das Prinzip dabei ist, dass ein Timer alle paar ms einen Interrupt auslöst, durch den dann ein Unterprogramm ausgeführt wird. Man kann im Hauptprogramm Sensoren abfragen, oder so, und die Impulserzeugung für die Motoren läuft sozusagen "von allein" im Hintergrund ab.
Ich hab mal ein paar Programmteile aus meinem Steuerprogramm ausgeschnitten um das Prinzip zu verdeutlichen. Der Code ist in Bascom für einen AVR, aber das spielt denk ich keine Rolle, es geht ja nur um's Prinzip, deswegen hab ich auch die ganze Variablendeklaration und so weggelassen.


' Timer0 Impulse für die Motoren
Config Timer0 = Timer , Prescale = 64
On Ovf0 Motoren 'Bei Überlauf wird das Unterprogramm "Motoren" ausgeführt

Enable Timer0
Stop Timer0
Enable Interrupts

' +++++++++++++ Hauptprogramm ++++++++++++++

'10cm geradeaus fahren

Vr = 20 'Geschwindigkeit linker Schrittmotor
Vl = 20 'Geschwindigkeit rechter Schrittmotor

Portc.5 = 1 'Drehrichtung links
Schrittelinks = 0 'Schrittzähler links zurücksetzen

Portc.4 = 0 'Drehrichtung rechts
Schritterechts = 0 'Schrittzähler rechts zurücksetzten

Start Timer0
Do
Loop Until Schrittelinks = 180
Stop Timer0

End 'end program


' ------------------ Subs -------------------
Motoren:
Timer0 = 220

If Vzl = 0 Then 'linker Schrittmotor
Vzl = Vl
Toggle Portc.3
Incr Schrittelinks
Else
Decr Vzl
End If

If Vzr = 0 Then 'rechter Schrittmotor
Vzr = Vr
Toggle Portc.2
Incr Schritterechts
Else
Decr Vzr
End If
Return

Einziger Nachteil dieser Art der Programmierung ist, dass man keinen zweiten Zeitkritischen Prozess laufen lassen kann.
Ich habe z.B. versucht die PWM-Signale einer Fernsteuerung auswerten, es ist mir aber (noch?) nicht gelungen, diesen ebenfalls zeitkritischen Prozess so ablaufen zu lassen, dass meine Motoren nicht ins Stottern kommen, so dass das jetzt ein Copro machen soll.

Grüsse, Marvin

seven
02.06.2004, 00:47
hi marvin,
danke für deine antwort.
das prinzip ist klar, denke ich. bei jedem timerüberlauf wird eine isr ausgeführt, die veranlasst dass beide schrittmotoren jeweils einen schritt machen. über den timer lässt sich so die geschwindigkeit einstellen. aber was macht die variable vzl bzw vzr? ist es nicht umständlich wenn sich der linke motor zb 2,46x schneller drehen soll als der rechte? vielleicht habe ich das noch nicht ganz durchdacht, aber mir erscheint es schwierig zwei unabhängige motoren mit einem timer zu steuern.
ich würde mich über eine ausführliche kommentierung der subroutine freuen

mfg sibi

seven
02.06.2004, 02:14
ok, habs jetzt denke ich ganz begriffen ;-) (was einem beim einschlafen alles so einfällt). im obigen quellcode muss der timer also 20mal überlaufen bis der motor einen schritt macht. damit lassen sich dann wohl auch zwei unterschiedliche geschwindigkeiten (über vl und vr) für die zwei motoren realisieren. die zeit zwischen zwei schritten ist also immer ein vielfaches der timerzeit.
manchmal dauerts einfach etwas länger bis es im hirn angekommen ist ;-)

mfg sibi

Marvin
02.06.2004, 04:20
Jup seven, genauso ist es. :)
Man kann keine beliebigen Geschwindigkeitsunterschiede zwischen den Motoren machen, aber die Abstufungen sind recht klein.
Der Motor macht übrigends nur bei jedem 2. Mal einen Schritt (in dem Beispiel also nach 40 Überläufen). Der Toggelbefehl kippt den Ausgang beim ersten Mal von LOW nach HIGH, was einen Schritt des Steppers zur Folge hat, beim 2. Mal kippt er von HIGH nach LOW, was keinen Schritt auslöst.

Ich hab meine besten Ideen übrigends auch meist kurz vor'm Einschlafen (oder auf Klo) ;)

Grüsse, Marvin