Ich bin völlig neu in der Montage und muss einen Zähler mit PIC16F628A, einem Druckknopf und einem Display entwickeln. Zusätzlich wird es einen externen Oszillator (555) geben.
Ich habe dabei einige Fortschritte gemacht, aber ich glaube, ich brauche etwas Hilfe von euch Leuten. Zuerst habe ich eine Verzögerung basierend auf Dekrementen gemacht, um Zahlen auf dem Display sehen zu können.
Mein Problem ist jetzt, dass ich, sobald ich den Knopf drücke, nur eine Zahl zählen muss, unabhängig davon, wie lange ich ihn gedrückt halte. So etwas wie, wenn es den Status ändert, wird es um 1 erhöht. Ich glaube, das muss mit Interrupts gemacht werden, denke ich.
Was ist nun die beste Lösung für mein Problem? Externer Interrupt, durch Zustandsinterrupt? Irgendetwas anderes?
Da Sie keinen Timer verwenden können (ermittelt aus Ihren Kommentaren), benötigen Sie eine geeignete Verzögerungsroutine, um eine bestimmte Zeitspanne bereitzustellen. Ich mag die Zeit von , aus früheren Erfahrungen. Sie können jedoch jeden Zeitraum verwenden, den Sie für angemessen halten. Angenommen, Ihr Prozessor ist werkseitig kalibriert Rate, wird der Unterrichtszyklus sein und es wird dauern Zyklen, um ein zu machen Zeitraum.
Der Verzögerungscode sollte wahrscheinlich in eine Unterroutine umgewandelt werden, um zu vermeiden, dass er immer wieder repliziert werden muss.
DELAY8MS MOVLW 0x3E
MOVWF DLO
MOVLW 0x07
MOVWF DHI
DECFSZ DLO, F
GOTO $+2
DECFSZ DHI, F
GOTO $-3
NOP
GOTO $+1
RETURN
Die Gesamtzeit, die von der obigen Routine belegt wird, kann wie folgt berechnet werden:
Wo Und , wobei 0 als 256 interpretiert wird. Die CALL- und RETURN-Anweisungen nehmen jeweils 2 Zyklen in Anspruch, und der obige Code berücksichtigt all dies. Der Aufruf sollte genau dauern Zyklen und, bei das heisst .
Sie müssen diese beiden Variablen erstellen, Und irgendwo. Das kann man meiner Meinung nach so machen:
CBLOCK
DLO
DHI
ENDC
Es gibt natürlich auch andere Wege. Und Sie können der CBLOCK-Zeile eine absolute Adresse hinzufügen, wenn Sie den Block an einer bestimmten Stelle platzieren möchten.
Nachdem Sie nun eine Verzögerungsroutine haben, können Sie mit dem nächsten Schritt fortfahren. Sie brauchen zwei neue Routinen. Eine, die wiederholt verzögert, bis die Schaltfläche aktiv wird, und eine, die wiederholt verzögert, bis die Schaltfläche inaktiv wird. Entprellung ist hier enthalten:
ACTIVE CALL DELAY8MS
BTFSC PORTx, PINy
GOTO ACTIVE
CALL DELAY8MS
BTFSC PORTx, PINy
GOTO ACTIVE
RETURN
INACTIVE CALL DELAY8MS
BTFSS PORTx, PINy
GOTO INACTIVE
CALL DELAY8MS
BTFSS PORTx, PINy
GOTO INACTIVE
RETURN
Ich kenne Ihre Port- oder PIN-Nummer nicht, also habe ich dort nur "Dummy" -Werte eingegeben. Sie müssen sie richtig ersetzen. Die obigen zwei Routinen gehen davon aus, dass 0 aktiv und 1 inaktiv ist.
Jetzt können Sie Ihren Hauptcode schreiben:
MAIN ; <code to reset your counter value>
GOTO LOOP_NXT
LOOP CALL ACTIVE
; <code to increment your counter value>
LOOP_NXT ; <code to display your counter value>
CALL INACTIVE
GOTO LOOP
Der obige Code setzt Ihren Zählerwert auf den Wert zurück, bei dem Sie beginnen möchten, und springt dann in die Schleife, wo er den Wert anzeigt und darauf wartet, dass die Schaltfläche inaktiv wird. Der Effekt hier ist, dass, wenn Sie Ihren Code mit gedrückter Taste starten (es sollte nicht sein, aber was ist, wenn es so ist?), der Code den Zähler immer noch zurücksetzt und ihn anzeigt ... aber er wartet, bis Sie ihn loslassen bevor Sie fortfahren. Also musst du auf den Schalter verzichten.
Sobald dies geschehen ist, wartet die Basisschleife dann einfach auf einen entprellten aktiven Zustand des Schalters. Wenn es das sieht, erhöht es den Zähler sofort (beim Drücken, nicht beim Loslassen), wartet dann aber, bis die Taste losgelassen wird, bevor es wieder fortfährt.
Das ist alles. Sie müssen noch den entsprechenden Code für den Zähler und die Anzeige schreiben. Aber das bringt die Idee für den Rest rüber.
Sie müssen Ihren Schalter "entprellen". Dies kann in Hardware durch Hinzufügen eines kleinen Kondensators über dem Eingang oder in Software erfolgen, indem überprüft wird, ob der Schalter seinen Zustand lange genug beibehält.
Jetzt ist das andere Problem, dass ich den Wert von 1 einmal und nur einmal hinzufügen muss, während ich die Taste drücke. Stellen Sie sich vor, die Taste wird 1 Minute lang gedrückt, und es darf nicht mehr als das anfängliche Inkrement von 1 hinzugefügt werden.
Jetzt brauchen Sie eine Software "One-Shot". Sie müssen sich daran erinnern, ob die Taste beim letzten Mal gedrückt wurde, als Sie nachgesehen haben.
// Pseudo code
if(button) { // Button was pressed
if(!buttonMemory) { // Button was off last time we looked.
counter ++; // Increment the counter
buttonMemory = true; // Remember the button was pressed.
}
} else {
buttonMemory = false; // Cancel the memory.
}
Es gibt mehrere Probleme. Aus Ihrer vagen Beschreibung geht hervor, dass Sie die Zeit messen möchten, in der eine Taste gedrückt wird. Sie haben zwei Probleme, das Entprellen der Taste und das Messen der Zeit, in der die entprellte Taste unten ist.
Ich würde beides in einem periodischen Interrupt von 1 ms tun. Gewöhnen Sie sich daran. Ein Takt von 1 ms ist für viele Dinge nützlich.
Auf diesem speziellen Prozessor ist der Timer 2 mit seinem eingebauten Periodenregister dafür gut geeignet. Stellen Sie es so ein, dass alle 1 ms (1 kHz Rate) ein Interrupt ausgelöst wird.
In der Interrupt-Routine entprellen Sie zunächst den Taster. Ich verwende gerne 50 ms als Entprellzeit. Die meisten Tasten hüpfen etwa 10 ms lang, aber ich habe einige gesehen, die fast 50 ms hüpfen. Außerdem ist dies ungefähr die maximale Zeit, die Menschen nicht als Verzögerung bemerken, sodass die Benutzererfahrung bei 50 ms nicht beeinträchtigt wird.
Behalten Sie ein Flag, das den offiziellen entprellten Zustand der Schaltfläche darstellt. Wenn der momentane Zustand der Taste gleich ist, setzen Sie den Entprellungszähler auf 50 zurück. Wenn sich der momentane und der entprellte Zustand der Taste unterscheiden, verringern Sie den Zähler. Wenn der Zähler 0 erreicht, ändern Sie den entprellten Zustand in den aktuellen Tastenzustand und setzen Sie den Zähler auf 50 zurück.
Jetzt, da Sie den entprellten Zustand der Taste haben, zählen Sie einfach jedes Mal hoch, wenn die Taste gedrückt wird, und tun Sie nichts, wenn Sie sie loslassen. Speichern Sie im speziellen Fall eines Übergangs von unten nach oben den Zählerwert und setzen Sie ein Flag für den Vordergrundcode, der anzeigt, dass eine neue gemessene Länge verfügbar ist. Löschen Sie den Zähler.
Dieser Zähler muss mehrere Bytes lang sein. Ein einzelnes Byte kann nur bis 255 zählen, was etwa ¼ Sekunde entspricht. Mit zwei Bytes kann die Taste etwas länger als eine Minute gedrückt werden. Das könnte gut genug sein. Nur um sicherzugehen, sollten Sie den Zähler nur dann erhöhen, wenn er nicht bereits auf Maximum steht. Auf diese Weise wird ein langer Tastendruck nur auf den maximal darstellbaren Wert geclippt.
jonk
ERS
gbarry
ERS
Benutzer253751