Eben deswegen hatte ich ja auch vorgeschlagen, das eine Hochsprache machen zu lassen die eine entsprechende Software-Funktion anbietet, und problemlos die Anpassung an einen anderen Controller selbst übernimmt.
BASCOM bietet eine Encoder-Funktion, in der Hilfe findet sich dazu folgendes Beispiel:
CodeBox BascomAVR
'-----------------------------------------------------------------------------------------
'name : encoder.bas
'copyright : (c) 1995-2005, MCS Electronics
'purpose : demonstration of encoder function
'micro : Mega128
'suited for demo : yes
'commercial addon needed : no
'An encoder has 2 outputs and a ground
'We connect the outputs to pinb.0 and pinb.1
'You may choose different pins as long as they are at the same PORT
'The pins must be configured to work as input pins
'This function works for all PIN registers
'-----------------------------------------------------------------------------------------
$regfile = "m128def.dat" ' specify the used micro
$crystal = 4000000 ' used crystal frequency
$baud = 19200 ' use baud rate
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
Print "Encoder test"
Dim B As Byte
'we have dimmed a byte because we need to maintain the state of the encoder
Portb = &B11 ' activate pull up registers
Do
B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1)
' ^--- 1 means wait for change which blocks programflow
' ^--------^---------- labels which are called
' ^-------^---------------------------- port PINs
Print B
Waitms 10
Loop
End
'so while you can choose PINB0 and PINB7,they must be both member of PINB
'this works on all PIN registers
Links:
Print "left rotation"
Return
Rechts:
Print "right rotation"
Return
End
ok, bereinigen wir das mal auf den wesentlichen Teil:
CodeBox BascomAVR
$regfile = "m128def.dat" ' specify the used micro
$crystal = 4000000 ' used crystal frequency (von wait-Instruktionen benötigt)
Dim B As Byte
'we have dimmed a byte because we need to maintain the state of the encoder
Portb = &B11 ' activate pull up registers
Do
B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1)
' ^--- 1 means wait for change which blocks programflow
' ^--------^---------- labels which are called
' ^-------^---------------------------- port PINs
Waitms 10 'Entprellung
Loop
End
Links:
'Code für erkannten Links-Schritt
Return
Rechts:
'Code für erkannten Rechts-Schritt
Return
End
Ok, für den zu wählenden Controller ist einfach dessen Definitionsdatei in Zeile 1 anzugeben, ich habe hier grad den Tiny2312A zur Hand.
Die tatsächliche Taktfrequenz (Zeile 2) benötigt BASCOM hier für die Berechnung der Warteschleifen, mein Tiny taktet mit 8MHz internem Oszillator.
Die zu verwendenden Pins wollen wir einfach austauschbar haben, also definieren wir uns dafür Compilernamen mittels Alias:
CodeBox BascomAVR
'### Eingänge 1 und 2, gelesen wird das PIN-Register, müssen zum selben Port gehören ###
Epin Alias Pinb 'Pinregister fürs lesen
Eport Alias Portb 'Portregister für die Pullups
E1 Alias 0
E2 Alias 1
'### Ausgänge 1 und 2, geschrieben wird das Port-Register ###
A1 Alias Portb.2
A2 Alias Portb.3
Beim Eingangsport wird das Port-Register für die Pullups benötigt, das Pin-Register für den Lesezugriff.
Die Eingänge werden bei der Encoder Instruktion verwendet:
CodeBox BascomAVR
B = Encoder(epin.e1 , Epin.e2 , Links , Rechts , 1)
Für die Wahl des Modus (Richtung+Puls vs. L-R-Pulse) könnte man beides implementieren, ich definiere 'ne Kompilerkonstante und verwende später bedingte Kompilierung:
CodeBox BascomAVR
'### Betriebsmodus: 1= Direction + Pulse, 0= Links- und Rechts-Pulse ###
Const Dirpulsemode = 1
Ebenso ob die Ausgänge H- oder L-aktiv sein sollen:
CodeBox BascomAVR
'### Zustand der Ausgänge: 1= H-aktiv, 0=L-aktiv
Const H_active = 0
Außerdem noch die Entprell(warte)zeit und die Pulsdauer als Konstanten:
CodeBox BascomAVR
'### Entprellwartezeit in ms ###
Const Debouncetime = 10
'### Pulszeit in µs ###
Const Pulsetime = 100
Bis hier noch kein neuer Code...
Los geht's - die Ausgänge müssen entsprechend der vorgegebenen Modi in Grundstellung gebracht werden (bedingte Kompilierung):
CodeBox BascomAVR
'Ausgänge in (modiabhängigen) Grundzustand bringen:
#if H_active = 0
Set A2
#if Dirpulsemode = 0
Set A1
#endif
#endif
Config A1 = Output
Config A2 = Output
Bei den Eingängen sind die Pullups zu aktivieren:
CodeBox BascomAVR
'Pullups der Eingänge aktivieren
Set Eport.e1
Set Eport.e2
In der Hauptprogrammschleife beim Encoder-Aufruf die Aliases ersetzen, hatte ich schon; bei der Wait-Instruktion die definierte Konstante rein.
Die beiden Encoder-Ergebnisroutinen:
CodeBox BascomAVR
Links:
'Code für erkannten Links-Schritt
#if Dirpulsemode = 1 'bei DirPulseMode
Reset A1
#if H_active = 0 'L-aktive
Reset A2
Waitus Pulsetime
Set A2
#else 'H-aktiv
Set A2
Waitus Pulsetime
Reset A2
#endif
#else 'bei L-R-Mode
#if H_active = 0 'L-aktiv
Reset A1
Waitus Pulsetime
Set A1
#else 'H-aktiv
Set A1
Waitus Pulsetime
Reset A1
#endif
#endif
Return
Rechts:
'Code für erkannten Rechts-Schritt
#if Dirpulsemode = 1 'bei DirPulseMode
Set A1
#if H_active = 0 'L-aktive
Reset A2
Waitus Pulsetime
Set A2
#else 'H-aktiv
Set A2
Waitus Pulsetime
Reset A2
#endif
#else 'bei L-R-Mode
#if H_active = 0 'L-aktiv
Reset A2
Waitus Pulsetime
Set A2
#else 'H-aktiv
Set A2
Waitus Pulsetime
Reset A2
#endif
#endif
Return
Alles nochmal zusammen:
CodeBox BascomAVR
$regfile = "ATtiny2313A.DAT" ' specify the used micro
$crystal = 8000000 ' used crystal frequency (von wait-Instruktionen benötigt)
'### Eingänge 1 und 2, gelesen wird das PIN-Register, müssen zum selben Port gehören ###
Epin Alias Pinb 'Pinregister fürs lesen
Eport Alias Portb 'Portregister für die Pullups
E1 Alias 0
E2 Alias 1
'### Ausgänge 1 und 2, geschrieben wird das Port-Register ###
A1 Alias Portb.2 '=Direction oder Left
A2 Alias Portb.3 '=Pulse oder Right
'### Betriebsmodus: 1= Direction + Pulse, 0= Links- und Rechts-Pulse ###
Const Dirpulsemode = 1
'### Zustand der Ausgänge: 1= H-aktiv, 0=L-aktiv ###
Const H_active = 0
'### Entprellwartezeit in ms ###
Const Debouncetime = 10
'### Pulszeit in µs ###
Const Pulsetime = 100
'###########################################################
'Ausgänge in (modiabhängigen) Grundzustand bringen:
#if H_active = 0
Set A2
#if Dirpulsemode = 0
Set A1
#endif
#endif
Config A1 = Output
Config A2 = Output
Dim B As Byte
'we have dimmed a byte because we need to maintain the state of the encoder
'Pullups der Eingänge aktivieren
Set Eport.e1
Set Eport.e2
Do
B = Encoder(epin.e1 , Epin.e2 , Links , Rechts , 1)
' ^--- 1 means wait for change which blocks programflow
' ^--------^---------- labels which are called
' ^-------^---------------------------- port PINs
Waitms Debouncetime 'Entprellung
Loop
End
Links:
'Code für erkannten Links-Schritt
#if Dirpulsemode = 1 'bei DirPulseMode
Reset A1
#if H_active = 0 'L-aktive
Reset A2
Waitus Pulsetime
Set A2
#else 'H-aktiv
Set A2
Waitus Pulsetime
Reset A2
#endif
#else 'bei L-R-Mode
#if H_active = 0 'L-aktiv
Reset A1
Waitus Pulsetime
Set A1
#else 'H-aktiv
Set A1
Waitus Pulsetime
Reset A1
#endif
#endif
Return
Rechts:
'Code für erkannten Rechts-Schritt
#if Dirpulsemode = 1 'bei DirPulseMode
Set A1
#if H_active = 0 'L-aktive
Reset A2
Waitus Pulsetime
Set A2
#else 'H-aktiv
Set A2
Waitus Pulsetime
Reset A2
#endif
#else 'bei L-R-Mode
#if H_active = 0 'L-aktiv
Reset A2
Waitus Pulsetime
Set A2
#else 'H-aktiv
Set A2
Waitus Pulsetime
Reset A2
#endif
#endif
Return
End
Kann das mal wer testen?? Controller, Taktfrequenz, Konstanten/Aliases und die Modi nach Wunsch vorgeben und dann compilieren/brennen/testen...