PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Int0 / Int1 Problem ( Prellen )



BlaueLed
27.01.2010, 20:20
Hallo zusammen,

ich habe mich nach mehreren anderen Bascom Projekten an den Interrupts versucht. Leider funktioniert die Sache mit Int0 und Int1 nicht wirklich. Hier erstmal die Aufgabe, welche ich zu lösen versuche:

Ich habe eine Kette. Jedes Kettenglied wird über einen Initiator erkannt ( 24V über Optokoppler 5V ). Diesen Initiator habe ich an Int0 angeschlossen. Wenn ich die Kette laufen lasse, und folgenden Code verwende funktioniert das sehr gut.



$regfile = "m644pdef.dat"
$crystal = 18432000
$baud = 19200

Config Pind.3 = Input
Config Pind.2 = Input
Pind.3 = 1
Pind.2 = 1

Config Int0 = Rising
On Int0 Takt
Enable Int0

Dim takter as Word

Main:
nop
goto main

Takt:
incr takter
print takter
return


Bei jedem Kettenglied wird die Variable Takter hochgezählt. Ich bekomme dies auch im Terminal angezeigt. An Int1 habe ich einen weiteren Initiator angeschlossen. Dieser erkennt die Kettenglieder, an denen ein weiteres Stück Metall angebracht ist ( Referenzkettengliederkennung ). Den Signalverlauf habe ich angehängt. Zuerst kommt das Signal an Int1. Kurze Zeit danach kommt Int0. Die Signale fallen in umgekehrter Reihenfolge wieder ab. Zuerst Int0 = 0 dann kurze Zeit danan Int1 = 0.

Bei folgendem Code wird Int1 sporadisch auch 2x ausgelöst:


$regfile = "m644pdef.dat"
$crystal = 18432000
$baud = 19200

Config Pind.3 = Input
Config Pind.2 = Input
Pind.3 = 1
Pind.2 = 1

Config Int0 = Rising
On Int0 Takt
Enable Int0

Config Int1 = Rising
On Int1 Referenz
Enable Int1

Enable Interrupts

Dim Takter As Word
Dim referenz as Word



Print "Booting"

Do
nop
Loop



Takt:
Incr takter
Return

Referenz:
If Pind.3 = 1 Then
print "referenz erkannt"
End If

Return


Ein Hardwareproblem schließe ich vorerst aus, da die Signale über Hutschienen Optokoppler getrennt sind. Mir kommt es so vor, als würde Int1 prellen. Es wäre nett, wenn Ihr mal über den Code schauen könntet, ob der Fehler im Programm zu finden ist.

Danke und Gruß
BlaueLed

Jaecko
27.01.2010, 20:58
Irgendwelche Ausgaben auf Displays, UARTs etc. macht man nicht in ISRs.
Normalerweise setzt man hier nur eine Variable und prüft in der Main-Loop, ob diese gesetzt ist. Wenn ja: Ausgabe und Variable wieder auf 0 setzen.

Wird die ISR nochmal aufgerufen, während die aber noch mit der Ausgabe von davor beschäftig ist, wirds Probleme geben.

Wenn das "Prellen" danach immer noch da ist, kann man mal nach weiteren Möglichkeiten schauen.


Und ich glaub die Zeilen hier:
Pind.3 = 1
Pind.2 = 1

Sollten jeweils Portd.x sein (hier sind doch die Pull-Ups gemeint?)

Vitis
28.01.2010, 11:24
hmmm ... optokoppler können aber schon recht schnell sein, kann schon sein, dass das prellen vonaußen kommt. Wie schon geschrieben, den Print aus der ISR raus nehmen und Flag setzen sowieso, Port Register setzen für Pullups, nicht Pin. Ggf. n Monostabiles Flipflop vorschalten oder halt per Software entprellen -> debounce.

BlaueLed
28.01.2010, 12:38
Hallo nochmal,

danke für Eure Antworten. Das mit dem Pind.3 = 1 habe ich geändert auf Portd.3 = 1 und die prints aus den interrupts entfernt. Leider brachte das keinen Erfolg. Das Prellen ist immer noch da. Dann habe ich es mit Debounce getestet. Die Kettenglieder werden mit einer maximalen Frequenz von 15 Hz erkannt. Also 15mal pro Sekunde. Da kommt bei mir das Debounce aus dem Takt und ich habe Taktfehler. Das Problem konnte ich dann doch noch lösen. Ich detektiere in der Main Loop die steigende Flanke und die fallende Flanke von jedem Initiator und berechne dann die Position jedes Kettengliedes. So bin ich schnell genug und habe kein Prellen mehr.

Danke und Gruß
BlaueLed