Hallo zusammen und einen schönen 1. Weihnachtsfeiertag! Ich habe folgendes Problem zu lösen bzw. ich habe schon eine Idee, die aber in der Praxis nicht funktioniert und ich hoffe auf ein paar gute Vorschläge. Ich habe eine rotierende Scheibe, auf der im Abstand von 90° 4 Magnete aufgebracht sind, ein langer und drei kurze. Diese Magnete flitzen an einer Spule vorbei, die eine positive und ein negative Spannung induziert: Wenn der Nordpol vorbeiflitzt, gibts eine positive und beim Südpol eine negative (es kann auch umgekehrt sein, spielt hier aber keine Rolle). Um diese Spannungen, 0 bis ca. 20V und 0 bis -20V, PIC-gerecht zu bekommen, wird die positive Spannung auf 5V begrenzt und die negative Spannung invertiert und auf 5V begrenzt. Wenn ich im folgenden von "positivem" und "negativem" Impuls rede, so bezieht sich das auf die ursprüngliche Spannungsform und nicht auf die PIC-gerecht aufbereitete. Wie Ihr seht, ist bei den drei kurzen Magneten der Abstand zwischen positiv und Negativimpuls praktisch nicht vorhanden, wohl aber beim langen. Diesen langen gilt es zu detektieren, bzw. den Positivimpuls des langen. Der Abstand zwischen positiver fallender Flanke und negativer steigender Flanke beträgt 3,8 ms bei einer Scheibendrehzahl von 1340 U/min. Die maximale Drehzahl der Scheibe ist 7000 U/min, also ergibt sich nach dem Dreisatz ein minimaler positiv-negativ-Abstand beim langen Magneten von 3,8ms*1340/7000=0,73ms Meine Lösung sieht so aus: Der PIC ist ein 16F88 mit 8MHz-Quarz, und ich nutze die ISR. Das Positivsignal geht auf RB0 und INT0 ist aktiviert. Das negative Signal geht auf RB4 und das RBIE-Bit von INTCON ist aktiviert -> bei jedem Positivimpuls und bei jedem Signalwechsel des Negativimpulses wird ein Interrupt ausgelöst. Bei der ISR werden zu Beginn die Flags abgefragt: Ist INT0IF gesetzt, geht's zum INT0-Teil, ist RBIF gesetzt, wird der RB-Block abgearbeitet. Nur diese beiden Ereignisse können Interrupts auslösen. Beim INT0-Teil wird TMR2 gestartet. Er wurde so mit Pre- und Postscaler konfiguriert, daß er nach 0,73 ms überläuft. Beim RBIE-Teil wird TMR2 gestoppt und resettet. Ein gesetztes TMR2IF zeigt den Überlauf und somit die Erkennung des langen Magneten an. Dieser ist zwar in diesem Moment schon wieder "vorbei", aber ich iniitiere beim nächsten positiven Impuls einen Counter, der von 3 runterzählt. Dieser Counter wird bei jedem folgenden Positivimpuls dekrementiert; bei 0 angekommen, weiß ich, jetzt ist es der lange Magnet. RB5,6 und 7 ändern sich nicht und lösen keinen Interrupt aus. Soweit die Theorie. Leider funktioniert es so in der Praxis nicht. Habt Ihr ein paar gute Tips, wo noch die Fehlerquellen sein könnten? Gruß Th.
Thomas M. schrieb: > Soweit die Theorie. Leider funktioniert es so in der Praxis nicht. Habt > Ihr ein paar gute Tips, wo noch die Fehlerquellen sein könnten? Was funktioniert nicht? Eingrenzen ist das Prinzip fast jeder Fehlersuche. Also erstmal schauen ob der Pic 1. das Signal empfängt, 2. den Interrupt auslöst 3. der Timer läuft usw. Das ist über einen Port an dem der Status H/L ausgegeben wird leicht machbar.
Mit dem Interrupt des Port B ist das so ne Sache. Ich kenne das von der 18F... Serie: Wenn du den "Interrupt on change" des Port B nutzen möchtest, musst du nach dem der Interrupt ausgelöst wurde immer (!) den Port lesen. Du kannst den Wert lesen und verwerfen, wenn du die Information nicht brauchst. Nur nach einem Lesen des Ports wir bei einer erneuten Änderung am Port ein erneuter Interrupt ausgelöst, sonst nicht. Bei den normalen Interrupteingängen ist das Lesen nicht erforderlich. Auf diesen Umstand bin ich bei der Implementierung eines DCF77 Empfänger gestoßen. Habe dabei einiges an Zeit verlohren, da dieser Hinweis etwas versteckt im Datenblatt steht. Vielleicht hilf dir das ja weiter? Eine genauere Fehlerbeschreibung wäre aber auf jeden Fall noch hilfreich. Gruß Alex
Das ist der Beginn meiner ISR:
[code]
btfss INTCON,INT0IF
btfss INTCON,RBIF
goto Int0
movf PORTB,W ; PORTB auslesen
BCF INTCON,RBIF
bcf T2CON,TMR2ON ; TMR2 stoppen
goto isr_end
Int0
[\code]
Du siehst, das hatte ich bereits berücksichtigt. Ich dachte vielleicht,
es liegt daran, daß positiv- und negativsignal so dicht beieinander
liegen. INT0 wird bei steigender Flanke ausgelöst, aber es gibt ja diese
Latenzzeit von 3-4 Maschinenzyklen vom Ansteigen der Flanke bis zum
Sprung zu Adresse 4h. Eigentlich dürfte das kein Problem sein: Die
Pulsbreite von ca. 1,3ms bei 1340 U/min nimmt umgekehrt proportional zur
Drehzahl ab. Bei 7000 U/min haben wir demnach 1,3ms*1340/7000=250µs. Bei
einem Taktzyklus von 500ns und 2µs Maschinenzyklus bin ich doch locker
innerhalb der toleranz,oder?
Th.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
