PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RNBFRA Software: Schrittmotoren mit Timern ansteuern (BASCOM



Albanac
10.05.2004, 18:58
Das Programm kann helfen Bascom Timersteuerung zu verstehen

Basis:
-https://www.roboternetz.de/phpBB2/viewtopic.php?t=321&highlight=timer
In HiTechs Post der Code über Timer

-RNBFRA Beispielprogramme von der CD



'(################################################ ###

Timertest.bas
Schrittmotoren Mit Timern Steuern...
Auf Dem Rnbfra 1.1

Moritz Wurth 10.05.2004

################################################## ### ')
Declare Sub Ledein(id As Word) 'Subs zur Ledanzeige deklarieren
Declare Sub Ledaus


Dim Rightspeed As Byte 'Variablendefintion XXXspeed als Geschwindigkeitsangabe
Dim Leftspeed As Byte ' XXX = Right bzw Left für die jeweilige seite

Dim Rightstatus As Bit 'Intern ben. Variable
Dim Leftstatus As Bit 'Intern ben. Variable
Dim Temp As Byte 'Intern ben. Variable
Dim Tempspeed As Byte 'Intern ben. Variable


$baud = 9600
$crystal = 8000000
'Ports für Schrittmotoren/LED einstellen
Config Pinc.5 = Output
Config Pinc.3 = Output

Config Pinc.4 = Output
Config Pinc.2 = Output

Config Pind.6 = Output

Const Writepowerport_adr = &H72
Const Readpowerport_adr = &H73

Dim I2cdaten As Byte


Config Timer0 = Timer , Prescale = 256 'Timer festlegen, Prescale legt fest welche X Takte der Timer aufgerufen wird
On Ovf0 Tim0_isr 'Wenn Timer0 ausgelöst wird, rufe Tim0_isr auf

Dim I As Integer 'Taktzähler
Dim Cnt As Byte


'Timer anschalten
Enable Timer0 'Interrupts anschalten
Enable Interrupts

'-----------------------------------------------------------------------
' Ab hier reguläres Programm
' Hier: An den 4 LED wird Binär bis 16 gezählt
' alle 1.6 Sekunden (16 * 100ms) wird die Geschwindigkeit auf dem Rechten Motor um 1 erhöht, links erniedrigt


Rightspeed = 50 'Startgeschwindigkeit 50

Do
Cnt = Cnt + 1
Call Ledein(cnt) 'LED setzen
If Cnt = 15 Then 'Wenn 1 mal durchlaufen wurde
Cnt = 0 'LED zähler wieder auf 0
Rightspeed = Rightspeed - 1 'Rechts eins erniedrigen
Leftspeed = 50 - Rightspeed 'Links ebenfalls verändern
If Rightspeed = 0 Then 'Wenn alles einmal durch ist (Rechts auf 0)
Stop Timer0 'Timer stoppen
Portd.6 = 0 'Schrittmotoren aus
End If
End If
Waitms 100
Loop


Tim0_isr:
I = I + 1
Temp = I Mod Rightspeed

If Temp = 0 Then
Rightstatus = Not Rightstatus
Portc.2 = Rightstatus
End If

Temp = I Mod Leftspeed
If Temp = 0 Then
Leftstatus = Not Leftstatus
Portc.3 = Leftstatus
End If

Return


End

Sub Ledein(id)
I2cstart
I2cwbyte Writepowerport_adr
I2cwbyte Id 'Datenbyte an PCF I2cstop
I2cstop
End Sub


Sub Ledaus()
I2cstart
I2cwbyte Writepowerport_adr 'Schreibbefehl an PCF schicken
I2cwbyte 0 'Datenbyte an PCF
I2cstop
End Sub

tomkeule
10.05.2004, 21:32
Hallo,

so ganz verstehe ich dieses Programm nicht. Vielleicht würde ich es ein bisschen besser verstehen wenn ich es zum laufen bringen würde. Habe zwar die vorhanden Fehler ( I2cinit bzw. Port für I2C) beseitigt aber das hat nichts gebracht.

Es will einfach nicht.

mfg

Tomkeule

Frank
10.05.2004, 21:55
Ich denke das Programm ist noch etwas zu durcheinandergewirbelt ;-) um die Timerprogrammierung so zu verstehen. Müsste man etwas klarer strukturieren. Die Schrittbefehle in seperate Subroutinen und Kapseln und unnötiges raus!

