-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Interrupt-Verwirrnisse / Quadraturdecoder

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.07.2005
    Alter
    46
    Beiträge
    179

    Interrupt-Verwirrnisse / Quadraturdecoder

    Anzeige

    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

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.07.2005
    Alter
    46
    Beiträge
    179
    Hm, man sollte die Datenblätter wirklich sorgfältiger lesen...

    Wenn ich nicht völlig danebenliege, hängen meine Probleme mit den Interruptmasken zusammen. INT0 scheint hier bei jedem Flankenwechsel auszulösen und INT1 nur beim Hi/Lo-Wechsel. Was uns zu der Frage bringt, wie man diese Register (konkret MCUCR) in Bascom direkt beschreiben kann.

    Oder gibt es eine Möglichkeit, den PCINT-Interrupt zu nutzen? Die Hilfe schweigt sich dazu leider aus.

    Ich wäre für jeden Hinweis dankbar.

    Viele Grüße,
    Thomas

    EDIT: Ich bin wirklich blind - oder man sollte um diese Zeit einfach nicht mehr vorm PC sitzen...
    Allerdings hilft mir das Setzen von MCUCR (auf &Bxxxx0101 entsprechend "interrupt at logical change") irgendwie auch nicht weiter: das sperrt INT0 und INT1 gleich völlig. Ich glaube, ich schlafe erstmal drüber...

  3. #3
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Zwischenfrage, bevor wir uns vertiefen: Welche Bascom Version verwendest du ?
    1.11.7.4 oder
    1.11.7.7 ( 8 )
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.07.2005
    Alter
    46
    Beiträge
    179
    Hier werkelt seit dem Wochenende die 1.11.7.9 in der Demo-Version. Vorher wars die 1.11.7.7 - ich habe das Update eigentlich nur wegen der ATTiny-Libs drübergejagt...

    Der entsprechende Programmabschnitt sieht inzwischen so aus:
    Code:
    Config Portd = &B11110011                                   'Eingänge festlegen
    
    Enable Interrupts
    
    Enable Int0
    Enable Int1
    
    Mcucr.0 = 1                                                 'INT0 auf "on logical change" setzen
    Mcucr.1 = 0
    
    Mcucr.2 = 1                                                 'INT1 auf "on logical change" setzen
    Mcucr.3 = 0
    
    On Int0 Auswertung
    On Int1 Auswertung
    Die Bits stehen anschließend auch korrekt im MCRCU-Register - werden aber ignoriert.

    Viele Grüße,
    Thomas

  5. #5
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Der blöden Fragen kein Ende: Bist du sicher, daß das ein
    Attiny2313 ist und nicht ein 90S2313 ? Weil letzterer kann das nicht mit beiden flanken
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.07.2005
    Alter
    46
    Beiträge
    179
    Ich bin mir eigentlich sicher (siehe $regfile = "attiny2313.dat"), aber der Compiler vielleicht nicht. Die dat-Files sagen mir leider ungefähr das gleiche wie ein chinesisches Telefonbuch, so daß ich da gar nicht erst nachzuschauen brauche

    Ich werde das Programm morgen mal auf der RNControl testen - mal schauen, was die dazu sagt. Und wenn's dort klappt, muß ich mal schauen, ob ich den ATTiny provisorisch verdrahten kann. Irgendwann muß ich mir doch mal 'ne einfache Experimentierplatine für den ATTiny basteln...

    Viele Grüße,
    Thomas

  7. #7
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Du mußt im Datenblatt schauen, ob der Chip überhaupt BEIDE Flanken kann.
    Der Atmega32 z.B. kann es NICHT (und 90S2313 auch nicht)
    Simulator weiß ich nicht, verwend' ich nie.
    Probier mal, ob du nicht mit EINER Flanke fürs Erste auch zurechtkommst.
    Kann dir jetzt nix besseres anbieten, die Statements im Programm stimmen, da is nix. Du hast es ja auch kontrolliert.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.07.2005
    Alter
    46
    Beiträge
    179
    Seltsam. Laut den Datenblätt sollten es sowohl der Tiny2313 und der Mega32 können (zumindest würde ich die zweite Zeile in "Table 32" so interpretieren), die entsprechenden Seiten sind jedenfalls identisch und Errata habe ich dazu bisher nicht gefunden. Ich hab mal 'nen Schreenshot angehängt.

    Zu der Auswertung nur einer Flanke habe ich bisher keine Idee. Hab auch schon überlegt, aber im schlimmsten Fall können dabei zwei Übergänge "durchrutschen", bis wieder ein "gültiger" Flankenwechsel kommt und den Interrupt auslöst.

    Viele Grüße,
    Thomas
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken attiny2313.jpg  

  9. #9
    warum nicht
    config int0 = rising / falling

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    29.10.2004
    Ort
    GRAZ
    Alter
    51
    Beiträge
    576
    Hallo

    Hier gibt es ein Beispiel in Basic für eine Vierfachauswertung für einen Encoder
    (läuft bei mir am Mega8 ohne Probleme)
    http://www.mikrocontroller.net/forum...37689.html#new

    Aber auf der Home von MCS gibt es auch ein Beispiel für normale Auswertung:
    http://www.mcselec.com/an_115.htm
    Funktioniert auch gut

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •