PCINT Verständnisproblem

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • PCINT Verständnisproblem

      Hallo,
      ich habe ein Programm auf einen Atmega8 laufen, dabei sind
      PD2 und PD3 als int0 und int 1mit eigenen isr´s belegt.
      Nun bräuchte für eine Programmerweiterung ich einen weiteren Interrupt.
      Ich müsste den dafür schon vorhandenen Eingang PD4 als Interrupt konfigurieren.
      Nach meiner Meinung könnte ich den Atmega8 durch einen pinkompatiblen Atmega88 ersetzen.
      Nur ist mir nicht klar, wie ich den/die Pcint konfiguriere.
      Zur jetzigen Belegung
      PD0=Eingang
      PD1=Eingang
      PD2= Eingang (Int0), soll so bleiben
      PD3=Eingang (Int1), soll so bleiben
      PD4=Eingang, soll Interrupt werden
      PD5= Ausgang, soll so bleiben
      PD6= Eingang, soll so bleiben
      PD7= Eingang, soll so bleiben

      Wenn ich die Anleitung richtig verstanden habe, müsste ich nun den ganzen PortD als Interrupt-Eingang definieren, und dann in der zugehörigen isr die Abfrage machen, welcher Pin ausgelöst hat (und dann den zugehörigen Code ausführen)

      Meine Überlegungen dazu:
      Nur wenn jeder Eingang als Interrupt wirkt, könnte es Timing-Probleme geben?
      Was mache ich mit dem Ausgang?
      Kann ich die für die übrigen Eingänge (ohne Interrupt-Funktion) den Sprung in die ISR unterbinden?

      Danke
      Gruß
      Hans
      Gruß
      Hans
    • Der Port wird maskiert. Es können also nur die pins einen interrupt auslösen, die durch die Maske ausgewählt wurden. Aber, alle ausgewählten pin springen in eine isr. Daher musst du in der isr heraus finden, welcher pin jetzt den interrupt ausgelöst hat. Wenn du nur einen pin eines ports maskierst, dann ist das ja eindeutig.

      PD.4 hat den PCINT20. Dafür ist zum maskieren PCMSK2 zuständig und davon bit4.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tschoeatsch ()

    • Ne, könnte man meinen, ist aber leider nicht so.
      Du musst die Gruppe als interruptquelle frei geben. Pcint20 gehört zur Gruppe pcint2. Die '2' findest du ja auch bei der Maske.
      pcmsk2.4=1
      on pcint2 pcint20_isr
      enable pcint2
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • funktioniert aber nicht,
      kann man da nicht auch = rising vorgeben?
      der Eingang wechselt ja, (Rechteckimpuls) offensichtlich reagiert der Interrupt auf steigende und fallende Flanken, er soll aber nur auf steigende reagieren,
      außerdem ist im Buch von s. Hoffmann geschrieben Pcmsk.3=1, lt Kommentar soll das enable Pcint3 sein, das ist dann doch wohl falsch?
      Die Bascom-Hilfe liefert zu Pcint überhaupt nichts,
      Gruß
      Hans
    • Hans_L schrieb:

      kann man da nicht auch = rising vorgeben?
      PCINT heißt ausbuchstabiert "Pin Change INTerrupt". Sie werden also von jeder Pegeländerung ausgelöst, eine primäre Differenzierung in falling und rising ist nicht möglich.
      Es gibt aber z.B. den kleinen Umweg, in der ISR den auslösenden Pin abzufragen, und die gewünschte Aktion nur bei einem der beiden möglichen Levels zu starten.

      Und PCMSK.3=1 bewirkt lediglich, dass die Interrupt-Funktion für den dazugehörigen Eingangspin sozusagen "freigeschaltet" wird.
      Den ganzen PC-Interrupt und die globalen Interrupts musst Du natürlich gesondert enablen.
    • Hans_L schrieb:

      kann man da nicht auch = rising vorgeben?
      Im Datenblatt steht When a logic change on any PCINT[23:16] pin triggers an interrupt request, also ein Wechsel. In welcher Richtung, ist nicht wählbar. Wenn du ein 'rising' erkennen willst, dann musst du in der isr einfach den pin auf 'jetzt gesetzt' abfragen, dann war er wohl vor dem interrupt auf low und hat mit dem Wechsel zu high den interrupt ausgelöst.
      Welche pcint# zu welcher Gruppe gehört, ist kontrollerabhängig. Die ports sind ja nicht immer 8 bit breit, die pcint werden aber durch nummeriert. Ich beziehe mich auf den mega48..mega328 Kontroller.
      Wenn das enable pcint2.. nicht geht, dann setze doch mal die nötigen bits in den Registern direkt. Im Datenblatt steht
      When the PCIE2 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt 2 is
      enabled. Any change on any enabled PCINT[23:16] pin will cause an interrupt. The corresponding interrupt of
      Pin Change Interrupt Request is executed from the PCI2 Interrupt Vector. PCINT[23:16] pins are enabled
      individually by the PCMSK2 Register.
      Um den interrupt zu enablen muss das PCIE2 bit gesetzt werden, das ist im PCICR (Pin Change Interrupt Control Register) bit2, also set PCICR.2. Dann könnte es weiter gehen mit
      on PCI2 Pcint20_isr. Ich muss mal in der .dat nachsehen, ob diese Registerbezeichnungen da enthalten sind...
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hans_L schrieb:

      außerdem ist im Buch von s. Hoffmann geschrieben Pcmsk.3=1, lt Kommentar soll das enable Pcint3 sein, das ist dann doch wohl falsch?
      doch, das ist richtig. Da wird ein attiny13 verwendet, der hat nur eine Gruppe von pcint. Daher nur ein Register pcmsk, ohne weitere Nummerierung. Und bei diesem Beispiel wird auf fallende Flanke geprüft.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • tuts nicht,

      Quellcode

      1. Config Pind.1 = Input 'brauche ich das?
      2. Config Pind.4 = Input
      3. Enable Pcint2
      4. Pcmsk2.4 = 1
      5. On Pcint2 Pcint20_isr
      6. A Alias Pind.4 ' PCint Inkremetalgeber Kanal -A-
      7. B Alias Pind.1 ' Inkremetalgeber Kanal -B-
      8. Portd.1 = 0 'Pullups ausschalten, muss ich das?
      9. Portd.4 = 0
      10. Dim Outword As Long
      11. Dim U As Long
      12. U = 0
      13. Outword = 0
      14. Const Delete_line = " "
      15. Enable Interrupts
      16. Cls
      17. 'Hauptschleife
      18. Do
      19. Locate 1 , 1
      20. Lcd Delete_line
      21. Locate 1 , 1
      22. Lcd Outword
      23. U = Outword / 2500 'Striche des Gebers/Umdrehung
      24. Locate 2 , 1
      25. Lcd Delete_line
      26. Locate 2 , 1
      27. Lcd U
      28. Locate 3 , 1
      29. Lcd A
      30. Locate 4 , 1
      31. Lcd B
      32. Loop
      33. End
      34. Pcint20_isr:
      35. If A = 0 Then 'wenn Kanal B auf 0 geht, soll die ISR nicht bearbeitet werden
      36. Return
      37. End If
      38. If B = 0 Then 'Kanal geht auf 1, Isr soll abgearbeitet werden
      39. Incr Outword
      40. Else
      41. Decr Outword
      42. End If
      43. Return
      Alles anzeigen

      mal sehen, ob ich den Code richtig eingefügt habe,

      also das Progrämmchen hat mit Int0 einwandfei funktioniert,
      neu sind die Zeilen 6 bis 8 und
      49 bis 51, dort soll die Abfrage auf steigende Flanke erfolgen
      Gruß
      Hans
    • Hm, jetzt bin ich mir nicht sicher. Ein Return einer isr ist ein anderes return als von einer sub. Im Assembler gibt es reti, return from interrupt und ret, einfach return. In deiner isr verwendest du mitten im code ein return, das könnte als 'falsches' (ret) verwendet werden. Das reti setzt meines Wissens die interrupt-flags zurück, damit ein erneuter interrupt ausgeführt werden kann. Um diese Unsicherheit zu umgehen, würde ich die isr etwas umbauen, sodass kein return in der Mitte nötig ist.

      BASCOM-Quellcode

      1. Pcint20_isr:
      2. If A = 1 Then 'wenn Kanal A auf 0 geht, soll die ISR nicht bearbeitet werden
      3. If B = 0 Then 'Kanal geht auf 1, Isr soll abgearbeitet werden
      4. Incr Outword
      5. Else
      6. Decr Outword
      7. End If
      8. End If
      9. Return
      probiere das doch mal.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hans_L schrieb:

      warum schweigt sich die Hilfe bei dem Thema PCINT so beharrlich aus, da ist ja absolut nichts zu finden?
      Man soll halt ab und zu bisschen tüfteln. a_15_a5ddcf85
      Das mit dem reti weiß ich auch nur von meinen spärlichen Versuchen mit Assembler zu programmieren, das wird auch nicht in der Hilfe stehen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • BASCOM-Quellcode

      1. $regfile = "m1284pdef.dat"
      2. E_int1_pcint Alias Portb.1
      3. E_int0_pcint Alias Portb.0
      4. Config E_int1_pcint = Input
      5. Set E_int1_pcint 'activate pull up
      6. Config E_int0_pcint = Input
      7. Set E_int0_pcint 'activate pull up
      8. Enable Pcint0 'we enable pcint0 as this has pcint8-pcint9
      9. On Pcint0 Isr_pcint8 'we jump to this label when one of the pins is changed
      10. Enable Pcint1 'we enable pcint0 as this has pcint8-pcint9
      11. On Pcint1 Isr_pcint8_9 'we jump to this label when one of the pins is changed
      12. 'Pcmsk0 = &B00001111 'enable pcint0-pcint3 (portb.0-portb.3)
      13. Pcmsk1 = &B00000011 'enable pcint8-pcint9 (portb.0-portb.1)
      14. '----------------------------[ Isr_pcint8 ]----------------------------------------
      15. Isr_pcint8:
      16. 'Taste_3
      17. 'Print "Pin change 8 " ; Bin(pcmsk1) ; Spc(3) ; Bin(pinb)
      18. 'As you see the mask does not change, so to find out which pin changed,
      19. 'you need to read the PINB register.
      20. 'Print "Taster 3 PC8"
      21. 'Print "Isr_pcint8"
      22. Return
      23. '-------------------------------------------------------------------------------------
      Alles anzeigen
      Gruß Holger
      link zu mir..
      forum.auto-steuerung.de
      ___
    • noch eine Frage zu PCInt, beeinflusst die Funktion (so wie weiter oben beschrieben) irgendwie die anderen Interrupts (Int0, Int1)?
      Die tun nicht mehr so wie sie sollen
      (Die Auswertung für den Drehgeber funktioniert, so wie sie soll)
      Gruß
      Hans

      Nachtrag:
      nachdem die ja zur gleichen Gruppe gehören, müsste ich die auch in der PCint_isr abfangen?
      funktioniert da die Abfrage über Int0 und Int1 nicht mehr?
      Gruß
      Hans

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Hans_L ()

    • Wenn ein input 2 verschiedene interrupts auslösen kann, dann wird nach einer Prioritätenliste die interrupts abgearbeitet. INTx hat Vorrang vor PCINTx
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • war vielleicht mißverständlich,
      auf Int0 und int1 gehen jeweils ein Taster, auf den Pcint geht Kanal A des Drehgebers,
      dieser Eingang wird problemlos erkannt und ausgewertet, nur die beiden Taster werden nicht mehr erkannt.
      Bevor ich die die Funktion PCint eingebaut habe, haben die beiden Taster auch einwandfrei funktioniert.
      Darum jetzt die Frage, ob durch die Konfiguration des Pcint die anderen beiden Interrupts "ausgeschaltet" wurden
      Gruß
      Hans
      Gruß
      Hans
    • Wenn die pins von INTx nicht in der Maske des PCINT als interruptgeber markiert sind, dann sollten die da auch keinen interrupt auslösen.
      Zeig mal dein Programm
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------