Michael
10.05.2004, 23:28
Hallo Albanac,
du startest deinen Timer0 nicht,also kommt es nie zum Interrupt und
du setzt in deiner Interruptroutine deinen Timer0 nicht auf einen anderen Wert, hast also immer den gleichen Überlaufwert für deinen Timer.
Im Interrupt setzt du auch nur einen Port, musst du nicht ein Schrittmuster generieren? etc.etc.
Gruss, Michael

tomkeule
11.05.2004, 06:47
Hallo,

ich habe mal selbst versucht Schrittmotoren über Timer zu steuern.


'Testprogramm für 2 Schrittmotoren über Timer

$crystal = 8000000 'Quarzfrequenz

Declare Sub Ledein
Declare Sub Ledaus

Const Writepowerport_adr = &H72 'I2C Adr PCF 2
Const Readpowerport_adr = &H73 'I2C Adr PCF 2

Dim I2cdaten As Byte 'Datenbyte aus PCF8574

Config Scl = Portc.0 'Ports fuer IIC-Bus
Config Sda = Portc.1
I2cinit

'******** Diese 4 Befehle sind nur ab RNBFRA Version 1.2 (nicht in V 1.1)
' notwendig und bzw. möglich (erweiterte Energiesparfunktion und LED´s)
' Bei Board 1.1 bitte auskommentieren oder löschen
I2cstart
I2cwbyte &H74 'Schreibbefehl an PCF3 schicken
' Led´s ein ,Motorendstufen ein, Port-Peripherie ein, RBN-Bus Sleep Modus aus (also Peripherie aktiv)
I2cwbyte &B00000010 'Datenbyte an PCF3
I2cstop
'*********

Config Pind.6 = Output 'Schrittmotoren Ein/Aus
Config Pinc.5 = Output 'Schrittmotor Links Richtung
Config Pinc.3 = Output 'Schrittmotor Links Step

Config Pinc.4 = Output 'Schrittmotor Rechts Richtung
Config Pinc.2 = Output 'Schrittmotor Rechts Step

Dim X As Word

Dim Y As Word

Dim Verteilung As Byte

Verteilung = 50 'Anfangseinstellung beide Motoren mit 50%

Portd.6 = 1 'Beide Schrittmotoren einschalten

'-------------------------------------------------------------------------------
On Timer0 Ontimer0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0

On Timer2 Ontimer2
Config Timer2 = Timer , Prescale = 1024
Enable Timer2

Enable Interrupts

Do

Input Verteilung

X = 250 * Verteilung
X = X / 100
Y = 250 - X
Print X ; "--" ; Y

Loop


End

'-------------------------------------------------------------------------------
Ontimer0:
Timer0 = X
Toggle Portc.2
Return


Ontimer2:
Timer2 = Y
Toggle Portc.3
Return


Meine Frage ist nun ob man das so machen kann??


mfg

Tomkeule

Michael
11.05.2004, 08:56
Hallo tomkeule,
hmmm, du stocherst mehr, als dass du es verstehst?
Ich weiss nicht, welchen Prozessor du verwendest, ich kenne das "RNBFRA" nicht. Hat jemand einen Link auf Datenblätter dazu?
Dann startest du deine Timer immer noch nicht.
Da Timer0 bei AVR's gewöhnlich ein 8bit-Timer ist, wirst du lustige Überläufe haben.
Hat die Elektronik eigene "Intelligenz" ?. Woher weiss der Schrittmotor, dass es z.B. vorwärts geht?
Gruss, Michael

tomkeule
11.05.2004, 09:52
Hallo Michael,

1. Warun stochern?

2.Beide Timer werden doch gestartet

3.Was verstehst du unter lustige Überläufe?

4.Dieses Prog ist nur für den Test der Schrittmotoransteuerung. Ich gehe mal davon aus das du das Input übersehen hast.

5.Die Auswertung der Sensoren ist hier noch nicht eingebaut.(Übersichtlichkeit)

6.Im Augenblick funktioniert das Prog nur für eine Laufrichtung.

Und zu gut letzt, das Prog funktioniert sogar.

mfg

Tomkeule

Frank
11.05.2004, 09:52
Anleitung mit Portbeschreibung etc. findest Du hier https://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=106

