Hi gRaf-eny,
Hanni hat recht. ISR's immer so kurz wie möglich.
Nebenbei sind 2 Timer ganz schlecht bei so Zeitkritischen Aufgaben, da die sich immer in die Quere kommen.
Leider gibst Du sehr wenig Infos zu Deinem Projekt (Proz, Quarz, was soll das Prog sonst noch machen, wie sieht der jetzige Quellcode aus (nicht nur Schnipsel),usw.).
Nach dem Schaltplan siehts nach einem ATMega8 aus ... Quarz wohl 16 MHz.
Meines erachtens musst Du das anders anpacken. Vergiss als erstes mal VB auf dem PC. Der Atmel kann kein Multitasking (na, ok .. Windows auch nicht wirklich ), also machen wir das einfach ganz schnell hintereinander.
Ich würde einfach erstmal die ISR entschlacken, indem die Halbschritte des Motors im Hauptprogramm schonmal in ein Array hinterlegt werden.
Außerdem würde ich in diesem speziellen Fall einen Timer immer zu festen Zeiten über die ISR laufen lassen.
Code:
' Hier die einzelnen Pins für die Motoren. Ein Array pro Pin reicht für beide Motoren
' Bit-Arrays gehen leider nicht. Würde mit Tricks gehen .. aber ist schon zu spät für mich (Uhrzeit) ;)
'******** Initialisierung *************
Dim Motorflag As Byte ' Welcher Motor ist gerade dran (1=Motor 1 ; 2=Motor 2)?
Dim Pause(2) As Word ' Pausenzähler (Geschwindigkeit Mot 1+2). Max. Wert 65535 !
Dim Hschritt(2) as Byte ' Halbschrittzähler
Din Direction(2) as Byte
Dim ISRZaehler(2) As Word
Dim MotorA(8) As Byte
Dim MotorB(8) As Byte
Dim MotorC(8) As Byte
Dim MotorD(8) As Byte
Dim I as Byte
' Da ich nicht weiß, was Schrittmotoren für eine Frequenz verkraften, gehe ich
' hier jetzt mal von 50 Hz aus. Da beide Motoren abwechselnd bedient werden,
' also eine Frequenz der ISR von 100 Hz
' Da reicht Timer0 (bei 16 MHz)
Config Timer0 = Timer, Prescale = 1024
Const Timervorgabe = 100
On Timer0 Timer_irq
Restore Halbschritt
For I=1 to 8
Read MotorA(I)
Read MotorB(I)
Read MotorC(I)
Read MotorD(I)
Next I
Motorflag = 1
Timer0 = Timervorgabe
Enable Timer0
Enable Interrupts
' *************************************
' ******** Hauptprogramm **************
Do
'(
Hier lesen wir irgendwie die ADC-Werte ein und wandeln sie in ein "verträgliches" Format
von mir aus von 400-1000 .. musst Du wissen
Der Timer springt also 100 mal pro Sekunde in die ISR .. jedes 2. mal kommt der gleiche Motor dran
In die ISR schreiben wir für jeden Motor eine "Pausenvariable", die bei jedem Einsprung hochgezählt wird.
Erreicht die Variable den Wert, den Du hier vorgibst (Geschwindigkeit), kriegt der jeweilige Motor seinen Halbschritt. Bei 1 in jedem ISR-Sprung, bei 65535 halt erst nach dem 65535zigsten Sprung. Ist das zu langsam, dann einfach den Timer schneller machen. Reicht der Endwert nicht, dann halt noch eine Zweite Variable einführen und beide hochzählen
Halbschritt
Am besten einfach rumprobieren. "ADC-Wert*irgendwas" .. keine Ahnung
Werte stehen dann in Pause(x). Richtung muss in Direction(x)
')
Loop
' ******** Hauptprogramm Ende **************
' Hier kommen die Daten für die Halbschritte
Halbschritt:
Data 1,0,0,1
Data 1,0,0,0
Data 1,1,0,0
Data 0,1,0,0
Data 0,1,1,0
Data 0,0,1,0
Data 0,0,1,1
Data 0,0,0,1
' Hier kommt die ISR
Timer_irq:
Timer0 = Timervorgabe ' Timer neu "laden"
If Motorflag = 1 Then ' Bitoperation wäre schöner aber geht nicht, da Bit 0/1 und Array ab 1 zählt
Motorflag = 2 ' müsste man dann in eine neue Variabel auslagern .. wollte ich nicht
Else
Motorflag = 1
End If
Incr ISRZaehler(Motorflag)
If ISRZaehler(Motorflag) >= Pause(Motorflag) Then
ISRZaehler(Motorflag) = 0
If Direction(Motorflag) = 1 Then
Incr Hschritt(Motorflag)
Elseif Direction(Motorflag) = 2 Then
Decr Hschritt(Motorflag)
End If
If Hschritt(Motorflag) = 9 Then
Hschritt(Motorflag) = 1
Elseif Hschritt(Motorflag) = 0 Then
Hschritt(Motorflag) = 8
End If
If Motorflag = 1 Then
Portb.0 = MotorA(Hschritt(1)) '<---- keine Ahnung, ob der Konstrukt so genommen wird
Portb.1 = MotorB(Hschritt(1)) ' Wenn nicht, musst Du ihn erst "aufdröseln"
Portb.2 = MotorC(Hschritt(1))
Portb.3 = MotorD(Hschritt(1))
Else
Portd.0 = MotorA(Hschritt(2))
Portd.1 = MotorB(Hschritt(2))
Portd.2 = MotorC(Hschritt(2))
Portd.3 = MotorD(Hschritt(2))
End If
End If
Return
Nur mal so als Denkanstoß. Ist jetzt zu spät .. können 1000 Fehler drin sein und vieles vll. einfacher zu machen sein. Vielleicht kannst Du ja ein paar Anregungen davon benutzen,
Tu mich aber langsam schwer mit denken
Gruß.
Rainer
Lesezeichen