PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Pinchange und Pegel feststellen gleichzeitig...



Willa
25.01.2010, 18:49
Hallo!
Ich habe da mal wieder eine offene Frage. Ich möchte am int1 ein Rechtecksignal abfragen (Summensignal RC-Empänger). Dabei ist die Dauer des high Zustands wichtig. Ich dachte ich mache es so:
Wenn Pegel steigt, timer auf null setzen. Wenn Pegel sinkt, Timerwert auslesen.
Mal vorweg - der Code funktioniert wunderbar. Mir ist aber nicht ganz klar warum. Obwohl ich ihn mir selbst ausgedacht habe.
Code läuft so ab: Ich habe den interrupt auf "change" konfiguriert um beide Events zu detektieren. Im Change interrupt frage ich nun als erstes ab ob der Pin high ist. Falls ja, dann wird die gestoppte Zeit übernommen, falls nein wird die MEssung für den nächsten Kanal vorbereitet.

Was ich nicht verstehe: Im idealen Fall eines Pin-Change interrupts, wäre zur zeit des interrupts der Pegel doch genau bei 2.5V, oder? Und damit wäre es dann Zufall ob das als high oder low zustand erkannt wird.
Außerdem verstehe ich nicht, warum ich im Interrupt als erstes nachfrage ob der Pegel high ist. Wenn er high ist, sollte der Pinchange interrupt doch eigentlich eine steigende Flanke detektiert haben. Und wenn der Pegel low ist sollte eine fallende Flanke detektiert worden sein.
Kann mir jemand bei diesen Unklarheiten weiterhelfen....?


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 38400
Config Timer0 = Timer , Prescale = 256 , Capture Edge = Falling
On Timer0 Detectrxpause
Config Int1 = Change
On Int1 Getreceiver
Config Pind.3 = Input

Dim Empf(5) As Integer
Dim Channel As Byte
Enable Timer0
Enable Interrupts
Enable Int1

Getreceiver:
If Pind.3 = 1 Then
Empf(channel) = Timer0
Else
Incr Channel
End If
Timer0 = 0
Return

Detectrxpause:
Channel = 0
Return

markusj
25.01.2010, 19:08
Punkt 1: Der PCINT wird ja durch einen erkannten Pegelwechsel getriggert, damit ließt du ja automatisch den Wert ein, der den PCTINT ausgelöst hat - außer der Pegel hat inzwischen noch einmal gewechselt ...

Punkt 2: Der PCINT wird ja auch bei der fallenden Flanke aufgerufen - irgendwie musst du ja erkennen, wann der Zählwert übernommen werden soll.

Geh mal ein Stück von der Leitung runter, dann wirds evtl. klarer :P

mfG
Markus

oberallgeier
25.01.2010, 19:15
... wäre zur zeit des interrupts der Pegel doch genau bei 2.5V ...Das Problem hatte ich auch mal gewälzt. Und dann gelesen:

[/size]EL-doc 8161D–AV R–10/09]The External Interrupt 0 is activated by the external pin INT0 if the SREG I-flag and the corresponding interrupt mask are set. The level and edges on the external INT0 pin that activate the interrupt are defined in Table 12-2. The value on the INT0 pin is sampled before detecting edges. If edge or toggle interrupt is selected, pulses that last longer than one clock period will generate an interrupt. Shorter pulses are not guaranteed to generate an interrupt. If low level interrupt is selected, the low level must be held until the completion of the currently executing instruction to generate an interrupt.Und dieses Sample untersucht dann jemand . . . nehme ich an.

Willa
25.01.2010, 19:17
Der PCINT wird ja durch einen erkannten Pegelwechsel getriggert, damit ließt du ja automatisch den Wert ein, der den PCTINT ausgelöst hat - außer der Pegel hat inzwischen noch einmal gewechselt ...
Achso? Ich dachte ein change wird detektiert, dann springt er in die interrupt routine und guckt nach was jetzt für ein Pegel anliegt.
Ich hab grad soweso festgestellt, dass nicht die dauer des high-pegels die kanäle codiert, sondern die Zeit von rising zu rising...
@oberallgeier: danke sehr

for_ro
25.01.2010, 19:59
Was ich nicht verstehe: Im idealen Fall eines Pin-Change interrupts, wäre zur zeit des interrupts der Pegel doch genau bei 2.5V, oder? Und damit wäre es dann Zufall ob das als high oder low zustand erkannt wird.
Wenn die ISR aufgerufen wird, macht BASCOM zunächst mal die Push-Orgie der Register. Bis die abgeschlossen ist (53 Takte) ist dein Signal längst auf dem Endpegel angekommen. Dann erst kommt deine Abfrage nach dem Pind.3.

markusj
25.01.2010, 21:03
for_ro: Selbst wenn man die Register-Pusherei von BASCOM mal vernachlässigt, kann es da kein Problem geben.
Der Pin-Change wird ja auf Basis der Eingangslogik erkannt, die den Wert im PINxn ausgibt - Ergo kann es da keine Mehrdeutigkeiten geben.

@William:
Woher soll der AVR das denn können/wissen was du mit dem konkreten Pegel machst?
Der AVR springt einfach nur in die ISR, wenn die von dir konfigurierte Bedingung (Signalwechsel), erkannt wird - was du daraus machst, ist dir überlassen. Insbesondere steht dir der Wert der den Interrupt ausgelöst hat, nicht zur Verfügung, der wird nicht zwischengespeichert.
Wenn du den Status der Eingangsregister abfragst, entspricht das dem aktuellen Wert - immer. Unter Umständen verpasst du so bei einer hinreichend langsamen Reaktion die komplette High/Low-Phase des Signals und liest den gleichen Wert ein, der zuvor am Eingang herrschte.

mfG
Markus