Ich komme leider jetzt nicht dazu ein kleines Timerbeispiel zu posten weil ich gerade selbst mit anderem Programm beschäftigt bin. Aber mach das bei Gelegenheit noch.
Im Grunde ist es einfach, nur für die Berechnung der Timerzeit braucht man etwas Übung

Das zweite Beispiel ist aber schon viel übersichtlicher. Könnte gehen! Timer wird doch gestartet!

Michael
11.05.2004, 10:59
Hallo tomkeule,

2.Beide Timer werden doch gestartet
Nein. Der Eintrag Start Timerx fehlt für beide Timer.

3.Was verstehst du unter lustige Überläufe?
Schrieb ich schon in meinem letztem Posting.
Denkanstoss: Der Timer0 hat 8bit, der Wert, den du reinschreibst hat x bit. Bestimme, ob x > 8 :)

4.Dieses Prog ist nur für den Test der Schrittmotoransteuerung. Ich gehe mal davon aus das du das Input übersehen hast.
Nein, keineswegs. Funktioniert dieser Teil des Programmes?

Und zu gut letzt, das Prog funktioniert sogar.
Ich melde trotzdem Zweifel an *g*
Ich sehe gerade (@Frank:danke für den Link), dass Timer2 auch 8bit hat. Obendrein kann in deiner Rechnung Y negative (Word-)Werte haben. Schreib mal einen "negativen" 16bit-Wert in eine 8bit-Variable. Das mein ich mit lustigen Überläufen.

Gruss, Michael

tomkeule
11.05.2004, 11:25
Hallo Michael,

2.ich hoffe das ich mich nicht irre, aber die Timer werden mit "enable Timer" gestartet

3.X und Y sind als WORd deklariert um bei der multiplikation einen Überlauf zu vermeiden.

4.Ja

Ja, Y kann negative sein. Aber nur wenn ich bei Input Müll eingebe.

(Alles nur Test und Ausprobe)

Aber Dank an Michael und alle Anderen für die Hilfe und Kritik.
Nur wer seine Fehler kennt kann sie beseitigen.

mfg

Tomkeule

tomkeule
11.05.2004, 11:49
sorry,

Timer0 wird eigentlich mit TCCR0=&B00000101 gestartet.(Vorverteilung 1024)

Oder in Bascom mit Config Timer0, welches auf das selbe Register zugreift.

mfg

Tomkeule

Michael
11.05.2004, 11:57
Hallo tomkeule,
zu 2.: Mit Enable werden sie erlaubt, mit start gestartet -->siehe Hilfe oder auch: RTFM!
zu3.: Klar X und Y sind Word- Werte, mitgedacht hast du da. Leider hast du vergessen, dass deine Timer nur 8 bit haben.
Ich sags dir jetzt nochmals: Dein Timer hat 8 (in Worten: ACHT) bit. Er läuft danach über! Deine Variable, die du reinschreibst, hat 16 bit. (SECHZEHN). Hast du überlegt, was passiert, wenn du einen Wert grösser als 8bit in eine 8bit-Variable schreibst???
Gruss, Michael

tomkeule
11.05.2004, 12:12
Hallo Michael,

bis auf Punkt 3 wäre soweit alles geklärt.

Bei meiner Variablen die als WORD deklariert ist(2 Byte) wird beim speichern in einer Byte -Variablen das 1.Byte abgeschnitten.

Glaube ich

mfg

Tomkeule

Dino Dieter
11.05.2004, 12:59
Hallo

Nochmal zur Erklärung

Mit
Config Timer0 = Timer , Prescale = 1024 wird der Timer Vorteiler eingestellt und danach läuft der Timer0 auch. Man kann den Timer0 nur über den Vorteiler anhalten indem man ihn auf null setzt.

Mit
Enable Timer0

wird der Timer0 Overflow Interrupt erlaubt und sonst gar nichts.


Mit
Stop Timer0
Wird der Vorteiler von Timer0 auf null gesetzt und er wird somit angehalten.

Mit
Start Timer0
Wird der alte Vorteilerwert wieder zurück geschrieben und der Timer damit wieder gestartet.

Das gleiche gilt für die anderen Timer auch.

MFG
Dieter

Albanac
11.05.2004, 13:04
Welchen wert setze ich wenn ich Timer0 = X setzte?

kann ich den timer auch langsamer laufen lassen?

Dino Dieter
11.05.2004, 13:49
Hallo

Mit Timer0 = x schreibst du den Wert der Variablen x in Timer0. Kommt halt immer darauf an, welcher Wert in x steht.

