Innholdsfortegnelse:

Slik tolker du rotasjonsretningen fra en digital rotasjonsbryter med en PIC: 5 trinn
Slik tolker du rotasjonsretningen fra en digital rotasjonsbryter med en PIC: 5 trinn

Video: Slik tolker du rotasjonsretningen fra en digital rotasjonsbryter med en PIC: 5 trinn

Video: Slik tolker du rotasjonsretningen fra en digital rotasjonsbryter med en PIC: 5 trinn
Video: Церковь скрыла мотивы Куликовской Битвы 2024, Juli
Anonim
Hvordan tolke rotasjonsretningen fra en digital rotasjonsbryter med en PIC
Hvordan tolke rotasjonsretningen fra en digital rotasjonsbryter med en PIC

Målet med denne instruksjonsboken er å illustrere hvordan du kobler en digital (kvadraturkodet) rotasjonsbryter til en mikrokontroller. Ikke bekymre deg, jeg skal forklare hva kvadraturkodet betyr for oss. Dette grensesnittet og den medfølgende programvaren vil tillate mikrokontrolleren å gjenkjenne rotasjonsretningen for hvert trekk fra en sperre til en annen. Jeg brukte nylig denne bryteren i et mikrokontrollerprosjekt som krevde et settpunkt for trykk ved hjelp av en knapp med 16 sperrer i stedet for opp/ned -knappene. Tanken var å la brukeren "ringe" inn ønsket trykk. Som et resultat måtte vi utvikle en programvarerutine for å hente posisjonsinformasjonen fra bryteren og utlede rotasjonsretningen for å øke eller redusere trykkpunktet for hovedsystemet. I denne instruksjonsboken dekker jeg det fysiske grensesnittet til mikrokontrolleren, teorien om drift for dreiebryteren, teorien om drift for programvaren samt fradragsrutinen. Til slutt viser jeg deg hvordan jeg bruker fradragsrutinen. Etter hvert som vi utvikler oss, prøver jeg å holde ting litt generisk slik at ideen kan brukes på så mange plattformer som mulig, men jeg vil også dele det jeg gjorde, slik at du kan se en bestemt applikasjon.

Trinn 1: Deler

Deler
Deler

For å implementere dette trenger du: En dreiebryter (kvadraturkodet) Trekk opp motstander Egnet mikrokontrollerplattform For mitt prosjekt brukte jeg en Grayhill 61C22-01-04-02 optisk encoder. Dataarket for dreiebryteren krever 8.2k ohm trekkmotstander på de to datalinjene som kommer fra bryteren. Du vil sjekke databladet for koderen du velger å bruke. Dreiebryteren jeg brukte kan også bestilles med en aksial trykknappbryter. Det er en nyttig funksjon for å foreta valg som har blitt ringt opp, etc., men jeg vil ikke diskutere grensesnittet her. Jeg har en "egnet mikrokontrollerplattform" oppført fordi (jeg tror) dette kan implementeres på mer enn én plattform. Jeg har sett mange mennesker som bruker andre mikrokontrollere for Instructables, så jeg vil også vise den generelle tilnærmingen. Jeg skrev all koden i PIC Basic Pro for bruk med en Microchip PIC16F877A. Egentlig er det viktigste du trenger på mikrokontrolleren muligheten til å avbryte når det er en logisk endring på en av to pinner. På PIC16F877A kalles dette PORTB -endringsavbruddet. Det kan være andre navn for det på andre kontrollere. Denne avbryterfunksjonen for mikrokontroller er en del av det som gjør denne implementeringen så elegant.

Trinn 2: Maskinvaregrensesnitt

Maskinvaregrensesnitt
Maskinvaregrensesnitt

En "enkel" løsning ville være å ha en "enkeltpol-16 kast" -bryter med 16 tilkoblinger til mikrokontrolleren. Hver bryterutgang ville deretter være knyttet til en pinne på mikrokontrolleren, slik at hver oppringningsposisjon kan kontrolleres av mikrokontrolleren. Dette er overdreven bruk av I/O -pinner. Ting blir enda verre hvis vi vil ha mer enn 16 stillinger (sperringer) tilgjengelig for oss på bryteren. Hver ekstra posisjon på bryteren vil kreve en ekstra inngang til mikrokontrolleren. Dette blir raskt en svært ineffektiv bruk av innganger på en mikrokontroller. Tast inn skjønnheten i den roterende bryteren. Dreibryteren har bare to utganger til mikrokontrolleren oppført som A og B på databladet. Det er bare fire mulige logiske nivåer som disse linjene kan ta: AB = 00, 01, 10 og 11. Dette reduserer antallet inngangslinjer du må bruke for å koble bryteren til mikrokontrolleren. Så vi har kuttet antall inngangslinjer ned til bare to. Hva nå? Det virker som om vi virkelig trenger 16 forskjellige stater, men denne nye bryteren har bare fire. Har vi skutt oss selv i foten? Nei. Les videre. Vi vil dekke litt av teorien bak rotasjonsbryteren for å forklare.

