Hur man ska tolka riktningen av rotation från en digital rotary switch med en PIC (5 / 5 steg)
Steg 5: programvara
För att få Darrel Taylor (DT) finns avbryter ställa in det två saker att göra:
1.) Include DT_INTS-14.bas och ReEnterPBP.bas arkivera i din kod.
2.) kopiera och klistra in detta i din kod.
ASM
INT_LIST makro, IntSource, etikett, typ, ResetFlag?
INT_Handler RBC_INT, _ISR, PBP, ja
endm
INT_CREATE
ENDASM
Infoga tabbar och blanksteg som bilden i slutet av Instructable så du kan se saker lite lättare i din kod. Måste du ändra det något för att passa dina behov. Under etiketten, ersätta ISR med namnet på den subrutin som är din ISR. Glöm inte understreck! Du behöver det!
För att få avbrotten arbetar, finns det två saker att göra:
1.) skriva ISR. Du ska skriva detta precis som du skulle skriva en PBP subrutin förutom att du kommer att behöva infoga @ INT_RETURN i slutet av subrutinen i stället för avkastning. Detta kommer att erkänna avbrottet och återgå programkörningen till där den slutade i huvudsakliga slingan.
Inuti ISR måste du rensa flaggan avbrott så att programmet inte är fastklämd i en rekursiv avbryta. Helt enkelt läsa PORTB är allt som behöver göras för att klara avbrott flaggan på PIC16F877A. Varje annan mikrokontroller har olika sätt att rensa avbrott flaggor. Kolla databladet för din mikrokontroller.
2.) när du når punkten i koden som du vill aktivera avbrottet, använder denna kodrad:
@ INT_ENABLE RBC_INT
Använd när du vill inaktivera avbrottet helt enkelt:
@ INT_DISABLE RBC_INT
Det finns en massa saker packas in i vad jag bara täckt så jag ska sammanfatta snabbt. Hittills har ditt program bör se ut ungefär så här:
; Någon behövde ställa in eller kod
INKLUDERA "DT_INTS-14.bas"
INKLUDERA "ReEnterPBP.bas"
ASM
INT_LIST makro, IntSource, etikett, typ, ResetFlag?
INT_Handler RBC_INT, _myISR, PBP, ja
endm
INT_CREATE
ENDASM
; Någon annan behövde ställa in eller kod
@ INT_ENABLE RBC_INT
; Kod som behöver veta vilka sätt ratten roterar
@ INT_DISABLE RBC_INT
; Annan kod
SLUTET; Slutet av program
myISR:
ISR koden här
@ INT_RETURN
(Avbryta Handler uppsättning upp tabell)
Jag tror det är där någon som inte använder en PIC eller DT avbrott kan gå in igen. Nu måste vi faktiskt skriva ISR så mikrokontroller vet vilket håll ratten roterar. Minns från avsnittet software teorin att vi kan härleda riktningen av rotation om vi vet den ingång som orsakade avbrottet, dess nytt värde och värdet av den andra ingången. Här är pseudokod:
Läs PORTB till en början variabel att rensa flaggan avbrott
Kontrollera om A orsakade avbrottet.
Om sant,
Jämföra A och B.
Kontrollera om olika, om annan
Det var Medsols rotation
Annat,
Det var moturs
Endif
Kontrollera om B orsakade avbrottet.
Om sant,
Jämför A och B
Kontrollera om olika, om samma,
Det var Medsols rotation
Annat,
Det var moturs
Endif
Returnera från avbrott
Hur vet vi om en förändring på A eller B orsakat avbrottet? Att upptäcka det nya värdet av den ändrade ingången och den andra (oförändrad) ingången är lätt eftersom vi kan läsa dem inuti ISR. Vi behöver veta vad tillståndet för var och en var innan avrättningen får skickas till ISR. Detta händer i huvudsaklig rutin. Den viktigaste rutinen sitter och väntar på en byte variabel som vi kallade CWflag ska vara 1 eller avmarkeras 0 av ISR. Efter varje erkänt ändringen av ratten eller om det finns ingen knopp aktivitet, är variabeln värdet 5 att indikera inaktiv. Om flaggan blir set eller rensas, den viktigaste rutinen värdet ökar omedelbart eller minskar börvärde trycket på lämpligt sätt baserat på rotation och sedan anger variabeln CWflag tillbaka till 5 eftersom ratten är nu ledig igen. Som den viktigaste rutinen är att kontrollera CWflag, det också dokumenterar tillståndet för A och B vridbrytaren värdena. Detta är verkligen enkelt och ser ut så här:
oldA = A
oldB = B
Det är verkligen inget super fancy här. Bara ta med de två i början av slingan som kontrollerar CWflag för rotation. Vi uppdaterar bara logik värdena för insatsvaror från vridknappen inuti öka/minska loop i huvudsaklig rutin så att vi kan se vad input orsakade avbrottet när ISR körs. Här är ISR koden:
ABchange:
Scratch = PORTB ' Läs PORTB att klara avbrott flagga
"Om A orsakar avbrottet, när B på rotationsriktning
OM oldA! = en då
"Om A och B är olika, det var Medsols rotation
OM A! = B SEDAN
GÅ TILL CW
"Annars var det moturs rotation
ANNAT
GÅ TILL CCW
ENDIF
ENDIF
"Om B orsakar avbrottet, kontrollera A för rotationsriktning
OM oldB! = B sedan
"Om A och B är samma, det var Medsols rotation
OM A == B SEDAN
GÅ TILL CW
"Annars var counter Medsols rotation
ANNAT
GÅ TILL CCW
ENDIF
ENDIF
CW:
CWflag = 1
@ INT_RETURN
CCW:
CWflag = 0
@ INT_RETURN
Jag har bifogat ISR koden i en AB_ISR.bas fil eftersom flikarna i koden inte är visar upp hur de borde.
Nu, eftersom ISR har de gamla värdena för ingångarna A och B kan den bestämma vilken kanal orsakade avbrottet, jämför med andra (oförändrad) input och bestämma riktningen av rotation. Alla huvudsakliga rutin har att göra är att kontrollera CWflag att se vilken riktning vredet har aktiverad (om det har) och öka eller minska en counter, ange punkt eller vad du vill eller behöver.
Jag hoppas detta hjälper och har inte varit alltför förvirrande. Denna typ av gränssnitt är särskilt användbart om ditt system använder redan avbrott eftersom detta är endast en mer avbrott att lägga till. Njut!