Langsamer geht leider nicht, da der maximale Vorteiler 1024 ist und der ja eingestellt ist.

Welche Zeiten willst du denn erreichen ?

Vielleicht kann ich dir da mal eine Lösung zeigen .

MFG
Dieter

Albanac
11.05.2004, 15:58
naja ich will das der schrittmotor sich langsamer dreht...

bis jetzt hab ich das nur mit modulo gemacht, gibts da keinen anderen trick?

Dino Dieter
11.05.2004, 16:36
Ok dann wollen wir mal rechnen.

Der Timer ist ja nur eine Speicherstelle des uC, den man mit dem Takt verbinden kann
und dann um 1 erhöht wird. Beim Wechseln von 255 auf 0 ( 256) kann ein Interrupt
ausgelöst werden.

Daraus ergibt sich.

Takt / Vorteiler = Zeit pro Erhöhung Beispiel: 8 MHZ / 1 = 125 ns
oder 8MHZ / 1024 = 128 us. Damit kann Timer0 minimal in 125 ns oder maximal in 128 us
um 1 erhöht werden.

Wenn man den Timer0 auf 0 einstellt dauert das dann 256 mal so lange, bis ein Interrupt auftritt.

Beispiel :

Timer0 = 100 Vorteiler 1024 Takt 8 MHZ

8MHZ / 1024 = 128 us pro Erhöhung. Der Timer braucht jetzt noch 256 - 100 = 156 Erhöhungen
bis zum Interrupt ---> 156 * 128 us = 19,98 ms bis zum Interrupt.

Wenn du jetzt in der Interrupt Routine eine Variable deiner Wahl um 1 erhöhst, hast
du doch eine Erhöhung alle ca 20 ms. Wenn deine Variable damit den Wert 50 erreicht,
so sind ungefähr 1 Sekunde vergangen. ( 0,9984 Sekunden )


dim zeit as byte

On Timer0 Ontimer0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0

do
nop
loop


Ontimer0:
Timer0 = 100 'Neue einstellen für 20 ms INT.
incr zeit 'Interrupts zählen
if zeit >= 50 then '1 Sekunde vorbei
Toggle Portc.2
zeit = 0 'Zeit löschen
endif
Return

MFG
Dieter

Frank
11.05.2004, 21:52
Hi Dino Dieter,
feines übersichtliches Beispiel! Albanac, daraus kann man eigentlich alles ableiten. Je nach Geschwindigkeit kannst du in der Timerroutine eigene Zähler nutzen und andere Subroutinen für bestimmte Aufgaben heranziehen. So könnte eine die Schrittmotoren bewegen und eine andere eine Uhr stellen usw. Durch veränderung des maximalen Zählerstandes bei dem auf 0 zurückgestellt wird, kannst du auch die Geschwindigkeit von Schrittmotoren regeln. Wenn man es einigermaßen elegant gestaltet dann ist das am Ende genauso einfach wie mit Getriebemotoren, nur halt genauer da du auch Schritte zählen kannst.

Dino Dieter
11.05.2004, 22:08
Hallo Frank

Ja das mit den Timern ist so eine Sache.

Habe mich am Anfang auch sehr schwer damit getan, jetzt geht es aber gut.

Timer1 hat ja noch viel viel mehr Möglichkeiten. Ist schon Klasse, was man mit den kleinen Dingern so alles anstellen kann.

MFG
Dieter

Michael
11.05.2004, 22:26
Hallo Dino Dieter,

Mit
Config Timer0 = Timer , Prescale = 1024 wird der Timer Vorteiler eingestellt und danach läuft der Timer0 auch.
Asche auf's Haupt, du hast recht. Jetzt hab ich's in der Doku auch gefunden. Mein Fehler war, dass ich die Timer prinzipiell nach dem Config stoppe, damit meine Motoren nicht loslaufen. Das muss ich dann mit Start wieder freigeben.
Eine kleine Korinthe muss ich aber trotzdem noch kacken :)
In deinem letztem Programm-Beispiel fehlt noch:
Enable Interrupts
Gruss, Michael

Dino Dieter
11.05.2004, 22:38
Hallo Michael

Dann sind wir doch wieder Quit.

Ich schau mir den Code im AVR Studio an, da sieht man dann schön was abgeht, oder halt auch, was nicht abgeht. 8-[


MFG Dieter