Trinn 3: Maskinvareteori om drift

Maskinvareteori om drift
Maskinvareteori om drift
Maskinvareteori om drift
Maskinvareteori om drift
Maskinvareteori om drift
Maskinvareteori om drift

Det er mulig å registrere rotasjonsretning ved hjelp av den nevnte "single pole-16 throw" -bryteren, men den bruker mange innganger på mikrokontrolleren. Ved å bruke dreiebryteren reduseres antall innganger til mikrokontrolleren, men nå må vi tolke signalene som kommer fra bryteren og oversette dem til en rotasjonsretning. Jeg nevnte tidligere at bryteren var kvadraturkodet. Dette er også en av de viktigste elegansene i denne løsningen. Dette betyr at det er en 2-bit kode bryteren gir som tilsvarer bryterens posisjon. Du tenker kanskje: "Hvis det er en to bits inngang til mikrokontrolleren, hvordan representerer vi alle de 16 posisjonene?" Det er et godt spørsmål. Vi representerer ikke dem alle. Vi trenger bare å kjenne de relative posisjonene til knotten, slik at vi kan bestemme rotasjonsretningen. Knappens absolutte posisjon er irrelevant. For rotasjon med klokken gjentas koden som bryteren gir hver fjerde sperring og er gråkodet. Gråkodet betyr at det bare er en bitendring for hver posisjonsendring. I stedet for at AB -inngangen teller opp for rotasjon med klokken i binær som denne: 00, 01, 10, 11, endres den slik: 00, 10, 11, 01. Legg merke til at for sistnevnte mønster er det bare en inngang som endres mellom settene. Verdiene mot klokken for AB -inngangen til mikrokontrolleren vil se slik ut: 00, 01, 11, 10. Dette er ganske enkelt motsatsen til klokken med AB = 00 listet først. Ta en titt på diagrammene for en mer visuell forklaring.

Trinn 4: Programvareteori for drift

Programvareteori for drift
Programvareteori for drift

