Innehållsförteckning:

Hur man tolkar rotationsriktningen från en digital vridomkopplare med en PIC: 5 steg
Hur man tolkar rotationsriktningen från en digital vridomkopplare med en PIC: 5 steg

Video: Hur man tolkar rotationsriktningen från en digital vridomkopplare med en PIC: 5 steg

Video: Hur man tolkar rotationsriktningen från en digital vridomkopplare med en PIC: 5 steg
Video: Så lyckas du på högskoleprovet: "repetera räkneregler" - Nyhetsmorgon (TV4) 2024, Juli
Anonim
Hur man tolkar rotationsriktningen från en digital vridomkopplare med en PIC
Hur man tolkar rotationsriktningen från en digital vridomkopplare med en PIC

Målet för denna instruerbara är att illustrera hur man kopplar en digital (kvadraturkodad) roterande switch till en mikrokontroller. Oroa dig inte, jag ska förklara vad kvadraturkodad betyder för oss. Detta gränssnitt och den medföljande programvaran gör det möjligt för mikrokontrollern att känna igen rotationsriktningen för varje förflyttning från en spärr till en annan. Jag använde nyligen denna typ av omkopplare i ett mikrokontrollerprojekt som krävde att ett tryck börvärde matades in med en vred med 16 spärrar istället för upp/ner -knapparna. Tanken var att låta användaren "ringa in" önskat tryck. Som ett resultat av det var vi tvungna att utveckla en mjukvarurutin för att få positionsinformationen från omkopplaren och härleda rotationsriktningen för att öka eller minska tryckbörvärdet för huvudsystemet. I denna instruktionsbok täcker jag det fysiska gränssnittet till mikrokontrollern, teorin om driften för vridomkopplaren, teorin om drift för programvaran samt avdragsrutinen. Slutligen visar jag dig min tillämpning av avdragsrutinen. När vi går framåt ska jag försöka hålla sakerna lite generiska så att idén kan tillämpas på så många plattformar som möjligt, men jag kommer också att dela med mig av vad jag gjorde så att du kan se en specifik applikation.

Steg 1: Delar

Delar
Delar

För att genomföra detta behöver du: En vridomkopplare (kvadraturkodad) Dra upp motstånd Lämplig mikrokontrollerplattform För mitt projekt använde jag en Grayhill 61C22-01-04-02 optisk kodare. Databladet för den roterande omkopplaren kräver 8,2k ohm uppdragningsmotstånd på de två datalinjerna som kommer från strömställaren. Du vill kontrollera databladet för den kodare du väljer att använda. Vridomkopplaren jag använde kan också beställas med en axiell tryckknappsbrytare. Det är en användbar funktion för att göra val som har ringts in, etc. men jag kommer inte att diskutera dess gränssnitt här. Jag har en "lämplig mikrokontrollerplattform" listad eftersom (jag tror) detta kan implementeras på mer än en plattform. Jag har sett många människor använda andra mikrokontroller för Instructables så jag vill också visa det allmänna tillvägagångssättet. Jag skrev all koden i PIC Basic Pro för användning med ett mikrochip PIC16F877A. Egentligen är det viktigaste du behöver på mikrokontrollern möjligheten att avbryta när det sker en logisk förändring på någon av två stift. På PIC16F877A kallas detta PORTB -ändringsavbrottet. Det kan finnas andra namn för det på andra kontroller. Denna avbrytarfunktion för mikrokontroller är en del av det som gör denna implementering så elegant.

Steg 2: Hårdvarugränssnitt

Hårdvarugränssnitt
Hårdvarugränssnitt

En "enkel" lösning skulle vara att ha en "single pole-16 throw" switch med 16 anslutningar till mikrokontrollern. Varje switchutgång skulle sedan knytas till en stift på mikrokontrollern så att varje rattposition kan kontrolleras av mikrokontrollern. Detta är en överdriven användning av I/O -stift. Saker blir ännu värre om vi vill ha mer än 16 positioner (spärrar) tillgängliga för oss på strömbrytaren. Varje extra position på omkopplaren skulle kräva en extra ingång till mikrokontrollern. Detta blir snabbt en mycket ineffektiv användning av ingångar på en mikrokontroller. Ange skönheten i den roterande omkopplaren. Den vridbara omkopplaren har bara två utgångar till mikrokontrollern listad som A och B på databladet. Det finns bara fyra möjliga logiska nivåer som dessa linjer kan ta: AB = 00, 01, 10 och 11. Detta minskar kraftigt antalet ingångslinjer du måste använda för att ansluta omkopplaren till mikrokontrollern. Så vi har minskat antalet inmatningsrader till bara två. Nu då? Det verkar som om vi verkligen behöver 16 olika tillstånd men den här nya omkopplaren har bara fyra. Har vi skjutit oss själva i foten? Nej. Läs vidare. Vi kommer att täcka lite av teorin bakom rotationsomkopplaren för att förklara.

