ThSteier
17.07.2005, 21:44
Hallo allerseits,
ich grübele hier gerade an einer Auswerteroutine für einen Inkrementaldrehgeber und habe dabei noch ein Verständnisproblem. Das Programm
$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 32
$framesize = 32
Dim Q_in As Byte ' aktuelle Werte am Eingang
Dim Q_alt As Byte 'Eingangswert vom letzten Zyklus
Dim Test As Byte
Dim Ud As Byte 'Drehrichtung, nur für Test
Config Portd = &B11111100 'Eingänge festlegen
Do
Q_in = Portd And &B00000011 'Ports D0 und D1 einlesen
Test = Q_alt Xor Q_in 'Wert geändert?
If Test = 0 Then
Goto Ende 'nein: Auswertung überspringen
End If
Rotate Q_alt , Right , 1 'vorherigen Wert rechtsverschieben
Ud = Q_alt Xor Q_in 'Drehrichtung bestimmen
Ud = Ud And 1
If Ud = 0 Then
Print "L"
Else
Print "R"
End If
Ende:
Q_alt = Q_in
Loop
End
funktioniert soweit, frißt allerdings durch das Polling gewaltig Rechenleistung.
Nun könnte man die Auswertung doch theoretisch auch in eine Interruptroutine packen, die jedesmal ausgelöst wird, wenn sich der Zustand der Eingänge ändert. Allerdings habe ich keine Idee, wie man ein und den selben IRQ auf beide Eingangspins legen kann. INT0 und INT1 zu verwenden, klappt hier (zumindest im BASCOM-Simulator) irgendwie nicht. Mal das Programm dazu:
$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 32
$framesize = 32
Dim Q_in As Byte ' aktuelle Werte am Eingang
Dim Q_alt As Byte 'Eingangswert vom letzten Zyklus
Dim Ud As Byte 'Drehrichtung, nur für Test
Config Portd = &B11110011 'Eingänge festlegen
Enable Interrupts
Enable Int0
Enable Int1
On Int0 Auswertung
On Int1 Auswertung
Do
Loop
Auswertung:
Q_in = Portd And &B00001100 'Ports D2 (INT0) und D3 (INT1) einlesen
Rotate Q_in , Right , 2 'Bits rechtsbündig verschieben
Rotate Q_alt , Right , 1 'vorherigen Wert rechtsverschieben
Ud = Q_alt Xor Q_in 'Drehrichtung bestimmen
Ud = Ud And 1
If Ud = 0 Then
Print "L"
Else
Print "R"
End If
Q_alt = Q_in
Return
End
Obwohl die gleiche Routine wie bei der Polling-Variante zum Einsatz kommt (die Überprüfung auf Zustandsänderung wird hier ja nicht gebraucht), stehen mir bei der Simulation alle Haare zu Berge: die Interruptroutine scheint nicht nur auf Flankenwechsel an D2 und D3, sondern auch (aber nur sporadisch) an anderen Pins zu reagieren - und liefert keine reproduzierbaren Ergebnisse.
Ich habe mir hier schon den Kopf blutig gekratzt, aber mir fällt einfach nicht ein, wo der Fehler sitzen könnte. Oder liegt es eher am Simulator? In Hardware kann ich es leider noch nicht testen, die Platine ist noch nicht fertig...
rätselnderweis,
Thomas
ich grübele hier gerade an einer Auswerteroutine für einen Inkrementaldrehgeber und habe dabei noch ein Verständnisproblem. Das Programm
$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 32
$framesize = 32
Dim Q_in As Byte ' aktuelle Werte am Eingang
Dim Q_alt As Byte 'Eingangswert vom letzten Zyklus
Dim Test As Byte
Dim Ud As Byte 'Drehrichtung, nur für Test
Config Portd = &B11111100 'Eingänge festlegen
Do
Q_in = Portd And &B00000011 'Ports D0 und D1 einlesen
Test = Q_alt Xor Q_in 'Wert geändert?
If Test = 0 Then
Goto Ende 'nein: Auswertung überspringen
End If
Rotate Q_alt , Right , 1 'vorherigen Wert rechtsverschieben
Ud = Q_alt Xor Q_in 'Drehrichtung bestimmen
Ud = Ud And 1
If Ud = 0 Then
Print "L"
Else
Print "R"
End If
Ende:
Q_alt = Q_in
Loop
End
funktioniert soweit, frißt allerdings durch das Polling gewaltig Rechenleistung.
Nun könnte man die Auswertung doch theoretisch auch in eine Interruptroutine packen, die jedesmal ausgelöst wird, wenn sich der Zustand der Eingänge ändert. Allerdings habe ich keine Idee, wie man ein und den selben IRQ auf beide Eingangspins legen kann. INT0 und INT1 zu verwenden, klappt hier (zumindest im BASCOM-Simulator) irgendwie nicht. Mal das Programm dazu:
$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 32
$framesize = 32
Dim Q_in As Byte ' aktuelle Werte am Eingang
Dim Q_alt As Byte 'Eingangswert vom letzten Zyklus
Dim Ud As Byte 'Drehrichtung, nur für Test
Config Portd = &B11110011 'Eingänge festlegen
Enable Interrupts
Enable Int0
Enable Int1
On Int0 Auswertung
On Int1 Auswertung
Do
Loop
Auswertung:
Q_in = Portd And &B00001100 'Ports D2 (INT0) und D3 (INT1) einlesen
Rotate Q_in , Right , 2 'Bits rechtsbündig verschieben
Rotate Q_alt , Right , 1 'vorherigen Wert rechtsverschieben
Ud = Q_alt Xor Q_in 'Drehrichtung bestimmen
Ud = Ud And 1
If Ud = 0 Then
Print "L"
Else
Print "R"
End If
Q_alt = Q_in
Return
End
Obwohl die gleiche Routine wie bei der Polling-Variante zum Einsatz kommt (die Überprüfung auf Zustandsänderung wird hier ja nicht gebraucht), stehen mir bei der Simulation alle Haare zu Berge: die Interruptroutine scheint nicht nur auf Flankenwechsel an D2 und D3, sondern auch (aber nur sporadisch) an anderen Pins zu reagieren - und liefert keine reproduzierbaren Ergebnisse.
Ich habe mir hier schon den Kopf blutig gekratzt, aber mir fällt einfach nicht ein, wo der Fehler sitzen könnte. Oder liegt es eher am Simulator? In Hardware kann ich es leider noch nicht testen, die Platine ist noch nicht fertig...
rätselnderweis,
Thomas