Indholdsfortegnelse:

Sådan fortolkes rotationsretningen fra en digital drejekontakt med en PIC: 5 trin
Sådan fortolkes rotationsretningen fra en digital drejekontakt med en PIC: 5 trin

Video: Sådan fortolkes rotationsretningen fra en digital drejekontakt med en PIC: 5 trin

Video: Sådan fortolkes rotationsretningen fra en digital drejekontakt med en PIC: 5 trin
Video: Sådan skriver du supersælgende nyhedsbreve | Din digitale virksomhed i København 2024, November
Anonim
Sådan fortolkes rotationsretningen fra en digital drejekontakt med en PIC
Sådan fortolkes rotationsretningen fra en digital drejekontakt med en PIC

Målet med denne Instructable er at illustrere, hvordan en digital (kvadratisk kodet) drejekontakt skal kobles til en mikrokontroller. Bare rolig, jeg forklarer, hvad kvadraturkodet betyder for os. Denne grænseflade og den medfølgende software gør det muligt for mikrokontrolleren at genkende rotationsretningen for hvert træk fra en spærring til en anden. Jeg har for nylig brugt denne type switch i et mikrokontrollerprojekt, der krævede, at et trykindstillingspunkt blev indtastet ved hjælp af en knap med 16 spærrer i stedet for op/ned -knapper. Ideen var at give brugeren mulighed for at "ringe op" til det ønskede tryk. Som følge heraf var vi nødt til at udvikle en software -rutine for at få positionsoplysningerne fra kontakten og udlede rotationsretningen for at øge eller sænke trykindstillingspunktet for hovedsystemet. I denne instruktive dækker jeg det fysiske interface til mikrokontrolleren, teorien om driften af drejekontakten, teorien om drift af softwaren samt fradragsrutinen. Endelig viser jeg dig min anvendelse af fradragsrutinen. Når vi skrider frem, vil jeg prøve at holde tingene lidt generiske, så ideen kan anvendes på så mange platforme som muligt, men jeg vil også dele, hvad jeg gjorde, så du kan se en bestemt applikation.

Trin 1: Dele

Dele
Dele

For at implementere dette har du brug for: En drejekontakt (kvadraturkodet) Træk modstande Egnet mikrokontrollerplatform Til mit projekt brugte jeg en Grayhill 61C22-01-04-02 optisk encoder. Databladet til drejekontakten kræver 8,2 k ohm pull -up -modstande på de to datalinjer, der kommer fra kontakten. Du vil kontrollere databladet for den encoder, du vælger at bruge. Den drejekontakt, jeg brugte, kan også bestilles med en aksial trykknapkontakt. Det er en nyttig funktion til at foretage valg, der er blevet ringet op osv., Men jeg vil ikke diskutere dens grænseflade her. Jeg har en "passende mikrokontrollerplatform" angivet, fordi (jeg tror) dette kan implementeres på mere end én platform. Jeg har set mange mennesker, der bruger andre mikrokontrollere til Instructables, så jeg vil også vise den generelle tilgang. Jeg skrev hele koden i PIC Basic Pro til brug med en Microchip PIC16F877A. Virkelig, den vigtigste ting, du har brug for på mikrokontrolleren, er evnen til at afbryde, når der er en logisk ændring på en af to stifter. På PIC16F877A kaldes dette PORTB -ændringsafbrydelsen. Der kan være andre navne på det på andre controllere. Denne mikrocontroller -afbrydelsesfunktion er en del af det, der gør denne implementering så elegant.

Trin 2: Hardware -grænseflade

Hardware -grænseflade
Hardware -grænseflade

En "simpel" løsning ville være at have en "single pole-16 throw" switch med 16 forbindelser til mikrokontrolleren. Hver switchudgang ville derefter blive bundet til en pin på mikrokontrolleren, så hver opkaldsposition kan kontrolleres af mikrokontrolleren. Dette er en overdreven brug af I/O -ben. Tingene bliver endnu værre, hvis vi vil have mere end 16 positioner (tilbageholdelser) til rådighed for os på kontakten. Hver ekstra position på kontakten ville kræve en ekstra input til mikrokontrolleren. Dette bliver hurtigt en meget ineffektiv brug af indgange på en mikrokontroller. Indtast skønheden i drejekontakten. Drejekontakten har kun to udgange til mikrokontrolleren angivet som A og B på databladet. Der er kun fire mulige logiske niveauer, som disse linjer kan tage: AB = 00, 01, 10 og 11. Dette reducerer i høj grad antallet af inputlinjer, du skal bruge til at forbinde kontakten til mikrokontrolleren. Så vi har reduceret antallet af inputlinjer til kun to. Hvad nu? Det ser ud til, at vi virkelig har brug for 16 forskellige tilstande, men denne nye switch har kun fire. Har vi skudt os selv i foden? Nix. Læs videre. Vi vil dække en lille smule af teorien bag drejekontakten for at forklare.

