Bascom PCINT Pin abfragen

dimmu

Neues Mitglied
11. Juli 2011
54
0
0
Schömberg bei Neuenbürg
Sprachen
  1. BascomAVR
Hallo alle zusammen,

Ich hoffe ich bin hier richtig. In meinem nächsten Projekt will ich bei einem Attiny 13 die PCINT Eingänge benutzen.

Als erstes habe ich mir mal das Datenblatt angeschaut. Da ich überhaupt nicht verstanden habe,:confused: habe ich mir dann alles was die Interrupts betrifft mal ins Deutsche übersetzt.

Soweit habe ich folgendes Verstanden.:hmmmm::hmmmm:

Ich muss die Interrupts global einschalten. Ich muss dem Controller sagen, dass ich die PCINTs benutzen will, und ich muss ihm sagen welche Pins genau. Dazu sieht mein Programm so aus.

Code:
Sreg.7 = 1                                                  'Globale Interrupts einschalten
Gimsk.5 = 1                                                 'PCInterrupt einschalten
On Pcint0 Interrupt                                         'Springe zu Interrupt
Pcmsk = &B00000011                                          'Einschalten pcint0 pcint1 (portb.0 portb.1)

Nun zum eigentlichen Problem. :confused::confused::confused:
Der PCINT löst ja sowohl bei fallender als auch bei steigender Flanke ein Interrupt aus. Ich will aber nur, dass die fallende Flanke einen auslöst. Nach allem was ich bis jetzt gelesen habe muss ich das selber in meiner Interrupt Routine auswerten. Hierzu fällt mir allerdings kein Befehl ein.
Die fallende Flanke wird von einem anderen MC ausgelöst, ich muss mich also nicht um Taster prellen oder so etwas kümmern.
Mit der Forumssuche konnte ich leider auch nichts finden.

Das zweite Problem was ich habe, ich möchte zwei Pins benutzen. Dazu muss ich in der Interrupt Routine erst mal abfragen welcher Pin den Interrupt ausgelöst hat. Geht das so einfach mit If Pinb.0 = 0 Then? Oder muss ich dazu einen anderen Befehl benutzen.

Danke für eure Unterstützung:D
Timo
 

Anhänge

  • 9.2. Externe Interrupts.pdf
    95,7 KB · Aufrufe: 85
Im wesentlichen hast Du das schon richtig verstanden.
Vorweg:
-Eigentlich solltest(!) Du die Bits in den I/O-Registern auch beim Namen nennen können, also "GIMSK.PCIE=1" bzw "SREG.I=1" - probiers mal aus...
-Zum de-/aktivieren der globalen Interrupts gibts eigene Befehle - in ASM sind das "SEI"/"CLI" (Set/Clear I-Flag), in Bascom "enable/disable interrupts"
waren beides nur Hinweise zur Übersichtlichkeit, klar - gehen tuts auch so...
-normalerweise macht man die Interrupts global erst dann scharf, wenn alles andere Bereit ist (als die eigentlichen Interrupts konfiguriert). Möglicherweise tritt ja ein auslösendes Event bereits ein, wenn man grad am konfigurieren ist...

Beim Tiny13 sind alle Pins an einen gemeinsamen PCINT angeschlossen. "PCINT0". Mit "On PCINT0 Adresse" wird die entsprechende Sprunganweisung im Interruptvektor eingetragen. Diese gilt dann also für alle Pins (die in PCMSK freigegeben sind) und für alle Flanken).
In PCMSK sensibilisiert Du also die einzelnen Pins.
Den PCINT0 als ganzes gibst Du in GIMSK frei.
(ggf andere Interrupts konfigurieren)
Globale Interrups freigeben.

Die ISR wird also immer dann aufgerufen, wenn irgendeiner der freigegebenen Pins in irgendeine Richtung umkippt.
Wenn Du nur einen Pin überwachst, und auch nur eine Flanke erkennen willst, kannst Du in der ISR den Zustand des Bits (PIN-Register) abfragen - vor dem Interrupt war es ja logischerweise genau andersrum als danach...
Wenn's mehrere Pins und/oder Flanken werden sollen, mußt Du Dir den letzten Zustand der relevanten Bits des Pinregisters merken (Puffern), und vergleichen...
 
Hallo LotadaC,


Zunächst vielen Dank für deine Antwort.

Nach deiner Bestätigung weiß ich nun, das mein Englisch nicht ganz eingerostet ist, und dass das übersetzten nicht ganz umsonst war.

Da ich leider noch auf meinen Tiny warte kann ich leider noch keine Versuche machen.

Für das erste Experiment würde ich gerne den PCINT 0 und PCINT 1 benutzten. Jeweils mit Erkennung der fallenden Flanke. Die Steigende benötige ich nicht.

Das mit der Abfrage des Pins in der ISR ist mir noch nicht so ganz klar.

Wenn ich die Zustand des Pins Pufferns soll, muss ich dazu eine Variable anlegen oder. Evtl könnte ich mir sowas vorstellen wie:

Ich lege ein Byte fest und definiere den Wert
Code:
Dim Puffer as Byte
Puffer = &B11111100

Jetzt vergleiche ich in der ISR