Rutinen som utleder rotasjonsretningen er avbruddsdrevet. Mikrokontrolleren du velger må være i stand til å avbryte når det er en endring på en av (minst) to pinner når avbruddet er aktivert. Dette kalles PORTB -endringsavbruddet på PIC16F877A. Når som helst bryteren roteres, blir mikrokontrolleren avbrutt og programkjøringen blir sendt til Interrupt Service Routine (ISR). ISR vil raskt finne ut hvilken vei bryteren ble rotert, sette et flagg på riktig måte og raskt gå tilbake til hovedprogrammet. Vi trenger dette for å skje raskt hvis brukeren roterer bryteren veldig fort. Vi vet at det grå kodede AB -mønsteret gjentas hver fjerde posisjon, så hvis vi får rutinen til å fungere for overganger mellom de fire posisjonene, vil det fungere for alle de andre. Legg merke til at i en fireposisjonssyklus er det fire kanter. En stigende kant og en fallende kant for A -inngangen så vel som B -inngangen. Mikroprosessoren vil bli avbrutt hver gang det er en kant som betyr at mikrokontrolleren vil bli avbrutt hver gang knappen dreies. Som et resultat må ISR finne ut hvilken vei knappen ble dreid. For å hjelpe oss med å finne ut hvordan vi gjør dette, vender vi oss til bølgeformen for rotasjon med klokken. Legg merke til at når A har en kant, er den nye verdien alltid forskjellig fra B. Når knappen går fra posisjon 1 til 2, går A over fra logikk-0 til logikk-1. B er fortsatt 0 for denne overgangen og matcher ikke den nye verdien av A. Når knappen går fra posisjon 3 til 4, har A en fallende kant mens B forblir på logikk-1. Legg igjen merke til at B og den nye verdien av A er forskjellige. Akkurat nå kan vi se at når A forårsaker avbruddet under rotasjon med klokken, er den nye verdien forskjellig fra B. La oss sjekke B for å se hva som skjer. B har en stigende kant når bryteren går over fra posisjon 2 til 3. Her er den nye verdien av B den samme som A. Ser man på den siste gjenværende kanten for rotasjon med klokken, har B en fallende kant som beveger seg fra posisjon 4 til 5. (Posisjon 5 er det samme som posisjon 1.) Den nye verdien av B er den samme som A også her! Vi kan nå gjøre noen fradrag! Hvis A forårsaker avbruddet og den nye verdien til A er forskjellig fra B, var rotasjonen med klokken. I tillegg, hvis B forårsaker avbruddet og den nye verdien av B er den samme som A, var rotasjonen med klokken. La oss raskt undersøke tilfellet med rotasjon mot klokken. På samme måte som rotasjon med klokken, vil rotasjon mot klokken forårsake fire avbrudd i en syklus: to for inngang A og to for inngang B. Inngang A har en stigende kant når knotten beveger seg fra posisjon 4 til 3 og en fallende kant som beveger seg fra posisjon 2 til 1. Når knotten beveger seg fra posisjon 4 til 3, er den nye verdien til A den samme som verdien til B. Legg merke til at når A beveger seg fra posisjon 2 til 1, er den nye verdien den samme som B også. Nå kan vi se at når A forårsaker avbruddet og den nye verdien samsvarer med den for B, var rotasjonen mot klokken. Raskt ser vi på inngang B for å bekrefte alt. B vil forårsake et avbrudd når knotten beveger seg fra posisjon 5 (som er den samme som 1) til 4, og når knappen flyttes fra posisjon 3 til 2. I begge disse tilfellene samsvarer ikke den nye verdien av B med den eksisterende verdien av A som er det motsatte av tilfellene når B forårsaker avbruddet for rotasjon med klokken. Dette er gode nyheter. Alt sjekker ut som det skal. For å oppsummere, hvis A forårsaker avbruddet og den nye verdien ikke samsvarer med verdien til B eller hvis B forårsaker avbruddet og den nye verdien av B samsvarer med verdien av A, vet vi at det var rotasjon med klokken. Vi kan sjekke de andre sakene for rotasjon mot klokken i programvare, eller vi kan anta at fordi den ikke var med klokken, var den mot klokken. Min rutine gjorde ganske enkelt antagelsen.

Trinn 5: Programvare

Programvare
Programvare
Programvare
Programvare