Trin 3: Hardwareteori om drift

Hardware teori om drift
Hardware teori om drift
Hardware teori om drift
Hardware teori om drift
Hardware teori om drift
Hardware teori om drift

Rotationsretningsregistrering er mulig ved hjælp af den førnævnte "single pole-16 throw" switch, men den bruger mange input på mikrokontrolleren. Brug af drejekontakten reducerer antallet af indgange til mikrokontrolleren, men nu er vi nødt til at fortolke signalerne fra kontakten og oversætte dem til en rotationsretning. Jeg nævnte tidligere, at kontakten var kvadraturkodet. Dette er også en af de vigtigste elegancer i denne løsning. Det betyder, at der er en 2-bit kode, kontakten giver, som svarer til switchens position. Du tænker måske: "Hvis der er en to bit input til mikrokontrolleren, hvordan repræsenterer vi alle 16 positioner?" Det er et godt spørgsmål. Vi repræsenterer dem ikke alle. Vi mangler bare at kende knappens relative positioner, så vi kan bestemme rotationsretningen. Knappens absolutte position er irrelevant. Ved rotation med uret gentages koden, som kontakten giver, hver fjerde spærring og er gråkodet. Gråkodet betyder, at der kun er en bitændring for hver positionsændring. I stedet for at AB -indgangen tæller op for rotation med uret i binær som denne: 00, 01, 10, 11, ændres den således: 00, 10, 11, 01. Bemærk, at for sidstnævnte mønster er der kun én indgang, der skifter mellem sæt. Værdierne mod uret for AB -input til mikrokontrolleren vil se sådan ud: 00, 01, 11, 10. Dette er ganske enkelt omvendt af urmønsteret med AB = 00 anført først. Tag et kig på diagrammerne for en mere visuel forklaring.

Trin 4: Softwareteori om drift

Softwareteori om drift
Softwareteori om drift