Code:
Puffer = Puffer and [COLOR=#ff0000]PCMSK 'Hier weiß ich nicht ob ich hier PCMSK schreiben darf oder ob es nicht Portb heißen muss.[/COLOR]

'Eigentlich müsste ich doch dann als Ergebnis bekommen, entweder 
'Puffer = &B00000001 oder 
'Puffer = &B00000010

'Dieses Ergebnis könnte ich doch dann mit 

IF Puffer = &B00000001 Then
…………. 
Elseif Puffer = &B00000010 Then
…………
Endif

Puffer = &B11111100

wieder auswerten können oder liege ich da falsch.
Ich bin mir allerdings nicht sicher ob ich dann nur die fallende Flanke erkenne oder auch die steigende

Danke
Timo
 
Ich würde das so angehen:

-die zu verwendenden Pins werden in einer Konstante (Compilervariable) abgelegt, dann können die später weiter verwendet werden, trotzdem kann das Programm einfach verändert werden. ZB "Const used_PCINT0=&B00000011". Diese kann dann also gleich zum Beschreiben des PCMSK verwendet werden ("PCMSK=used_PCINT0")
-Als Puffer (des letzten Status der Pins) benötigen wir ein Byte. Zur Initialisierung sollte aber der Ist-Zustand der relevanten Pins ausgelesen und zugewiesen werden. Direkt vorm Scharfmachen des Interruptes. In etwa so: "Puffer=PinB AND used_PCINT0". Du mußt das PIN-Register auslesen, und gleich die nicht zu überwachenden Beinchen ausmaskieren (vielleicht soll ja da später was anderes ran).
-In der ISR liest Du in eine temporäre Variable ebenso den Ist-Zustand ein ("Ist=PinB AND used_PCINT0") - hier hast Du also für jeden Pin die Pegelinformation (jedes Bit mit einer 1 ist Hi, die anderen (0) sind lo, oder werden nicht überwacht), Du weißt aber noch nicht, welcher den IRQ ausgelöst hatte. Dazu benötigst Du den Puffer. "Puffer=Puffer EOR Ist" liefert Dir jetzt eine 1 in allen Bits, die sich seit dem letzten mal geändert haben.
-Als letztes muß natürlich der Ist-Zustand in den Puffer geschrieben werden: "Puffer=Ist".

n welcher Form Du jetzt dazwischen diese Bits verarbeiten willst (die ISR sollte ja möglichst kurz bleiben) - also direkt auswerten, oder an das Hauptprogramm weiterreichen, hängt natürlich vom Umfang ab.
Vorschlag in etwa klar?

P.S.: bin mir mit dem exclusiven Oder bei Bascom nicht sicher, vielleicht heißt es da auch "XOR".
 
Hallo,

ich habe jetzt mal versucht das ganze in Code zu verpacken.

Code:
Const Used_pcint = &B00000011
 Dim Puffer As Byte
 Dim Ist As Byte
 Dim Int_1 As Bit
 Dim Int_0 As Bit

Gimsk.5 = 1                                                 'PCInterrupt einschalten
 Pcmsk = Used_pcint                                         'Einschalten pcint0 pcint1 (portb.0 portb.1)
 On Pcint0 Isr                                              'Springe zu Interrupt
 Sreg.7 = 1                                                 'Globale Interrupts einschalten


 Do

 If Int_0 = 1 Then
 .........
 Else
 .............
 End If

 Puffer = Pinb And Used_pcint                               'in Puffer müsste jetzt eigentlich &B00000011 stehen

 Loop

 Isr:                                                       'ISR wird angesprungen weil zb. PCINT0 nach GND gezogen wird
 Ist = Pinb And Used_pcint                                  'In ist müsste jetzt &B00000010 stehen
 Puffer = Puffer Xor Ist                                    'in Puffer müsste jetzt &B00000001 stehen

 [COLOR="#FF0000"]'So wie ich es sehe müsste ich ja an dieser stelle sehen welcher Pin den interrupt ausgelöst hat.[/COLOR]
 If Puffer = &B00000001 Then
 Int_0 = 0
 End If


 Puffer = Ist                                               'in puffer müsste jetzt &B00000010 stehen

 Return)

Ein paar dinge versethe ich allerdings noch nicht.
Aus welchem Grund möchtes du Puffer am Ende nochmal mit Ist gleichsetzten. Die Auswertung ist ja davor bereits getan, und wenn ich wieder in der Hauptschleife bin setzte ich Puffer ja sowieso wieder auf den used_PCINT.

Oder willst du das machen das nur die fallende Flanke erkannt wird?
 
Weil der Puffer den derzeitigen Ist-Zustand für den nächsten IRQ ... ähm ... puffern soll. Also für das dann erfolgende XOR.
"Puffer=PinB AND used_PCINT" soll nur einmal zur Initialisierung der Variable durchgeführt werden,also vor der Schleife.
Nach dem XOR hast Du den/die schuldigen Beinchen für den IRQ gefunden, korrekt. Aber welche Flanke das jetzt war (also genau genommen, welchen Pegel Du am entsprechenden Pin hast), weißt Du noch nicht. Das steht aber noch in der Ist-Variable.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)