Stap 5: Software
Om de Darrel Taylor (DT) zijn interrupts instellen er twee dingen te doen:
1.) inclusief de DT_INTS-14.bas en ReEnterPBP.bas bestanden in uw code.
2.) kopiëren en plak deze in uw code.
ASM
INT_LIST macro; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _ISR, PBP, ja
endm
INT_CREATE
ENDASM
Voeg tabs en spaties als de afbeelding aan het einde van de Instructable zodat u dingen een beetje gemakkelijker in uw code zien kunt. U zult moeten aanpassen iets aan uw behoeften. Onder Label, ISR Vervang door de naam van de subroutine die uw ISR. Vergeet niet het onderstrepingsteken! U het nodig hebt!
Als u de interrupts werken, zijn er twee meer dingen te doen:
1.) schrijven de ISR. Dit zul je schrijven net als je gaat schrijven een subroutine PBP behalve dat moet u invoegen van @ INT_RETURN aan het einde van de subroutine in plaats van terugkeer. Dit zal de interrupt erkennen en waar deze was gebleven in de hoofdlus op uitvoering van het programma terugkomen.
Binnen de ISR moet u duidelijk de interrupt-vlag, zodat het programma niet raken in een recursieve-interrupt verstrikt doet. Gewoon lezen van PORTB is dat alles moet worden gedaan om te wissen de interrupt-vlag op de PIC16F877A. Elke verschillende microcontroller heeft een andere manier van clearing interrupt vlaggen. Controleer de data sheet voor uw microcontroller.
2.) wanneer u het punt bereikt in de code die u wilt inschakelen van de interrupt, deze lijn van code worden gebruikt:
@ INT_ENABLE RBC_INT
Wanneer u zin voor ontredderen de interrupt gewoon gebruik maken van:
@ INT_DISABLE RBC_INT
Er is een heleboel dingen verpakt in wat ik alleen gedekt zodat ik snel zal samenvatten. Tot nu toe uw programma moet als volgt uitzien:
; Om het even welk nodig instellen of code
OMVATTEN "DT_INTS-14.bas"
OMVATTEN "ReEnterPBP.bas"
ASM
INT_LIST macro; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _myISR, PBP, ja
endm
INT_CREATE
ENDASM
; Alle andere nodig instellen of code
@ INT_ENABLE RBC_INT
; Is de code die moet weten welke weg de knop draaien
@ INT_DISABLE RBC_INT
; Andere code
EINDE; Einde van programma
myISR:
ISR code hier
@ INT_RETURN
(Interrupt Handler Set Up tabel)
Ik denk dat dit is waar iedereen die geen gebruik van een PIC maakt of DT interrupts opnieuw kunnen meedoen. Nu, moeten we eigenlijk schrijven de ISR zodat de microcontroller weet welke kant is de knop draaien. Herinner mij uit de sectie software theorie dat we dat de richting van rotatie afleiden kunnen als we weten de ingang waardoor de interrupt, de nieuwe waarde en de waarde van de andere input. Hier is de pseudocode:
Lees PORTB in een kras variabele om te wissen de interrupt-vlag
Controleer als A de interrupt veroorzaakt.
Als de waarde true is,
Vergelijk A en B.
Controleer indien verschillend, indien verschillend,
Het was rechtsom draaien
Anders,
Het was tegen de klok in
Endif
Controleer als B de interrupt veroorzaakt.
Als de waarde true is,
Vergelijk A en B
Controleer of anders, als dezelfde,
Het was rechtsom draaien
Anders,
Het was tegen de klok in
Endif
Retourneren uit interrupt
Hoe weten we als een verandering op A of B veroorzaakt de interrupt? Ontdekken van de nieuwe waarde van het gewijzigde input en de andere (ongewijzigd) input is gemakkelijk, omdat we ze binnen de ISR. kan lezen We willen weten wat de status van elk een was voordat de uitvoering wordt verzonden naar de ISR. Dit gebeurt in de belangrijkste routine. De belangrijkste routine zit en wacht op een byte-variabele die noemden we CWflag worden ingesteld op 1 in- of uitgeschakeld op 0 door de ISR. Nadat elk erkend verandering van de knop of als er geen knop activiteit, is de variabele ingesteld op 5 om aan te geven een ruststand. Als de vlag instellen krijgt of is uitgeschakeld, de belangrijkste routine onmiddellijk verhoogt of verlaagt de druk instelpunt op passende wijze op basis van de rotatie en vervolgens idle sets de CWflag variabele terug naar 5, omdat de knop nu opnieuw. Als de belangrijkste routine is het controleren van de CWflag, is het ook het documenteren van de staat van de A en B draaischakelaar waarden. Dit is werkelijk eenvoudig en ziet er als volgt:
oldA = A
oldB = B
Er is echt niets super mooie hier. Net omvatten die twee lijnen aan het begin van de lus controleert de CWflag voor rotatie. We updaten slechts de waarden van de logica van de ingangen van de draaiknop binnen de increment/decrement lus in de belangrijkste routine, zodat we welke input veroorzaakt de interrupt zien kunnen wanneer de ISR wordt uitgevoerd. Hier is de ISR-code:
ABchange:
kras PORTB = "Lees PORTB voor interrupt markering wissen
' A veroorzaakt de interrupt, Controleer B voor draairichting
IF oldA! = een dan
' Als A en B verschillend zijn, het was rechtsom draaien
IF A! = B THEN
GOTO CW
' Anders, het was linksom draaien
ANDERS
GOTO CCW
ENDIF
ENDIF
' Als B de interrupt veroorzaakt, controleert u A draairichting
Als oldB! = B THEN
' Als A en B hetzelfde zijn, het was rechtsom draaien
IF A DAN B ==
GOTO CW
' Anders, het was teller rechtsom draaien
ANDERS
GOTO CCW
ENDIF
ENDIF
CW:
CWflag = 1
@ INT_RETURN
CCW:
CWflag = 0
@ INT_RETURN
Ik heb de ISR-code opgenomen in een AB_ISR.bas-bestand omdat de tabbladen in de code worden niet weergegeven zoals die ze zou moeten.
Nu, omdat de ISR de oude waarden voor A en B het kan bepalen welke input veroorzaakt de interrupt-ingangen heeft, vergelijken met de andere (ongewijzigd) input en draairichting bepalen. Alle de belangrijkste routine moet doen is controleren de CWflag om te zien welke richting de knop veranderd (indien aanwezig) en een toename of decrement een teller, set punt of wat je leuk of behoefte aan.
Ik hoop dat dit helpt en niet is te verwarrend. Dit soort interface is vooral handig als uw systeem al interrupts wordt gebruikt als dit is slechts één meer onderbreken om toe te voegen. Geniet van!