Den rutine, der udleder rotationsretningen, er interruptdrevet. Den mikrokontroller, du vælger, skal være i stand til at afbryde når som helst der er en ændring på en af (mindst) to ben, når afbrydelsen er aktiveret. Dette kaldes PORTB -ændringsafbrydelsen på PIC16F877A. Når som helst kontakten drejes, afbrydes mikrokontrolleren, og programafviklingen sendes til afbrydelsesrutinen (ISR). ISR vil hurtigt finde ud af, på hvilken måde kontakten blev drejet, sætte et flag korrekt og hurtigt vende tilbage til hovedprogrammet. Vi har brug for, at dette sker hurtigt, hvis brugeren roterer kontakten meget hurtigt. Vi ved, at det grå kodede AB -mønster gentages hver fjerde position, så hvis vi får rutinen til at fungere for overgange mellem de fire positioner, fungerer det for alle de andre. Bemærk, at der i en firepositionscyklus er fire kanter. En stigende kant og en faldende kant for A -input samt B -input. Mikroprocessoren afbrydes hver gang der er en kant, hvilket betyder, at mikrokontrolleren vil blive afbrudt, hver gang knappen drejes. Som et resultat heraf skal ISR finde ud af, hvilken vej knappen er drejet. For at hjælpe os med at finde ud af, hvordan vi gør dette, vender vi os til kurven for rotation med uret. Bemærk, at når A har en kant, er dens nye værdi altid forskellig fra B. Når knappen går fra position 1 til 2, overgår A fra logic-0 til logic-1. B er stadig 0 for denne overgang og matcher ikke den nye værdi af A. Når knappen går fra position 3 til 4, har A en faldende kant, mens B forbliver på logik-1. Bemærk igen, at B og den nye værdi af A er forskellige. Lige nu kan vi se, at når A forårsager afbrydelsen under rotation med uret, er dens nye værdi forskellig fra B. Lad os kontrollere B for at se, hvad der sker. B har en stigende kant, når kontakten overgår fra position 2 til 3. Her er den nye værdi af B den samme som A. Ser man på den sidste tilbageværende kant for rotation med uret, har B en faldende kant, der bevæger sig fra position 4 til 5. (Position 5 er den samme som position 1.) Den nye værdi af B er også den samme som A her! Vi kan nu foretage nogle fradrag! Hvis A forårsager afbrydelsen, og den nye værdi for A er forskellig fra værdien for B, var rotationen med uret. Hvis B derudover forårsager afbrydelsen, og den nye værdi af B er den samme som A, var rotationen med uret. Lad os hurtigt undersøge sagen om rotation mod uret. Ligesom rotation med uret vil rotation mod uret forårsage fire afbrydelser i en cyklus: to for input A og to for input B. Input A har en stigende kant, når knappen bevæger sig fra position 4 til 3 og en faldende kant, der bevæger sig fra position 2 til 1. Når knappen bevæger sig fra position 4 til 3, er den nye værdi af A den samme som værdien af B. Bemærk, at når A bevæger sig fra position 2 til 1, er dens nye værdi også den samme som B. Nu kan vi se, at når A forårsager afbrydelsen, og dens nye værdi matcher den for B, var rotationen mod uret. Hurtigt ser vi på input B for at verificere alt. B vil forårsage en afbrydelse, når knappen bevæger sig fra position 5 (hvilket er det samme som 1) til 4, og når knappen flyttes fra position 3 til 2. I begge disse tilfælde matcher den nye værdi af B ikke den eksisterende værdi af A, som er det modsatte af de tilfælde, hvor B forårsager afbrydelsen til rotation med uret. Dette er gode nyheder. Alt tjekker ud, som det skal. For at opsummere, hvis A forårsager afbrydelsen, og dens nye værdi ikke matcher værdien af B, eller hvis B forårsager afbrydelsen, og den nye værdi af B matcher værdien af A, ved vi, at der var rotation med uret. Vi kan kontrollere de andre sager for rotation mod uret i software, eller vi kan antage, at fordi det ikke var rotation med uret, var det mod uret. Min rutine gjorde simpelthen antagelsen.

Trin 5: Software

Software
Software
Software
Software

