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.
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,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
Tu mich aber langsam schwer mit denken![]()
Gruß.
Rainer







Zitieren
Lesezeichen