Jeg brukte ikke de innebygde avbruddene i PIC Basic Pro. Jeg brukte et par filer som jeg inkluderte i koden min fra Darrel Taylor for å kjøre rutinen. Det er her en enorm kreditt til Darrel hører til! Filene er gratis. Bare besøk hans nettsted for mer informasjon, andre applikasjoner og for å laste ned filene. Du kan hoppe over denne delen hvis du ikke bruker en PIC med Darrel Taylor -avbrudd. Bare sett opp avbruddene etter behov på plattformen du bruker. For å sette opp Darrel Taylor (DT) -avbruddene er det to ting å gjøre: 1.) Inkluder DT_INTS-14.bas- og ReEnterPBP.bas-filene i kode.2.) Kopier og lim dette inn i koden. ASMINT_LIST makro; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, ja endm INT_CREATEENDASMIytt faner og mellomrom som grafikken på slutten av instruksjonsboken, slik at du kan se ting litt lettere i koden din. Du må endre det litt for å passe dine behov. Under etikett, erstatt ISR med navnet på underrutinen som er din ISR. Ikke glem understreken! Du trenger det! For å få avbruddene til å fungere, er det to ting å gjøre: 1.) Skriv ISR. Du skriver dette akkurat som om du skulle skrive en PBP -underprogram bortsett fra at du må sette inn @ INT_RETURN på slutten av subrutinen i stedet for RETURN. Dette vil bekrefte avbrudd og returnere programkjøringen til der det sluttet i hovedsløyfen. På innsiden av ISR må du fjerne avbruddsflagget slik at programmet ditt ikke blir fanget av et rekursivt avbrudd. Det er bare å lese PORTB for å fjerne avbruddsflagget på PIC16F877A. Hver forskjellige mikrokontroller har en annen måte å fjerne avbruddsflagg. Kontroller databladet for mikrokontrolleren din. ting pakket inn i det jeg nettopp dekket, så jeg skal oppsummere raskt. Så langt bør programmet ditt se slik ut:; Eventuell nødvendig konfigurasjon eller kodeINCLUDE "DT_INTS-14.bas" INCLUDE "ReEnterPBP.bas" ASMINT_LIST makro; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _myISR, PBP, ja endm INT_CREATEENDASM; Eventuelle andre nødvendige oppsett eller koder@ INT_ENABLE RBC_INT; Kode som trenger å vite hvilken vei knappen dreier@ INT_DISABLE RBC_INT; Annen kodeEND; Slutten på programmyISR:; ISR -kode her@ INT_RETURN (Interrupt Handler Set Up Table) Jeg tror det er her alle som ikke bruker PIC- eller DT -avbrudd kan bli med igjen. Nå må vi faktisk skrive ISR slik at mikrokontrolleren vet hvilken vei knappen dreier. Husk fra programvareteori -delen at vi kan utlede rotasjonsretningen hvis vi kjenner inngangen som forårsaket avbruddet, den nye verdien og verdien av den andre inngangen. Her er pseudokoden: Les PORTB i en skrapelabel for å fjerne avbruddsflagget Sjekk om A forårsaket avbruddet. Hvis det er sant, sammenlign A og B. Kontroller om det er annerledes, hvis det er annerledes. Det var rotasjon med klokken Ellers, det var mot klokken EndifCheck om B forårsaket avbruddet. Hvis det er sant, sammenlign A og B Sjekk om det er annerledes, hvis det samme, Det var rotasjon med klokken Else, Det var mot klokken EndifReturn from interrupt Hvordan vet vi om en endring på A eller B forårsaket avbruddet? Det er enkelt å finne den nye verdien til den endrede inngangen og den andre (uendrede) inngangen fordi vi kan lese dem inne i ISR. Vi trenger å vite hva tilstanden til hver enkelt var før henrettelse blir sendt til ISR. Dette skjer i hovedrutinen. Hovedrutinen sitter og venter på at en bytevariabel som vi kalte CWflag skal settes til 1 eller slettes til 0 av ISR. Etter hver kvitterte endring av knappen eller hvis det ikke er noen knappaktivitet, settes variabelen til 5 for å indikere en inaktiv tilstand. Hvis flagget blir satt eller blir fjernet, øker eller reduserer hovedrutinen umiddelbart settpunktstrykket på riktig måte basert på rotasjonen og setter deretter CWflag -variabelen tilbake til 5 fordi knappen er nå inaktiv igjen. Siden hovedrutinen er å kontrollere CWflag, dokumenterer den også tilstanden til A- og B -bryterverdiene. Dette er veldig enkelt og ser slik ut: oldA = AoldB = BDet er virkelig ikke noe super fancy her. Bare ta med de to linjene i begynnelsen av løkken som sjekker CWflag for rotasjon. Vi oppdaterer bare de logiske verdiene til inngangene fra dreieknappen inne i inkrement/decrement loop i hovedrutinen, slik at vi kan se hvilken inngang som forårsaket avbruddet når ISR kjøres. Her er ISR -koden: ABreise: scratch = PORTB 'Les PORTB for å fjerne avbruddsflagget' Hvis A forårsaker avbruddet, sjekk B for rotasjonsretning IF oldA! = A THEN 'Hvis A og B er forskjellige, var det rotasjon med klokken IF A! = B DA GOTO CW 'Ellers var det rotasjon mot klokken ELLER GOTO CCW ENDIF ENDIF' Hvis B forårsaker avbrudd, sjekk A for rotasjonsretning IF gammel B! = B DA 'Hvis A og B er like, er det var rotasjon med klokken IF A == B DA GOTO CW 'Ellers var det rotasjon mot klokken ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1@ INT_RETURNCCW: CWflag = 0@ INT_RETURN Jeg har tatt med ISR -koden i en AB_ISR.bas -fil fordi faner i koden vises ikke slik de burde. Nå, fordi ISR har de gamle verdiene for innganger A og B, kan den bestemme hvilken inngang som forårsaket avbruddet, sammenligne den med den andre (uendrede) inngangen og bestemme retningen av rotasjon. Alt hovedrutinen trenger å gjøre er å sjekke CWflag for å se hvilken retning knappen har dreid (hvis den har det) og øke eller redusere en teller, settpunkt eller hva du vil eller trenger. Jeg håper dette hjelper og ikke har vært det også forvirrende. Denne typen grensesnitt er spesielt nyttig hvis systemet ditt allerede bruker avbrudd, ettersom dette bare er et avbrudd til. Nyt!

Anbefalt: