MrMiffy08
09.04.2012, 19:53
Hallo zusammen,
ich hab hier ein bisschen Code zusammengebastelt, um einen Stepper "manuell", also mit einem Drehencoder und Taster (Pollin Best.Nr. 240 313) zu steuern. Ich hab die Statemachine von screwdriver eingebaut und eine Tastenabfrage, und Bascom gibt mir immer wieder Fehlermeldungen aus die ich nicht deuten kann. Vielleicht sieht hier einer der Erfahrenen unter Euch sofort, was fehlt oder umgestellt werden muss.
Hier der Code:
'************************************************* ******************************
'*** Programm zur manuellen Ansteuerung eines Steppers mit clk, Dir, Enable***
'*** mit Pollin Drehencoder ***
'************************************************* ******************************
'*** Author: MrMiffy08 ***
'*** Datum: 2.4.2012 ***
'************************************************* ******************************
'*** mit Attiny 2313
'Pind.1 Encoder Signal A Pin 2
'Pind.0 Encoder Signal B Pin 3
'Pind.3 Drehencoder Taster Pin 7
'Pind.2 Output für Motor_Takt Pin 6
'Pind.4 Motor Enable Output Pin 8
'Pind.5 Motor Richtung DIR Output Pin9
$regfile = "attiny2313.dat"
$crystal = 8000000
$swstack = 10
'System-Timer für periodische Encoder-Abfrage
Config Timer0 = Timer , Prescale = 64
On Timer0 Isr_timer0
Enable Timer0
Const Timer0_reload = 131 'Wert für 1ms Abfragetakt Dreh-Encoder
'Inputs: Drehencoder-Anschlüsse
Config Portd.0 = Input : Set Portd.0 : Ph_b Alias Pind.0 'Encoder Signal B an Pin 2
Config Portd.1 = Input : Set Portd.1 : Ph_a Alias Pind.1 'Encoder Signal A an Pin 3
Config Portd.3 = Input : Set Portd.3 : Encoder_switch Alias Pind.3 'Drehencoder Taster Pin 7
'Outputs
Config Portd.2 = Output : Set Portd.2 : Mot_takt Alias Pind.2 'Output für Motor_Takt Pin 6 hier muss der Takt rauskommen
Config Portd.4 = Output : Set Portd.4 : Motor_enable_output Alias Pind.4 'Motor Enable Output Pin 8 - braucht High für Motor On
Config Portd.5 = Output : Set Portd.5 : Mot_dir Alias Pind.5 'Motor DIR Output Pin 9 Richtungswechsel mit H/L
'Config Portd.5 = Output : Set Portd.5 : Mot_takt_2 Alias Pind.5 ' dies ist der 2. Phaseneingang beim A3966 für die Richtungssteuerung
Config Encoder_switch = 1 'Taster Pullup, muss initial auf High sein!
Config Motor_enable_output = 0 'Pulldown an Motor Enable Ausgang - muss initial auf GND
Config Timer1 = Timer , Prescale = 8 Timer1 'Einstellungen Für Den Motor -takt = 24s/sec
Const Timer1_reload = 23869
Const Langzaehler = 100 'nach 100ms gilt die Taste als lange gedrueckt
Const Doppelzaehler = 20 'Innerhalb dessen muss zweiter Klick erfolgen
Dim Zaehler As Byte
Dim Gedrueckt As Byte 'Art des Drueckens (Kurz/Lang/Doppel)
Const Kurz = 1
Const Lang = 2
Const Doppel = 3
'************************************************* ******************************
'*** Variablen ***
'************************************************* ******************************
Dim Rotary As Byte 'Zahlenwert des Encoders
Dim Rotary0 As Byte 'Aktueller Rasterwert (A,B)
Dim Rotary1 As Byte 'Übergangswert (A,B) zwischen Rastungen
Dim Rotary2 As Byte 'Letzter Rasterwert (A,B)
Dim Rotary_last As Byte 'Letzter Encoder-Wert (nur für Demo)
Dim Motakt As Word
Dim Motakt_timer As Word
'Dim Motakt_2 As Word
'************************************************* ******************************
'*** ISR_TIMER0 ***
'*** Periodische Auswertung des Dreh-Encoders ***
'************************************************* ******************************
Enable Interrupts
Isr_timer0:
Timer0 = Timer0_reload
Shift Rotary0 , Left , 1 'Schieberegister für Entprellung (A,B)
Rotary0.4 = Ph_a 'Phase A lesen -> Bit 4
Rotary0.0 = Ph_b 'Phase B lesen -> Bit 0
If Rotary0 <> Rotary2 Then 'Neues Signalpaar (A,B) ?
Select Case Rotary0
Case &B0000_0000 'Aktuell (A,B)= (0,0)
Select Case Rotary1
Case &B1111_0000 'Übergang war (A,B)= (1,0), also
Incr Rotary 'Encoder-Wert erhöhen
Case &B0000_1111 'Übergang (A,B)= (0,1), also
Decr Rotary 'Encoder-Wert verringern
End Select
Rotary2 = &B0000_0000 'Aktuelles (A,B) in vorheriges (A,B)
Case &B0000_1111 'Übergang (A,B)= (0,1) zwischen Rastungen
Rotary1 = &B0000_1111 'erkennen und in abspeichern
Case &B1111_0000 'Übergang (A,B)= (1,0) zwischen Rastungen
Rotary1 = &B1111_0000 'erkennen und abspeichern
Case &B1111_1111 'Aktuell (A,B)= (1,1)
Select Case Rotary1
Case &B0000_1111 'Übergang war (A,B)= (0,1), also
Incr Rotary 'Encoder-Wert erhöhen
Case &B1111_0000 'Übergang war (A,B)= (1,0), also
Decr Rotary 'Encoder-Wert verringern
End Select
Rotary2 = &B1111_1111 'Aktuelles (A,B) in vorheriges (A,B)
End Select
End If
Return
Debounce Encoder_switch , 0 , Tastenauswertung , Sub 'Subroutine Art des Drueckens (Kurz/Lang/Doppel)
'************************************************* ******************************
'*** HAUPTPROGRAMM ***
'************************************************* ******************************
Do
Motakt = 24
If Rotary_last <> Rotary Then 'Encoder gedreht?
If Rotary_last > Rotary Then 'Motor langsamer regeln
If Motakt > 24 Then
Motakt = Motakt - 10
End If
Else
Motakt = 24
End If
If Rotary_last < Rotary Then 'Motor schneller regeln
If Motakt < 240 Then
Motakt = Motakt + 10
End If
Else
Motakt = 240
End If
Rotary_last = Rotary 'Neue Stellung merken
End If
Motakt_timer = Motakt / 240 '240 = pre 1 und 32203 für Timer1
Motakt_timer = Motakt_timer * 32203
'Tastendruckauswertung:
Select Case Gedrueckt 'Hier koennen beliebige Anweisungen erfolgen
Case Kurz: 'Es wurde einmal kurz gedrueckt
Motor_enable_output = 1 'Zur Demo hier LEDs
Waitms 200
Case Lang: 'Die Taste wurde lange gedrueckt
Mot_dir = 1
Waitms 200
Case Doppel: 'Die Taste wurde doppelt gedrueckt
Mot_dir = 0
Waitms 200
End Select
Portd.3 = 1 'und wieder auf Null setzen
Loop
End 'end program
'************************************************* ******************************
'*** ISR_TIMER1 ***
'*** Takterzeugung ***
'************************************************* ******************************
On Timer1 : Timer1 = Motakt_timer 'Jeder Timer Überlauf macht den Takt für den Motor
On Int1 Toggle Mot_takt 'Hier müsste jetzt D.2 takten und zwar nach der Vorgabe von Rotary
'Mot_takt_2 = Not Portd.2 'gegenläufiges Toggeln von
'bei (kurzem) Tastendruck an PinD.3 der Motor über Portd.4 enabled werden und mit 24/sec loslaufen
'bei langem Tastendruck - 1 sec. (gleicher PortPin wie oben, also PinD.3) Ausgang Portd.5 = Dir toggelt, jeweils 3 sec in eine Richtung, dann 3 sec in andere Richtung.
'bei Doppelklick stoppt das Hin und Her wieder - weiter in eine Richtung.
'sowie eine Routine die eine Led ansteuert - ist aber sekundär (wenn dann an PB0)
'Jetzt muss noch (für A3966) der Phase_2 Ausgang gegenläufig mitgehen...
'************************************************* ******************************
'*** Subroutine ***
'*** Tastendruckauswertung ***
'************************************************* ******************************
Tastenauswertung: 'Subroutine Tastenauswertung:
Zaehler = 0
Do
Incr Zaehler
Waitms 10
Loop Until Encoder_switch = 0 Or Zaehler = Langzaehler
If Zaehler = Langzaehler Then
Gedrueckt = Lang 'lange gedrueckt
Else 'einmal kurz gedrueckt
Zaehler = 0
Do
Incr Zaehler
Waitms 10
Loop Until Encoder_switch = 1 Or Zaehler = Doppelzaehler
If Zaehler = Doppelzaehler Then 'bleibt bei einmal kurz
Gedrueckt = Kurz
Else
Gedrueckt = Doppel 'zweites Mal kurz gedrueckt
End If
End If
Return
'************************************************* ******************************
'*** Subroutine ***
'*** LED-Ausgabe ***
'************************************************* ******************************
'hier kommt noch was
Bascom sagt: Error 61: Line 241 - Label not found .......
und meldet die letzte Kommentarzeile als Fehlerzeile.
Bin für jeden Hinweis dankbar!
Schöne Ostergrüße,
MM
ich hab hier ein bisschen Code zusammengebastelt, um einen Stepper "manuell", also mit einem Drehencoder und Taster (Pollin Best.Nr. 240 313) zu steuern. Ich hab die Statemachine von screwdriver eingebaut und eine Tastenabfrage, und Bascom gibt mir immer wieder Fehlermeldungen aus die ich nicht deuten kann. Vielleicht sieht hier einer der Erfahrenen unter Euch sofort, was fehlt oder umgestellt werden muss.
Hier der Code:
'************************************************* ******************************
'*** Programm zur manuellen Ansteuerung eines Steppers mit clk, Dir, Enable***
'*** mit Pollin Drehencoder ***
'************************************************* ******************************
'*** Author: MrMiffy08 ***
'*** Datum: 2.4.2012 ***
'************************************************* ******************************
'*** mit Attiny 2313
'Pind.1 Encoder Signal A Pin 2
'Pind.0 Encoder Signal B Pin 3
'Pind.3 Drehencoder Taster Pin 7
'Pind.2 Output für Motor_Takt Pin 6
'Pind.4 Motor Enable Output Pin 8
'Pind.5 Motor Richtung DIR Output Pin9
$regfile = "attiny2313.dat"
$crystal = 8000000
$swstack = 10
'System-Timer für periodische Encoder-Abfrage
Config Timer0 = Timer , Prescale = 64
On Timer0 Isr_timer0
Enable Timer0
Const Timer0_reload = 131 'Wert für 1ms Abfragetakt Dreh-Encoder
'Inputs: Drehencoder-Anschlüsse
Config Portd.0 = Input : Set Portd.0 : Ph_b Alias Pind.0 'Encoder Signal B an Pin 2
Config Portd.1 = Input : Set Portd.1 : Ph_a Alias Pind.1 'Encoder Signal A an Pin 3
Config Portd.3 = Input : Set Portd.3 : Encoder_switch Alias Pind.3 'Drehencoder Taster Pin 7
'Outputs
Config Portd.2 = Output : Set Portd.2 : Mot_takt Alias Pind.2 'Output für Motor_Takt Pin 6 hier muss der Takt rauskommen
Config Portd.4 = Output : Set Portd.4 : Motor_enable_output Alias Pind.4 'Motor Enable Output Pin 8 - braucht High für Motor On
Config Portd.5 = Output : Set Portd.5 : Mot_dir Alias Pind.5 'Motor DIR Output Pin 9 Richtungswechsel mit H/L
'Config Portd.5 = Output : Set Portd.5 : Mot_takt_2 Alias Pind.5 ' dies ist der 2. Phaseneingang beim A3966 für die Richtungssteuerung
Config Encoder_switch = 1 'Taster Pullup, muss initial auf High sein!
Config Motor_enable_output = 0 'Pulldown an Motor Enable Ausgang - muss initial auf GND
Config Timer1 = Timer , Prescale = 8 Timer1 'Einstellungen Für Den Motor -takt = 24s/sec
Const Timer1_reload = 23869
Const Langzaehler = 100 'nach 100ms gilt die Taste als lange gedrueckt
Const Doppelzaehler = 20 'Innerhalb dessen muss zweiter Klick erfolgen
Dim Zaehler As Byte
Dim Gedrueckt As Byte 'Art des Drueckens (Kurz/Lang/Doppel)
Const Kurz = 1
Const Lang = 2
Const Doppel = 3
'************************************************* ******************************
'*** Variablen ***
'************************************************* ******************************
Dim Rotary As Byte 'Zahlenwert des Encoders
Dim Rotary0 As Byte 'Aktueller Rasterwert (A,B)
Dim Rotary1 As Byte 'Übergangswert (A,B) zwischen Rastungen
Dim Rotary2 As Byte 'Letzter Rasterwert (A,B)
Dim Rotary_last As Byte 'Letzter Encoder-Wert (nur für Demo)
Dim Motakt As Word
Dim Motakt_timer As Word
'Dim Motakt_2 As Word
'************************************************* ******************************
'*** ISR_TIMER0 ***
'*** Periodische Auswertung des Dreh-Encoders ***
'************************************************* ******************************
Enable Interrupts
Isr_timer0:
Timer0 = Timer0_reload
Shift Rotary0 , Left , 1 'Schieberegister für Entprellung (A,B)
Rotary0.4 = Ph_a 'Phase A lesen -> Bit 4
Rotary0.0 = Ph_b 'Phase B lesen -> Bit 0
If Rotary0 <> Rotary2 Then 'Neues Signalpaar (A,B) ?
Select Case Rotary0
Case &B0000_0000 'Aktuell (A,B)= (0,0)
Select Case Rotary1
Case &B1111_0000 'Übergang war (A,B)= (1,0), also
Incr Rotary 'Encoder-Wert erhöhen
Case &B0000_1111 'Übergang (A,B)= (0,1), also
Decr Rotary 'Encoder-Wert verringern
End Select
Rotary2 = &B0000_0000 'Aktuelles (A,B) in vorheriges (A,B)
Case &B0000_1111 'Übergang (A,B)= (0,1) zwischen Rastungen
Rotary1 = &B0000_1111 'erkennen und in abspeichern
Case &B1111_0000 'Übergang (A,B)= (1,0) zwischen Rastungen
Rotary1 = &B1111_0000 'erkennen und abspeichern
Case &B1111_1111 'Aktuell (A,B)= (1,1)
Select Case Rotary1
Case &B0000_1111 'Übergang war (A,B)= (0,1), also
Incr Rotary 'Encoder-Wert erhöhen
Case &B1111_0000 'Übergang war (A,B)= (1,0), also
Decr Rotary 'Encoder-Wert verringern
End Select
Rotary2 = &B1111_1111 'Aktuelles (A,B) in vorheriges (A,B)
End Select
End If
Return
Debounce Encoder_switch , 0 , Tastenauswertung , Sub 'Subroutine Art des Drueckens (Kurz/Lang/Doppel)
'************************************************* ******************************
'*** HAUPTPROGRAMM ***
'************************************************* ******************************
Do
Motakt = 24
If Rotary_last <> Rotary Then 'Encoder gedreht?
If Rotary_last > Rotary Then 'Motor langsamer regeln
If Motakt > 24 Then
Motakt = Motakt - 10
End If
Else
Motakt = 24
End If
If Rotary_last < Rotary Then 'Motor schneller regeln
If Motakt < 240 Then
Motakt = Motakt + 10
End If
Else
Motakt = 240
End If
Rotary_last = Rotary 'Neue Stellung merken
End If
Motakt_timer = Motakt / 240 '240 = pre 1 und 32203 für Timer1
Motakt_timer = Motakt_timer * 32203
'Tastendruckauswertung:
Select Case Gedrueckt 'Hier koennen beliebige Anweisungen erfolgen
Case Kurz: 'Es wurde einmal kurz gedrueckt
Motor_enable_output = 1 'Zur Demo hier LEDs
Waitms 200
Case Lang: 'Die Taste wurde lange gedrueckt
Mot_dir = 1
Waitms 200
Case Doppel: 'Die Taste wurde doppelt gedrueckt
Mot_dir = 0
Waitms 200
End Select
Portd.3 = 1 'und wieder auf Null setzen
Loop
End 'end program
'************************************************* ******************************
'*** ISR_TIMER1 ***
'*** Takterzeugung ***
'************************************************* ******************************
On Timer1 : Timer1 = Motakt_timer 'Jeder Timer Überlauf macht den Takt für den Motor
On Int1 Toggle Mot_takt 'Hier müsste jetzt D.2 takten und zwar nach der Vorgabe von Rotary
'Mot_takt_2 = Not Portd.2 'gegenläufiges Toggeln von
'bei (kurzem) Tastendruck an PinD.3 der Motor über Portd.4 enabled werden und mit 24/sec loslaufen
'bei langem Tastendruck - 1 sec. (gleicher PortPin wie oben, also PinD.3) Ausgang Portd.5 = Dir toggelt, jeweils 3 sec in eine Richtung, dann 3 sec in andere Richtung.
'bei Doppelklick stoppt das Hin und Her wieder - weiter in eine Richtung.
'sowie eine Routine die eine Led ansteuert - ist aber sekundär (wenn dann an PB0)
'Jetzt muss noch (für A3966) der Phase_2 Ausgang gegenläufig mitgehen...
'************************************************* ******************************
'*** Subroutine ***
'*** Tastendruckauswertung ***
'************************************************* ******************************
Tastenauswertung: 'Subroutine Tastenauswertung:
Zaehler = 0
Do
Incr Zaehler
Waitms 10
Loop Until Encoder_switch = 0 Or Zaehler = Langzaehler
If Zaehler = Langzaehler Then
Gedrueckt = Lang 'lange gedrueckt
Else 'einmal kurz gedrueckt
Zaehler = 0
Do
Incr Zaehler
Waitms 10
Loop Until Encoder_switch = 1 Or Zaehler = Doppelzaehler
If Zaehler = Doppelzaehler Then 'bleibt bei einmal kurz
Gedrueckt = Kurz
Else
Gedrueckt = Doppel 'zweites Mal kurz gedrueckt
End If
End If
Return
'************************************************* ******************************
'*** Subroutine ***
'*** LED-Ausgabe ***
'************************************************* ******************************
'hier kommt noch was
Bascom sagt: Error 61: Line 241 - Label not found .......
und meldet die letzte Kommentarzeile als Fehlerzeile.
Bin für jeden Hinweis dankbar!
Schöne Ostergrüße,
MM