Steg 3: Maskinvarudeori om drift

Maskinvarudeori om drift
Maskinvarudeori om drift
Maskinvarudeori om drift
Maskinvarudeori om drift
Maskinvarudeori om drift
Maskinvarudeori om drift

Rotationsriktningsavkänning är möjlig med den ovannämnda omkopplaren "single pole-16 throw", men den använder många ingångar på mikrokontrollern. Genom att använda vridomkopplaren reduceras antalet ingångar till mikrokontrollern men nu måste vi tolka signalerna som kommer från omkopplaren och översätta dem till en rotationsriktning. Jag nämnde tidigare att omkopplaren var kvadraturkodad. Detta är också en av de viktigaste eleganserna i denna lösning. Det betyder att det finns en 2-bitars kod som omkopplaren ger som motsvarar switchens position. Du kanske tänker: "Om det finns en tvåbitars ingång till mikrokontrollen, hur representerar vi alla 16 positioner?" Det är en bra fråga. Vi representerar inte dem alla. Vi behöver bara veta knoppens relativa positioner så att vi kan bestämma rotationsriktningen. Vredets absoluta position är irrelevant. För rotation medurs upprepas koden som omkopplaren ger var fjärde spärr och är gråkodad. Gråkodad betyder att det bara är en bitändring för varje positionsändring. Istället för att AB -ingången räknas upp för medurs rotation i binär så här: 00, 01, 10, 11, ändras den så här: 00, 10, 11, 01. Observera att för det senare mönstret är det bara en ingång som växlar mellan uppsättningar. Värdena moturs för AB -ingången till mikrokontrollern kommer att se ut så här: 00, 01, 11, 10. Detta är helt enkelt motsatsen till medurs med AB = 00 listat först. Ta en titt på diagrammen för en mer visuell förklaring.

Steg 4: Programvarudeori

Programvarudeori
Programvarudeori