Jeg brugte ikke de indbyggede afbrydelser i PIC Basic Pro. Jeg brugte et par filer, som jeg inkluderede i min kode fra Darrel Taylor, til at køre rutinen. Det er her en enorm kredit til Darrel hører til! Filerne er gratis. Besøg bare hans websted for mere information, andre applikationer og for at downloade filerne. Du kan springe denne del over, hvis du ikke bruger en PIC med Darrel Taylor -afbrydelser. Bare konfigurer afbrydelserne efter behov på den platform, du bruger. For at få Darrel Taylor (DT) -afbrydelser sat op er der to ting at gøre: 1.) Inkluder DT_INTS-14.bas- og ReEnterPBP.bas-filerne i din kode.2.) Kopier og indsæt dette i din kode. ASMINT_LIST makro; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, ja endm INT_CREATEENDASMIndsæt faner og mellemrum som grafikken i slutningen af Instructable, så du kan se tingene lidt lettere i din kode. Du skal ændre det lidt, så det passer til dine behov. Under etiket skal du erstatte ISR med navnet på den underprogram, der er din ISR. Glem ikke understregningen! Du har brug for det! For at få afbrydelserne til at fungere er der to ting mere at gøre: 1.) Skriv ISR. Du skriver dette ligesom du skulle skrive en PBP -underprogram bortset fra at du bliver nødt til at indsætte @ INT_RETURN i slutningen af underprogrammet i stedet for RETURN. Dette vil anerkende afbrydelsen og returnere programkørsel til det sted, hvor den slap i hovedsløjfen. Inde i ISR'en skal du rydde afbrydelsesflagget, så dit program ikke bliver fanget i en rekursiv afbrydelse. Bare at læse PORTB er alt, hvad der skal gøres for at rydde afbrydelsesflaget på PIC16F877A. Hver forskellige mikrokontroller har en anden måde at slette afbrydelsesflag. Tjek databladet til din mikrokontroller. ting pakket ind i det, jeg lige dækkede, så jeg opsummerer hurtigt. Indtil videre skal dit program se sådan ud:; Enhver nødvendig opsætning 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; Enhver anden nødvendig opsætning eller kode@ INT_ENABLE RBC_INT; Kode, der skal vide, hvilken vej knappen drejer@ INT_DISABLE RBC_INT; Anden kodeEND; Slutning af programmyISR:; ISR -kode her@ INT_RETURN (Interrupt Handler Set Up Table) Jeg tror, det er her alle, der ikke bruger en PIC eller DT -afbrydelser, kan deltage igen. Nu skal vi faktisk skrive ISR'en, så mikrokontrolleren ved, hvilken vej knappen drejer. Husk fra softwareteori -afsnittet, at vi kan udlede rotationsretningen, hvis vi kender input, der forårsagede afbrydelsen, dens nye værdi og værdien af det andet input. Her er pseudokoden: Læs PORTB i en scratch -variabel for at rydde afbrydelsesflaget Kontroller, om A forårsagede afbrydelsen. Hvis det er sandt, sammenlign A og B. Kontroller, om det er anderledes, hvis det er anderledes, Det var rotation med uret Ellers, det var mod uret EndifCheck, om B forårsagede afbrydelsen. Hvis det er sandt, sammenlign A og B Kontroller, om det er anderledes, hvis det samme, Det var rotation med uret Ellers, Det var mod uret EndifReturn fra interruptHvordan ved vi, om en ændring på A eller B forårsagede afbrydelsen? Det er let at opdage den nye værdi for det ændrede input og det andet (uændret) input, fordi vi kan læse dem inde i ISR. Vi har brug for at vide, hvad tilstanden for hver enkelt var, før henrettelse sendes til ISR. Dette sker i hovedrutinen. Hovedrutinen sidder og venter på, at en bytevariabel, som vi kaldte CWflag, sættes til 1 eller slettes til 0 af ISR. Efter hver kvitteret ændring af knappen, eller hvis der ikke er nogen knopaktivitet, sættes variablen til 5 for at angive en inaktiv tilstand. Hvis flaget bliver indstillet eller ryddet, øger eller reducerer hovedrutinen straks setpunktstrykket på passende vis baseret på rotationen og sætter derefter CWflag -variablen tilbage til 5, fordi knappen nu er inaktiv igen. Da hovedrutinen er at kontrollere CWflag, dokumenterer den også tilstanden for A- og B -drejekontaktværdierne. Dette er virkelig simpelt og ser sådan ud: oldA = AoldB = BDer er virkelig ikke noget super fancy her. Medtag bare de to linjer i begyndelsen af sløjfen, der kontrollerer CWflag for rotation. Vi opdaterer bare de logiske værdier for input fra drejeknappen inde i inkrement/decrement loop i hovedrutinen, så vi kan se, hvilket input der forårsagede afbrydelsen, når ISR'en udføres. Her er ISR -koden: ABrektion: scratch = PORTB 'Læs PORTB for at rydde afbrydelsesflag' Hvis A forårsager afbrydelsen, skal du kontrollere B for rotationsretning IF gammelA! = A SÅ 'Hvis A og B er forskellige, var det rotation med uret IF A! = B DAN GOTO CW 'Ellers var det rotation mod uret ELLER GOTO CCW ENDIF ENDIF' Hvis B forårsager afbrydelsen, skal du kontrollere A for rotationsretning IF oldB! = B THEN 'Hvis A og B er ens, er det var rotation med uret IF A == B DAN GOTO CW 'Ellers var det rotation mod uret ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1@ INT_RETURNCCW: CWflag = 0@ INT_RETURN Jeg har inkluderet ISR -koden i en AB_ISR.bas -fil, fordi faner i koden vises ikke, som de skal. Nu, fordi ISR har de gamle værdier for input A og B, kan den bestemme, hvilken input der forårsagede afbrydelsen, sammenligne den med den anden (uændret) input og bestemme retningen af rotation. Alt, hvad hovedrutinen skal gøre, er at kontrollere CWflag for at se, hvilken retning knappen har drejet (hvis den har) og øge eller reducere en tæller, setpunkt eller hvad du vil eller har brug for. Jeg håber, at dette hjælper og ikke har været det også forvirrende. Denne type grænseflade er især nyttig, hvis dit system allerede bruger afbrydelser, da dette kun er endnu en afbrydelse at tilføje. God fornøjelse!

Anbefalede: