Hallo allerseits,

ich grübele hier gerade an einer Auswerteroutine für einen Inkrementaldrehgeber und habe dabei noch ein Verständnisproblem. Das Programm
Code:
$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:
Code:
$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