Rutinen som härleder rotationsriktningen är avbrottsdriven. Mikrocontrollern som du väljer måste kunna avbryta när som helst det sker en ändring på någon av (minst) två stift när avbrottet är aktiverat. Detta kallas PORTB -ändringsavbrottet på PIC16F877A. Varje gång omkopplaren roteras kommer mikrokontrollern att avbrytas och programkörningen skickas till Interrupt Service Routine (ISR). ISR kommer snabbt att ta reda på på vilket sätt omkopplaren roterades, sätta en flagga på lämpligt sätt och snabbt återgå till huvudprogrammet. Vi behöver detta för att hända snabbt om användaren vrider omkopplaren väldigt snabbt. Vi vet att det gråkodade AB -mönstret upprepas var fjärde position, så om vi får rutinen att fungera för övergångar mellan de fyra positionerna fungerar det för alla andra. Lägg märke till att i en fyrlägescykel finns det fyra kanter. En stigande kant och en fallande kant för A -ingången samt B -ingången. Mikroprocessorn avbryts varje gång det finns en kant vilket innebär att mikrokontrollern kommer att avbrytas varje gång vredet vrids. Som ett resultat måste ISR räkna ut på vilket sätt ratten vrids. För att hjälpa oss att ta reda på hur vi gör detta vänder vi oss till vågformen för medurs rotation. Lägg märke till att varje gång A har en kant, är dess nya värde alltid annorlunda än B. När ratten går från position 1 till 2, övergår A från logic-0 till logic-1. B är fortfarande 0 för denna övergång och matchar inte det nya värdet av A. När ratten går från position 3 till 4 har A en fallande kant medan B förblir vid logik-1. Lägg märke till igen att B och det nya värdet på A är olika. Just nu kan vi se att när som helst A orsakar avbrottet under medurs rotation, är dess nya värde annorlunda än B. Låt oss kontrollera B för att se vad som händer. B har en stigande kant när omkopplaren övergår från position 2 till 3. Här är det nya värdet för B detsamma som A. Om man tittar på den sista kvarvarande kanten för medurs rotation, har B en fallande kant som rör sig från position 4 till 5. (Position 5 är samma som position 1.) Det nya värdet för B är samma som A också här! Nu kan vi göra några avdrag! Om A orsakar avbrottet och det nya värdet för A skiljer sig från det för B var rotationen medurs. Dessutom, om B orsakar avbrottet och det nya värdet för B är samma som A, var rotationen medsols. Låt oss snabbt undersöka fallet medurs. Precis som medurs rotation, kommer moturs rotation att orsaka fyra avbrott i en cykel: två för ingång A och två för ingång B. Ingång A har en stigande kant när vredet rör sig från position 4 till 3 och en fallande kant som flyttas från läge 2 till 1.. När vredet flyttas från position 4 till 3 är det nya värdet för A detsamma som värdet på B. Observera att när A flyttar från position 2 till 1 är det nya värdet samma som det för B också. Nu kan vi se att när A orsakar avbrottet och dess nya värde matchar det för B var rotationen moturs. Snabbt tittar vi på ingång B för att verifiera allt. B kommer att orsaka ett avbrott när ratten flyttas från position 5 (vilket är samma som 1) till 4 och när ratten flyttas från position 3 till 2. I båda dessa fall matchar det nya värdet för B inte det befintliga värdet av A som är motsatsen till de fall då B orsakar avbrottet för medurs rotation. Det här är goda nyheter. Allt checkar ut som det borde. För att sammanfatta, om A orsakar avbrottet och dess nya värde inte matchar värdet på B eller om B orsakar avbrottet och det nya värdet för B matchar värdet på A vet vi att det var medurs rotation. Vi kan kontrollera de andra fallen för rotation moturs i programvara eller så kan vi anta att eftersom det inte var medurs var det moturs. Min rutin gjorde helt enkelt antagandet.

Steg 5: Programvara

programvara
programvara
programvara
programvara

