PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Unverständliches Problem mit INT0 / INT1



popi
04.09.2008, 11:46
Hallo zusammen,

wie beschrieben habe ich die notwendigen Interrupts aktiviert:


Enable Int0
Config Int0 = Rising
On Int0 Isr_von_int0
Enable Interrupts

Bei einem Interrupt wird dessen Code aber 2x hintereinander ausgeführt, merk ich an der kurz pulsierernden LED am PORTD.6:


Isr_von_int0:
If Schrittweite < 5 Then
Incr Schrittweite
Pulseout Portd , 6 , 5000
End If
Return

Um das Prellen "notdüftig" und zu testzwecken zu unterbinden, habe ich ein delay eingebaut, aber auch hiermit wird der code wieder 2x ausgeführt (2 maliges pulsieren der PORTD.6 LED)


Isr_von_int0:
waitms 1000
If Schrittweite < 5 Then
Incr Schrittweite
Pulseout Portd , 6 , 5000
End If
Return

Was übersehe ich denn da???

Grüße

popi

PicNick
04.09.2008, 12:04
Popi, Kollege, das "Waitms 1000" alleine ist ja noch kein entprellen.
Du mußt danach schauen, ob der INT0-Eingang immer noch = 1 ist, und NUR DANN machst du auch den Rest von der ISR.
Wobei 1 ganze Sekunde etwas viel scheint.


ISR_VON_INT0:
Waitms 1
IF PIND.2 = 1 THEN ' (atmega32)
...
...
END IF
RETURN



EDIT: wenn das dann immer noch 2x aufgerufen wird, ist vielleicht wirklich dein Signalinput etwas zu viel verwackelt

popi
04.09.2008, 12:30
Robert,

mein Retter vor langer Zeit (du erinnerst dich noch?, bin Dir noch immer ein Kasten Bier schuldig ;o), hoffe es geht dir gut.

Zum Thema: ja, es wird noch immer 2x ausgefüht, warum auch immer.
Wenn Du sagst, es hängt am verwakelten Signal, dann suche ich nicht mehr weiter. Wobei mir sich die Frage stellt, warum dann genau 2 mal nur???
Könnte ja auch 3x prellen??

Wie auch immer, habe deinen Rat befolgt, geht aber leider immer noch nicht.

Wäre es nicht möglich, innerhalb de Routine den INT0 auszuschalten, dann eine Wartezeit, dann code und dann wieder INT0 ein?

Wie auch immer, wenn es kein Codefehler ist, nehme ich einen anderen Taster. Schau mal bitte nur kurz über den Code, das weiß ich bescheid.

Liebe GRüße

popi



$regfile "ATtiny2313.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 24

'************************************************* *****************************

Enable Int0
Config Int0 = Falling
On Int0 Isr_von_int0
Enable Int1
Config Int1 = Falling
On Int1 Isr_von_int1
Enable Interrupts

Config Portd.6 = Output
Config Portb.3 = Output
Config Portb.4 = Output
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1

Dim Schleife As Integer
Dim Schrittweite As Integer

Schrittweite = 1
'************************************************* *****************************

Do

For Schleife = 100 To 250 Step Schrittweite
Compare1a = Schleife
Compare1b = 350 - Schleife
Waitms 10
Next Schleife

Schrittweite = Schrittweite * -1
For Schleife = 250 To 100 Step Schrittweite
Compare1a = Schleife
Compare1b = 350 - Schleife
Waitms 10
Next Schleife
Schrittweite = Schrittweite * -1

Loop
End

Isr_von_int0:
Waitms 1000 <-- warum wird es überhaupt noch mal angenommen, werden interrupts "gespeichert"

If Pind.2 = 0 Then
If Schrittweite < 5 Then
Incr Schrittweite
Pulseout Portd , 6 , 5000
End If
End If
Return


'folgendes ist zukunft, erst muss INT0 gehen
Isr_von_int1:
If Schrittweite < 5 Then
Decr Schrittweite
Pulseout Portd , 6 , 5000
End If
Return

PicNick
04.09.2008, 12:54
Ja, Popi, ich erinnere mich, ich hab auch noch deine Sourcen, denk' ich ;-)

Bei meinem Besipiel ist folgendes zu beachten:
IF PIND.2 = 1 THEN ' (atmega32) RISING
IF PIND.2 = 0 THEN ' (atmega32) FALLING



Ja, Interrupts merkt er sich. Sofort nach dem return hüpft er wieder rein.

Ich persönlich würde, wenn es um Tasten geht, überhaupt keinen Interrupt verwenden. Denn so schnelle Finger gibt es nicht.

Wart mal kurz, ich werde dir einen Programmvorschlag unterbreiten.

EDIT: ööhmm, wie hast du denn jetzt die Tasten ? Mit (internem) Pullup und "falling" beim Drücken ?

popi
04.09.2008, 12:58
Hallo Robert,

lieb von Dir, aber falls Du keine Zeit hast, es muss diesmal nicht so schnell sein ;o)

Ansonsten mache ich das einfach im DO LOOP Beeich über if pind.x = 1 then.. und bitwait pind, 6 , reset und dann incrementiere ich.

Das müsste am einfachsten sein (wie reden nicht von effektiv ;o)

Grüße

popi

PicNick
04.09.2008, 13:55
Versuch vielleicht mal, testen kann ich es aber nicht



$regfile "ATtiny2313.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 24


'************************************************* *****************************
Config Portd.6 = Output
Config Portb.3 = Output
Config Portb.4 = Output
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1


'************************************************* *****************************
Config Pind.2 = Input ' (Int0)
Config Pind.3 = Input ' (Int1)

Portd.2 = 1 ' Pullup aktivieren
Portd.3 = 1 ' Pullup aktivieren

Dim Schleife As Word
Dim Schrittweite As Word
Dim Zwischenwert As Word

Dim Richtung As Byte
Dim Tasten As Byte 'Tasten
Dim Freigabe As Byte
'( Nur wenn freigegeben, werden gedrückte Tasten akzeptiert
Für Einen Neuen Tastendruck Muß Er Erstmal Auslassen
')

Schrittweite = 1
Richtung = 1
Schleife = 100
'************************************************* *****************************

Do
Tasten = Pind And &H0C ' nur die Tasten-Bits
'( mögliche Werte:
&H0c Garnix Gedrückt
&H08 Taste Schritt+
&H04 Taste Schritt -
&H00 Beide Tasten - > Ungültig , Ignoriert
')
If Freigabe = 0 Then
If Tasten = &H0C Then Freigabe = 1 ' nix gedrückt, nächte gilt wieder
Else
If Tasten = &H08 Then
Freigabe = 0 ' sperren
If Schrittweite < 5 Then
Incr Schrittweite
Pulseout Portd , 6 , 5000
End If
Else
If Tasten = &H04 Then
Freigabe = 0 ' sperren
If Schrittweite > 1 Then
Decr Schrittweite
Pulseout Portd , 6 , 5000
End If
End If
End If
End If
If Richtung = 1 Then
If Schleife < 250 Then
Schleife = Schleife + Schrittweite
Waitms 10
else
richtung = 0
End If
Else
If Schleife > 100 Then
Schleife = Schleife - Schrittweite
Waitms 10
else
richtung = 1
End If
End If
Compare1a = Schleife
Zwischenwert = 350 - Schleife
Compare1b = Zwischenwert

Loop
End


Anmerkung:

das mit dem zwischenwert ist nur sicherheitshalber, ich bin nicht sicher, ob Bascom sonst richtig reagiert, weil ja Compare1b ein BYte ist, "350" aber nicht

popi
04.09.2008, 14:23
Hallo Robert,


weil ja Compare1b ein BYte ist, "350" aber nicht

Der Compiler hat nicht gemeckert.
Sollte er? Über sowas glaube ich, denke ich viel zu wenig nach.
Ich dachte sowieso, das, obwohl 350 kein Byte ist, einfach 350 -100 subtrahiert werden, unabhängig von der Definition der Variablen sondern nur vom Wert (Inhalt) her berücksichtigt.

Wie auch immer, natürlich funktioniet der Code ;)

Vielen Dank, ich werde es so belassen.

Und danke auch für den Hinweis mit dem Interrupt. Du hast schon recht mit den schnellen Fingern.
Polling reicht hier ja auch vollkommen aus.

Liebe Grüße und vielen Dank noch mal

bis demnächst


popi

PicNick
04.09.2008, 14:34
Na, super. :-)
Bascom verarbeitet so eine Zeile immer mit dem Typ der Zielvariablen
Er kann dabei aus einem Word 0-250 tadellos ein Byte machen.
Aber er versucht das auch bei 350. das sind &H015E
Im unteren Byte steht also nur &H005E (94)
und damit würde er glatt weiterrechnen
also eigentlich 94 - schleife.