Moin-moin!
Das sieht schon ziemlich gut aus, und zu Deinen Fragen gibt´s auch Antworten!
Erstmal gibt´s aber noch ein paar Anmerkungen zu Deinem bisherigen Code (von oben nach unten):
SREG.7=1 ist korrekt - genau das gleiche macht aber auch der Befehl "Enable Interrupts". Das ist also quasi doppelt gemoppelt.
PCICR.0=1 aktiviert den PCINT0 - auf "Bascom" könnte man aber analog dazu "Enable PCINT0" schreiben (liest sich einfacher).
Das Bit PCIFR.0 dient dem Controller dagegen als sogenanntes "Flag" (so ´ne Art Signal) - es wird gesetzt wenn die Interrupt-Bedingung eintritt, und gelöscht wenn die dazugehörige Interrupt-Routine ausgeführt wurde. Der Controller macht das ganz alleine; dieses Bit solltest Du also erstmal in Ruhe lassen![]()
PINB.1=0: Die PIN-Register enthalten die logischen Zustände die an einem Anschluss anliegen, der als Eingang konfiguriert ist. Man fragt sie also ab wenn man wissen möchte, ob ein Anschluss High oder Low ist. Vermutlich wolltest Du den PullUp-Widerstand des Eingangs B.1 aktivieren - das ginge dann mit PORTB.1=1.
Compare A = Toggle, Clear Timer = 1: Diese Befehle braucht man nur für PWM-Anwendungen - in diesem Fall sind sie unnötig.
Und diese Sequenz
Do:
Lowerline : LCD " Puls: " ; I ; " ms"
Toggle PORT.3
Loop
ist auch etwas problematisch: Dein LCD hämmert alle paar Millisekunden seine Buchstaben in die untere Zeile - und zwar hintereinander. Das heißt, schneller als Du sehen kannst ist die untere Zeile vollgeschrieben, und alles was danach kommt geht in´s "Nirvana".
Abhilfe würde hier der Befehl "Locate 2,1" vor dem LCD-Befehl schaffen: Damit startet jeder Ausdruck an der ersten Stelle der zweiten Zeile.
Und zu den PCINTs muss man auch ein paar Dinge wissen, um die Wirrnis zu verstehen:
Es gibt 24 Anschlüsse, die einen Pinchange-Interrupt auslösen können: PCINT0, PCINT1,...PCINT23. Es gibt aber keine 24 unterschiedlichen Pinchange-Interrupts, sondern nur drei: PCINT0, PCINT1 und PCINT2 (vergleichbar mit den beiden "normalen" Interrupts INT0 und INT1). Dass diese drei Interrupts genauso heißen wie die ersten drei Anschlüsse, ist sehr verwirrend. Die Interrupt Anschlüsse sind nun in 8er-Gruppen zusammengefasst, von denen jeder Anschluss den selben Interrupt auslöst:
Anschlüsse PCINT0-PCINT7 -> PCINT0
Anschlüsse PCINT8-PCINT15 -> PCINT1
Anschlüsse PCINT16-PCINT23 -> PCINT2
Wenn Du also über den Pin 15 den Interrupt auslösen möchtest, ist das der Anschluss PCINT1, und somit die Interrupt-Routine PCINT0 ! (verwirrend, aber wahr)
Das PCMSK-Register hast Du also korrekt gesetzt mit &B00000010. Und PCICR.0=1 ist auch korrekt, schließlich möchtest Du ja die Gruppe "PCINT0" aktivieren (man könnte auch in Bascom direkt schreiben "Enable PCINT0).
Aber Du musst dann "On PCINT0 Lesen" schreiben!
Und die Messung von RC-Impulsen habe ich immer so gemacht:
Lesen:
If PINB.1=1 then
Timer1=0
Else
I=Timer1
End if
Return
Heißt also, dass der Timer zurückgesetzt wird wenn der Impuls beginnt (Flanke und PINB.1=1), und sein aktueller Wert auf die Variable I überschrieben wird, wenn der Impuls endet (Flanke und PINB.1=0). Wenn Du einen Prescaler von 64 nimmst, läuft der Timer erst nach 200 ms über - in dieser Zeit sollten mindestens 10 Impulse aufgelaufen sein. Und wenn nicht, springt der Controller berechtigterweise in die ISR "Fehler".
Wenn Du dann noch ein "Flag" setzt wenn das Impulsende erkannt wurde, kannst Du in der Hauptschleife das Flag abfragen und den LCD-Befehl nur ausführen lassen, wenn auch tatsächlich ein neuer Impuls gemessen wurde. Aber das wäre vielleicht was für die nächste Runde
Ich hoffe, das waren nicht zu viele & verwirrende Informationen - ansonsten einfach nachfragen!
Lesezeichen