Jag använde inte de inbyggda avbrotten i PIC Basic Pro. Jag använde ett par filer som jag inkluderade i min kod från Darrel Taylor för att driva rutinen. Det är här en enorm kredit till Darrel hör hemma! Filerna är gratis. Besök bara hans webbplats för mer information, andra applikationer och för att ladda ner filerna. Du kan hoppa över den här delen om du inte använder en PIC med Darrel Taylor -avbrott. Ställ bara in avbrotten efter behov på den plattform du använder. För att ställa in Darrel Taylor (DT) -avbrotten finns det två saker att göra: 1.) Inkludera DT_INTS-14.bas- och ReEnterPBP.bas-filerna i din kod.2.) Kopiera och klistra in detta i din kod. ASMINT_LIST makro; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, yes endm INT_CREATEENDASMinni flikar och mellanslag som grafiken i slutet av instruktionsboken så att du kan se saker lite lättare i din kod. Du måste ändra det något för att passa dina behov. Under Etikett, ersätt ISR med namnet på den underrutin som är din ISR. Glöm inte understrykningen! Du behöver det! För att få avbrotten att fungera finns det ytterligare två saker att göra: 1.) Skriv ISR. Du skriver det här precis som om du skulle skriva en PBP -subrutin förutom att du måste infoga @ INT_RETURN i slutet av subrutinen istället för RETURN. Detta kommer att bekräfta avbrottet och återföra programkörningen till där det slutade i huvudslingan. Inuti ISR måste du rensa avbrottsflaggan så att ditt program inte fastnar i ett rekursivt avbrott. Att bara läsa PORTB är allt som behöver göras för att rensa avbrottsflaggan på PIC16F877A. Varje mikrokontroller har ett annat sätt att rensa avbrottsflaggor. Kontrollera databladet för din mikrokontroller. saker packade i det jag just täckte så jag sammanfattar snabbt. Hittills bör ditt program se ut ungefär så här:; Vilken konfiguration som helst eller kodINCLUDE "DT_INTS-14.bas" INCLUDE "ReEnterPBP.bas" ASMINT_LIST makro; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _myISR, PBP, ja endm INT_CREATEENDASM; Alla andra nödvändiga inställningar eller kod@ INT_ENABLE RBC_INT; Kod som behöver veta på vilket sätt ratten roterar@ INT_DISABLE RBC_INT; Annan kodEND; Slut på programmyISR:; ISR -kod här@ INT_RETURN (Interrupt Handler Set Up Table) Jag tror att det är här alla som inte använder PIC- eller DT -avbrott kan gå med igen. Nu måste vi faktiskt skriva ISR så att mikrokontrollern vet åt vilket håll ratten roterar. Kom ihåg från programvarudeorisektionen att vi kan härleda rotationsriktningen om vi känner till ingången som orsakade avbrottet, dess nya värde och värdet på den andra ingången. Här är pseudokoden: Läs in PORTB i en skrapvariabel för att rensa avbrottsflaggan Kontrollera om A orsakade avbrottet. Om det är sant, jämför A och B. Kontrollera om det är annorlunda, om det är annorlunda. Det var medurs rotation Annars, det var moturs EndifCheck om B orsakade avbrottet. Om det är sant, jämför A och B Kontrollera om det är annorlunda, om samma, Det var medurs rotation Annars, Det var moturs EndifReturn från interrupt Hur vet vi om en förändring på A eller B orsakade avbrottet? Att upptäcka det nya värdet för den ändrade ingången och den andra (oförändrade) ingången är lätt eftersom vi kan läsa dem inuti ISR. Vi måste veta hur var och en var innan avrättningen skickas till ISR. Detta händer i huvudrutinen. Huvudrutinen sitter och väntar på att en bytevariabel som vi kallade CWflag ska ställas in på 1 eller rensas till 0 av ISR. Efter varje kvitterad ändring av vredet eller om det inte finns någon vredaktivitet, ställs variabeln till 5 för att indikera ett viloläge. Om flaggan blir inställd eller rensas, ökar eller minskar huvudrutinen omedelbart börvärdetrycket på lämpligt sätt baserat på rotationen och sätter sedan tillbaka CWflag -variabeln till 5 eftersom ratten nu är inaktiv igen. Eftersom huvudrutinen är att kontrollera CWflag, dokumenterar den också tillståndet för A- och B -omkopplarens värden. Det här är verkligen enkelt och ser ut så här: oldA = AoldB = BDet finns verkligen inget superfint här. Inkludera bara de två raderna i början av slingan som kontrollerar CWflaggen för rotation. Vi uppdaterar bara logikvärdena för ingångarna från vridknappen inuti inkrement/sänkningsslingan i huvudrutinen så att vi kan se vilken ingång som orsakade avbrottet när ISR körs. Här är ISR -koden: ABändring: scratch = PORTB 'Läs PORTB för att rensa avbrottsflagga' Om A orsakar avbrottet, kontrollera B för rotationsriktning OM gammaltA! = A DÅ 'Om A och B är olika var det rotation medurs IF A! = B SEDAN GOTO CW 'Annars var det moturs rotation ELLER GOTO CCW ENDIF ENDIF' Om B orsakar avbrottet, kontrollera A för rotationsriktning IF gammalB! = B DÅ 'Om A och B är desamma, är det var rotation medsols OM A == B Därefter GOTO CW 'Annars var det moturs rotation ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1@ INT_RETURNCCW: CWflag = 0@ INT_RETURNI Jag har inkluderat ISR -koden i en AB_ISR.bas -fil eftersom flikar i koden visas inte som de ska. Nu, eftersom ISR har de gamla värdena för ingångar A och B kan den avgöra vilken ingång som orsakade avbrottet, jämföra den med den andra (oförändrade) ingången och bestämma riktningen av rotation. Allt huvudrutinen behöver göra är att kontrollera CWflaggen för att se vilken riktning vredet har vridit (om det har) och öka eller minska en räknare, börvärde eller vad du vill eller behöver. Jag hoppas att detta hjälper och inte har varit det för förvirrande. Denna typ av gränssnitt är särskilt användbart om ditt system redan använder avbrott eftersom detta bara är ytterligare ett avbrott att lägga till. Njut av!

Rekommenderad: