PIC-handledning - Från register till avbrott

Prova Vårt Instrument För Att Eliminera Problem





Innan du går in på de små detaljerna i PIC-programmering, är det först viktigt att lära sig några bra programmeringsmetoder.

Förståelse av register

Till att börja med antar att du skriver a (semikolon) när som helst i programmet, allt som kommer efter detta semikolon skulle ignoreras av kompilatorn tills naturligtvis vagnen kommer tillbaka till positionen.



Ovanstående funktion gör att vi kan lägga till kommentarer eller kommentarer så att de inte blir en del av programmet men ändå underlättar oss att identifiera programmet med hjälp av kommentarerna bredvid det. Att lägga kommentarer är en rekommenderad metod när man programmerar någon IC.

Nästa viktiga sak i kursen är att tilldela namn till de olika konstanterna (du skulle lära dig dem senare utförligt). Detta gör det också enklare att förstå vad som skrivs till, eller om de involverade värdena, istället för att bli förvirrad med de inkluderade siffrorna.



Ovanstående måste göras i form av faktiska namn för omedelbar igenkänning, till exempel COUNT, det skulle vara viktigt att notera att här används alla stora bokstäver för att göra det tydligt och indikerar också att det är ett konstant värde.


Som vi kan se görs ovanstående i form av en låda gjord av semikolon, det gör att den bara ser renare ut. Försök också att dokumentera programmet på papper, den här övningen hjälper dig att förstå saker på ett stegvis sätt.

2. Registren.

Registret inom en PIC är ett område som accepterar skriftliga detaljer och som gör det möjligt att läsa från det. Du kan jämföra det med ett pappersark där du kan visualisera innehåll och även lägga till genom att skriva över det.

Figuren nedan visar en typisk registerfilkarta inbäddad i en PIC16F84. Formatet är inte något som faktiskt är inställt inuti PIC, det är helt enkelt för att ange hur bitarna kan ordnas inuti chipet och för att förstå några av de inblandade kommandona.

Du kan se att den i grund och botten är uppdelad i Bank 0 och Bank 1. Bank 1 ansvarar för att styra PIC: ns faktiska funktion, till exempel tel PIC vilka bitar vid Port A som tilldelas som ingångar och vilka som utgångar.

Bank 2 är bara för att manipulera informationen.

Låt oss förstå detta genom följande exempel:

Antag att vi vill tilldela en bit vid PortA high. För detta skulle vi först behöva gå till Bank 1 för att ställa in den angivna biten eller stiftet vid Port A i form av en utgång. Efter detta återvänder vi till Bank 0 och levererar en logisk 1 (bit 1) till den specifika stiftet.

De vanligaste registren som vi gärna vill använda i Bank 1 är STATUS, TRISA och TRISB.

STATUS hjälper oss att återvända till bank 0, TRISA tillåter oss att välja vilka stift vid port A som är utgångar och vilka som kan vara ingångar, medan TRISB underlättar att välja mellan utgång och ingångsstift vid port B. SELECT-registret i BANK 0 tillåter användaren att bläddra till Bank 1.

Låt oss sammanfatta hela konceptet med följande beskrivning:

STATUS:

För att byta från bank 0 till bank 1 kommanderar vi STATUS-registret. Detta implementeras genom att ställa in bit # 5 i STATUS-registret till 1. För att återvända till Bank 0 tilldelar vi bit 5 i STATUS-registret till 0. STATUS-registret är placerat vid adress 03h, här betyder h tat numret kan vara i Hexadecimal.

TRISA och TRISB:

Dessa ligger på adress 85h och 86h på motsvarande sätt. För att programmera en stift som en utgång eller en ingång levererar vi bara en noll eller en till den specifika biten i registret. Nu kan detta göras på två sätt, via binär eller Hex. Om man inte kan konvertera parametern kan han eller hon gå till en vetenskaplig kalkylator för att implementera värdena.

Nu har vi 5 stift vid port A, vilket motsvarar 5 stift. Om vi ​​tänker fixa en av stiften som ingångar levererar vi en '1' till den specifika biten.

Om vi ​​ville tilldela en av stiften som utgångar skulle vi ställa in den specifika stiftet till “0”. Bitarna är hjälpmedel exakt motsvarande bitarna, eller mer exakt bit 0 är RA0, bit 1 skulle vara RA1, bit 2 = RA2 och så vidare. Låt oss förstå det på detta sätt:

Antag att du vill fixa RA0, RA3 och RA4 som utgångar, medan RA1 / RA2 som i / ps, skulle du göra detta genom att skicka 00110 (06h). Kontrollera att bit 0 är åt höger enligt vad som anges här:

Port A Stift RA4 RA3 RA2 RA1 RA0

Bitnummer 4 3 2 1 0

Binär 0 0 1 1 0

Detsamma gäller TRISB.

PORTA och PORTB

För att avge en av utgångsstiften högt, erbjuder vi bara en “1” för respektive bit i vårt PORTA- eller PORTB-register. En identisk procedur kan också följas för TRISA- och TRISB-register. Innan vi går in i vårt första exempel på kodning, låt oss bara förstå en kupong med fler register, nämligen w och f.

W och F

W-registret är ett vanligt register som gör att du kan tilldela valfritt värde. Så snart du tilldelar W en storlek kan du fortsätta genom att lägga till detta till ett annat värde eller helt enkelt flytta det. När ett annat värde tilldelas skrivs detaljerna helt enkelt över på W.

F-registret vidarebefordrar sitt skriftliga ämne till ett register. Vi skulle kräva att detta F-register tilldelar ett värde över ett register, kan vara över STATUS- eller TRISA-registren, eftersom dessa inte tillåter oss att lägga värdena direkt över dem. Ett exempelprogram

Låt oss undersöka följande exempelkod som visar oss hur ovanstående instruktion implementeras och skulle också bevittna några av instruktionerna i kursen.

Låt oss börja med att fixa Port A enligt ovan.

För detta måste vi flytta från Bank 0 till Bank1, detta görs genom att ställa in STATUS-registret beläget på adress 03h, bit 5 till 1.

BSF 03h, 5

BSF betyder bituppsättning F. Vi använder två siffror efter denna instruktion - 03h, vilket är STATUS-registeradressen, och siffran 5 som motsvarar bitnumret.

Så vad vi säger är ”Ställ in bit 5 i adress 03h till 1”.

Vi är nu i Bank 1.

MOVLW 00110b

Vi lägger in det binära värdet 00110 (bokstaven b betyder att numret är i binärt) i vårt allmänna register W. Jag kunde naturligtvis ha gjort det i hex, i vilket fall vår instruktion skulle vara:

MOVLW 06h

Antingen fungerar. MOVLW betyder 'Move Literal Value Into W', vilket på engelska betyder att sätta värdet som följer direkt i W-registret.

Nu måste vi lägga detta värde i vårt TRISA-register för att ställa in porten:

MOVWF 85h

Denna instruktion indikerar 'Flytta innehållet i W till registeradressen som följer', i detta fall hänvisar adressen till TRISA.

Vårt TRISA-register har nu siffran 00110 eller presenteras grafiskt:

Port A Stift RA4 RA3 RA2 RA1 RA0

Binär 0 0 1 1 0

Ingång / utgång O O I I O

Så nu har vi våra Port A-stift, vi måste återvända till Bank 0 för att justera en av informationen.

BCF 03h, 5

Denna instruktion åstadkommer omvänd BSF. Det innebär 'Bit Clear F'. Ett antal nummer som motsvarar är adressen till registret, här STATUS-registret, liksom bitfiguren, i detta fall bit fem. Vad vi just har slutfört just nu är definierad bit fem på vår

STATUS registrera till 0

Vi har nu återvänt till bank 0.
Följande är koden i ett block:

BSF 03h, 5 Gå till Bank 1
MOVLW 06h Sätt 00110 i W
MOVWF 85h Flytta 00110 till TRISA
BCF 03h, 5 Kom tillbaka till Bank 0

Inom den senaste instruktionen bekräftade vi dig sättet att skapa IO-portstift på PIC så att de eventuellt kan matas in eller ut.

Genom den här kursen, låt mig hjälpa dig att skicka data till portarna.

Skicka data till portar

I den efterföljande handledningen kommer vi att slutföra genom att blinka en LED på och av som består av en fullständig programdetalj och ett enkelt kretsschema så att du kan se att PIC utför exakt vad vi förväntar oss.

Försök inte att sätta ihop och programmera din PIC med resultaten nedan, eftersom de endast är illustrationer. Inledningsvis kommer vi att etablera Port A bit 2 som en utgång:

Detta kan kännas igen från den tidigare instruktionen. Den enda skillnaden kan vara. Vi har fixat varje bit av stiften på A som utdata, genom att leverera 0h till tri-state-registret. Så vad han nu måste göra är att sätta på en LED.

Vi åstadkommer detta genom att schemalägga en av stiften (den med lysdioden kopplad till den) högt. För att uttrycka det annorlunda applicerar vi en '1' på stiftet. Detta är exakt hur det utförs (observera kommentarerna för en förtydligande för varje rad):

Därför, vad vi nu har åstadkommit är att sätta på och sedan släcka lampan en gång. Vad vi önskar är att lysdioden slås på därefter kontinuerligt.

Vi uppnår detta genom att få programmet för att återgå till starten. Vi åstadkommer detta genom att inledningsvis skapa en tagg i början av vårt program och därefter informera programmet om att gå vidare dit. Vi anger en tagg helt enkelt.

Vi skriver in en term, säg START, skriv sedan koden:

Som visats nämnde vi ursprungligen uttrycket 'Start' direkt i början av programmet.

Därefter nämnde vi helt klart ”goto Start” i slutet av programmet. Instruktionen ”goto” utför precis vad den förklarar.

Detta program skulle alltid tända och stänga av lysdioden när vi slår på strömmen och tenderar att stängas av när vi tar bort elen. Vi kanske borde kolla vårt program ännu en gång:

Visst har vi utelämnat kommentarerna, men vi kan fortfarande följa instruktionerna och siffrorna.

Detta kan vara lite förbryllande senare om du försöker felsöka programmet och medan du skriver koden har du memorerat alla adresser.

Även om kommentarerna kan placeras fortfarande kan det bli lite rörigt. Detta kommer att kräva namngivning av siffrorna och kan uppnås genom en ytterligare instruktion: 'equ' Instruktionen 'equ' antyder att vissa saker kan vara lika med andra saker.

Det kanske inte är en instruktion för PIC, snarare för monteraren. Denna instruktion underlättar tilldelning av namn till en registeradressplats eller en konstant till en programmeringsperiod.

Vi kommer att upprätta några konstanter för vårt program och bevittna också hur mycket enkelt det läser programmet.

Sedan nu har vi fixat de konstanta värdena vi kan fortsätta genom att ställa in dem i vårt program. De konstanta värdena måste anges innan de används.

se därför till att alltid placera dem i början av programmet. Vi kommer att skriva om programmet exklusive kommentarer en gång till för att jämföra den tidigare märkningen med den senaste.

Kanske kan du märka att konstanterna möjliggör något lättare förståelse av programmet, men vi är fortfarande utan kommentarer, dock inga bekymmer, eftersom vi ännu inte är färdiga.

Det kan finnas en mindre nackdel med vårt blinkande LED-program.
Varje instruktion behöver en klocksekvens för att avslutas. Om vi ​​använder en 4MHz kristall, kräver varje instruktion att 1 / 4MHz eller 1uS ska avslutas.

Eftersom vi bara har använt fem instruktioner, skulle lysdioden aktiveras och sedan släcks i 5uS. Detta kan vara alltför snabbt för att folk ska märka, dessutom verkar det som om lysdioden är helt tänd.

Vad vi istället bör åstadkomma är att skapa en hämning mellan att sätta på lysdioden och att stänga av lysdioden. Teorin om hämningen är att vi räknar ner från en tidigare kvantitet, så när det blir noll slutar vi räkna.

Nollvärdet betyder slutförandet av förseningen, och vi fortsätter att arbeta vår process under hela programmet. Därför är det första vi måste göra att bestämma en konstant att använda som vår räknare.

Låt oss beteckna detta konstanta ANTAL. Därefter måste vi avgöra hur viktigt ett nummer vi ska börja räkna från. Visst är den största siffran vi kan inkludera 255, eller FFh i hex., Som jag pratade om i den tidigare handledningen, tilldelar equ-instruktionen ett uttryck till en registersituation.

Detta innebär att oavsett vilken kvantitet vi tilldelar vårt COUNT, skulle det matcha artiklarna i ett register. Om vi ​​försöker beteckna värdet FFh, kommer vi att få ett misstag när vi har sammanställt programmet.

Anledningen är platsen FFh är, därför kan vi inte få tillgång till den. Hur måste vi därför utse ett äkta nummer? Visst kommer det att kräva en liten mängd lateral fundering.

Om vi ​​till exempel anger vårt RÄKNING till adressen 08h, skulle detta indikera en grundläggande målregisterdestination. Som standard är de orörda områdena inställda på FFh. Följaktligen, om COUNT leder till 08h, kommer du att stöta på värdet på FFh medan vi startar först. Ändå, jag du, hur kan vi fixa COUNT till ett annat nummer ?, allt vi tillämpar är att 'flytta' en värdering till den här destinationen först.

Som en illustration, antar att vi ville att COUNT skulle ha ett värde på 85h, kan vi inte nämna COUNT ekv 85h eftersom det är läget för vårt Tri-State-register för Port A. Exakt vad vi åstadkommer är följande: movlw 85hFörsta sättet värdet 85h i W-registret movwf 08h

Flytta det nu till vårt 08-register. Därefter, om vi uttrycker COUNT ekv 08h, skulle COUNT matcha värdet 85h. Delikat, är det inte! Därför bestämmer vi inledningsvis vår konstant: COUNT ekv 08h Följande måste vi minska detta COUNT med en tills den blir noll.

Det händer helt enkelt så att det finns en instruktion som är utformad för att uppnå detta för oss genom att använda en ”goto” och en tagg.

Instruktionen vi ska tillämpa är: DECFSZ COUNT, 1 Denna instruktion säger 'Minska registret (här är det COUNT) med numret som spårar komma. Om vi ​​uppnår noll, hoppa två punkter framåt. ”Låt oss hitta den i aktion först innan vi placerar den i vår kurs.

Vad vi har utfört är initialt att fastställa vårt konstanta COUNT till 255. Det efterföljande segmentet placerar en tagg, som heter LABEL nära vår decfsz-instruktion.

Decfsz COUNT, 1 minskar värdet på COUNT med ett och behåller slutresultatet rakt till COUNT. Dessutom verifierar det att kontrollera om COUNT har ett värde på 0.

Om den inte gör det, utlöser det i så fall programmet att växla till nästa rad. Nu har vi en ”goto” -deklaration som ger oss tillbaka till vår decfsz-instruktion.

Om värdet på COUNT fungerar lika, resulterar decfsz-instruktionen i vårt program att hoppa två platser framåt och skickas dit vi har hävdat att 'Fortsätt här'.

Eftersom du kan observera har vi därför fått programmet att sitta på en plats en förutbestämd tid innan du fortsätter. Detta kan kallas en fördröjningsslinga.

Förstå fördröjningsslingor

Om vi ​​behöver en mer omfattande fördröjning kan vi följa en slinga i nästa. De extra slingorna, desto längre fördröjning. Låt oss åtminstone två, förutsatt att vi vill observera LED-blixt .. Vi kommer att placera dessa fördröjningsslingor i vårt program och åstadkomma genom att göra det till ett genuint program genom att införa kommentarer:

Det är möjligt att sammanställa detta program efter vilket program PIC. Var uppenbarligen säker på att du försöker kretsen för att kontrollera om den verkligen fungerar. Följande är ett kretsschema som du bör konstruera så snart du har programmerat PIC.


Bra gjort, du kunde faktiskt ha komponerat ditt första PIC-program, samt konstruerat en krets för att blinka en LED på och av. Hittills, om du har följt dessa kurser, kanske du har lärt dig totalt sju instruktioner av 35, men utan tvekan hittills kan du styra I / O-portarna!

Skulle du försöka ändra fördröjningsslingorna för att göra LED-blixt snabbare - vad verkar det minimala värdet på COUNT för att i huvudsak se LED-blixt? Eller kanske vill du inkludera en tredje eller kompletterande fördröjningsslinga efter den första för att stabilisera LED-lampan. en unik konstant för varje fördröjningsslinga.

Du kan eventuellt sedan lura med dina fördröjningsslingor för att återge LED-blixten med en viss hastighet, till exempel efter en sekund. Låt oss inom nästa instruktion se hur vi kan använda något som kallas en subrutin för att upprätthålla programmet kompakt och grundläggande. En subrutin är en integrerad del av koden eller programmet som kan kallas och när du kan behöva det. Underrutiner används i fall där du ofta utför samma funktion.

Vad är underrutiner

Fördelarna med att använda en subrutin är att det sannolikt kommer att bli enklare att ändra värdet en gång inuti en subrutin istället för att säga tio gånger genom hela ditt program, liksom det bidrar mycket till att minska minnesnivån som ditt program förbrukar inuti BILD. Vi kommer att kolla in en underrutin:

Inledningsvis måste vi ge vår underrutin en beteckning, och i denna situation har vi valt RUTIN. Vi skriver därefter koden som vi vill utföra som normalt. Det är därför vi har valt förseningen i vårt blinkande LED-program. Slutligen avslutar vi underrutinen genom att skriva in RETURN-instruktionen.

För att börja subrutinen var som helst i vårt program skriver vi snabbt instruktionen CALL och sedan subrutinbeteckningen.

Vi kommer att överväga detta lite mer djupt. När vi väl har kommit till den del av vårt program som CALL xxx, där xxx är namnet på vår underrutin, hoppar programmet till var som helst subrutinen xxx är installerad. Instruktionerna inuti subrutinen utförs.

Närhelst instruktionen RETURN genomförs, hoppar programmet tillbaka till vårt huvudprogram till instruktionen efter vår CALL xxx-instruktion.

Det är möjligt att ringa liknande subrutiner flera gånger som du vill, vilket förklarar varför användning av subrutiner minskar den allmänna varaktigheten för vårt program.

Ändå finns det ett par faktorer du bör känna till. Inledningsvis, som med vårt huvudprogram, måste alla specifika konstanter bekräftas innan du kan använda dem.

Dessa kan eventuellt erkännas i själva underrutinen eller direkt i början av huvudprogrammet. Jag föreslår att du erkänner allt i början av ditt huvudprogram, eftersom du sedan inser att saker och ting är i identisk position. Därefter bör man se till att huvudprogrammet hoppar över subrutinen.

Vad jag antyder med detta är att om du placerar subrutinen direkt i slutet av ditt primära program, förutom om du använder en 'Goto' -deklaration för att hoppa från var subrutinen är, skulle programmet fortsätta och implementera subrutinen oavsett om du kräver det till eller på annat sätt.

PIC skiljer inte mellan en subrutin och huvudprogrammet. Vi kommer att kolla in vårt blinkande LED-program, men den här gången ska vi använda en subrutin för fördröjningsslingan. Helst kommer du att upptäcka hur mycket mindre komplicerat programmet ser ut, liksom att du kanske hittar hur subrutinen praktiskt gäller.

Så småningom kan du se att genom att använda en underrutin för vår fördröjningsslinga kan vi ha minskat programmets dimensioner.

Varje gång vi önskar en fördröjning, eventuellt när lysdioden är på eller av, kallar vi i princip fördröjningen underrutin. Efter avslutad subrutin leder programmet tillbaka till linjen enligt vår ”Call” -instruktion. I bilden ovan tänder vi lampan.

Vi kontaktar sedan subrutinen. Programmet kommer sedan tillbaka så att vi kan stänga av lysdioden. Vi kallar subrutinen en gång till, bara om subrutinen kanske har slutförts, kommer programmet tillbaka och den efterföljande instruktionen som den känner igen är ”goto Start”. För alla som kan vara intresserade var vårt första program 120 byte långt.

Genom att använda subrutinen kan vi minska vår programstorlek ner till 103 byte. Det här kunde inte låta så fantastiskt, men med tanke på det faktum att vi bara har totalt 1024 byte inuti PIC, är varje liten mängd fördelar.

Låt oss kolla in läsning från portarna inom nästa instruktion.

Hittills har vi komponerat till Port A för att vi ska kunna slå på och av en LED. Vid den här tiden kommer vi att se hur vi ska läsa I / O-stiften på portarna.

Läser in- / utgångsportar

Detta är exakt för att säkerställa att vi kan länka en extern krets och påverka alla specifika utgångar som den erbjuder.

Om du kommer ihåg från våra tidigare kurser, om du vill etablera I / O-portarna, behövde vi hoppa från bank 0 till bank 1. Vi kommer att uppnå det initialt:

Vid denna tidpunkt har vi fixat bit 0 i Port A för ingång. vi måste nu undersöka om stiftet är högt eller lågt. För att uppnå detta kan man bara använda en av två instruktioner:

BTFSC och BTFSS.

BTFSC-instruktionen betyder 'Gör ett bitprov i registret såväl som den bit vi anger.

Om det är ett 0, i det fallet utelämnar vi den efterföljande instruktionen ”. BTFSS innebär 'Gör ett bitprov i registret och den bit vi etablerar. Om den är inställd på 1, förbi vi den efterföljande instruktionen.

Vilken vi använder bestäms av exakt hur vi önskar att vårt program ska svara medan vi studerar input. Som en illustration, om vi bara väntar på att ingången ska vara en 1, kan vi kanske använda BTFSS-instruktionen på följande sätt:

Kod här:

BTFSS PortA, 0Gå igång Fortsätt här:
:

Programmet växlar bara till 'Fortsätt här' förutsatt att bit 0 på PortA är schemalagd till 1.

Vi kommer för närvarande att skriva ett program som kan leda till en lysdiod i samma takt, men om en omkopplare är begränsad skulle den blinka lysdioden två gånger så långsammare.

Det är möjligt att utöva detta program på egen hand, ändå Vi har införlivat listan på något sätt.

Du kan försöka och författa hela programmet för att kontrollera om du förstår principerna. Vi kommer att använda motsvarande krets som tidigare, med inkludering av en brytare ansluten RA0 av PIC och den positiva skenan för vårt utbud.

Vad vi har åstadkommit här är att tända lampan. Därefter bestämmer jag om strömbrytaren är stängd.

Om det är begränsat, ansluter jag nästa till vår fördröjningsundervisning. Detta ger oss motsvarande fördröjning som tidigare, men vi kontaktar vid det här tillfället två gånger.

Samma sak gäller när LED-lampan är släckt. Om strömbrytaren inte är stängd, har vi registrerat våra tidigare på- och avstängningsperioder.

Har du följt dessa lektioner från början, kanske du försöker förstå att du för närvarande har upptäckt tio av de 35 instruktionerna för PIC 16F84! Och varje bit av dessa lär sig bara genom att sätta på och stänga av en LED.

Hittills har vi komponerat PIC blinkar en LED på och av.

Därefter kunde vi med vår PIC genom att inkludera en omkopplare, därför varierade blixtens hastighet.

Använda minnesutrymme effektivt

Det enda problemet är att programmet är ganska långt och ganska ineffektivt med minne. Det verkade ok medan jag inkluderade kommandona för första gången, men det borde finnas ett enklare sätt att utföra det. Positivt finns det, vi kommer att analysera hur vi bokstavligen slog på och av lysdioden.

movlw 02hmovwf PORTAmovlw 00hmovlw PORTA

Först fyllde vi vårt w-register med 02h, därefter överfördes det till vårt PortA-register för att tända lampan. För att stänga av den packade vi w med 00h, varefter den flyttades till vårt PortA-register.

Mellan alla dessa rutiner tvingades vi komma i kontakt med en underrutin för att säkerställa att vi kunde observera att LED blinkar.

Därför behövde vi överföra två uppsättningar info ett par gånger (en gång till w-registret sedan till PORTA) samt ringa en subrutin två gånger (en gång för på och sedan en gång för av). Således, hur skulle vi kunna uppnå detta med extra effektivitet? Väldigt enkelt.

Vi använder en annan instruktion som kallas XORF. XORF-instruktionen fungerar som en exklusiv ELLER-funktion i registret som vi anger med den information vi tillhandahåller. Jag tror att jag måste klargöra vad i världen en exklusiv ELLER är innan vi fortsätter. Om vi ​​har två ingångar och en utgång kan ingången bara vara 1 om, och så länge de två ingångarna skiljer sig åt. Medan de är desamma kommer utdata troligen att vara 0. Följande är en sanningstabell för individer som väljer att kolla in dessa:

A B F0 0 00 1 11 0 11 1 0

Vi kommer vid den här tiden att kolla vad som händer om vi gör B precis som vår tidigare produktion och helt enkelt ändrar värdet på A:

A B F
0 0 0
0 0 0
1 0 1
1 1 0
1 0 1

Om vi ​​bibehåller värdet på A samma som 1, och vi exklusiva ELLER det med utgången, skulle utgången växla. Om du inte kan lägga märke till detta från sanningstabellen kan du se det nedan genom att använda binär:

0 Strömutgång
EX-ELLER Med 1 1 Ny utgång
EX-ELLER Med 1 0 Ny utgång

Kanske kan du upptäcka att genom att exklusiv ORing utdata med 1, växlar vi nu utdata från 0 till 1 till 0.
Därför behöver vi bara ett par meningar för att slå på och av vår LED:

MOVLW 02h
XORWF-DÖRR, 1

Vad vi just kommer att uppnå är att lägga till vårt w-register med 02h. Vi är i så fall exklusiva ELLER beställa detta nummer oavsett vad som finns på vår PortA. Om bit 1 är en 1 kommer den att ändras till en 0. Om bit 1 är en 0 kommer den att ändras till en 1. Låt oss undersöka den här koden en eller två gånger för att visa hur den kör binärt:

DÖRR
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

Vi behöver faktiskt inte ladda samma värde i vårt w-register varje gång, därför är det möjligt att uppnå detta en gång i början och helt enkelt hoppa tillbaka till vårt växlingskommando. Dessutom borde vi inte fastställa ett värde i vårt PortA-register. Anledningen? Visst, eftersom det är en 1 vid strömförsörjning kan vi enkelt växla mellan den. Jag, alternativt en 0 på power up, vi skulle till och med nu växla mellan den.

Därför vill du se vår nybildade kod. Den första representerar vår blinkande LED-kod, medan den andra visar den med tillägget av omkopplaren:

Låt oss önska att du kan hitta att helt enkelt genom att använda en enkel instruktion, har vi nu minskat skalan för vårt program. Sanningen är att för att visa hur mycket vi kan minska våra program med, har vi visat de två programmen, precis vad som komponerades och deras dimensioner i tabellen nedan:

Program Alter Dimensions (Bytes)
Blinkande LED Original 120
Blinkande LED-subrutin tillagd 103
Blinkande LED XOR-funktion 91
LED med omkopplare Original 132
LED med omkopplare XOR-funktion 124.

Därför har vi inte bara upptäckt några nya instruktioner utan vi har också minskat storleken på vårt skript!

Nedan analyserar vi hur du kan vinkla enskilda bitar, genomföra vissa enkla aritmetiska data samt datatabeller.

Logiska chefer

Under den senaste handledningen presenterade jag Exclusive OR-operationen. ExOR-funktionen förstås som en logisk operatör.

I denna handledning kommer jag att belysa de ytterligare logiska operatörerna som PIC främjar. Det kommer inte att finnas något slags fall i punktprogram, men vi kommer att lära oss enkla metoder för att använda operatörerna genom att tillämpa små kodområden.

OCH-OCH-funktionen analyserar i princip två bitar och levererar en 1 om de är desamma och en 0 om de är distinkta. Om vi ​​till exempel nämnde 1 OCH 1 är resultatet 1, medan vi skulle förklara 1 OCH 0 skulle konsekvensen vara 0.

Det är självklart att vi också kan utvärdera ord, liksom allt OCH-funktionen åstadkommer att granska de två termerna bit för bit. Exemplet nedan visar att två 8-bitars ord blir ANDed tillsammans med produkten:

11001011
OCH 10110011
Motsvarar 10000011

Jag hoppas att du håller med, resultatet kommer helt enkelt att ha en 1 när 2 1s hand i hand med varandra i ett par ord. Vi kan till exempel använda AND-funktionen för att verifiera portarna.

Om vi ​​kontrollerar några I / O-stift som är kopplade till en krets, och vi bör hålla ett öga på en viss situation där endast ett fåtal av stiften är höga, i så fall kan vi ganska mycket läsa port, varefter OCH resultatet med det tillstånd vi har undersökt, identiskt med förekomsten ovan.

PIC ger oss två ingredienser för AND.
De är ANDLW och ANDWF. ANDLW tillåter oss att utföra en AND-funktion med detaljerna i W-registret och ett belopp som vi anger.

Syntaxen är: ANDLW där är exakt vad vi ska OCH innehållet i W med.

Konsekvensen av OCH-funktionen skulle lagras direkt i W-registret.
ANDWF tillåter oss att utföra en AND-funktion i W-registret och ett annat register, till exempel en PORT. Syntaksen är: ANDWF, d i vilket är det register vi är entusiastiska över, t.ex. PORTA, och d visar PIC där du ska placera resultatet. Om d = 0 placeras resultatet i W-registret och av d = 1 sparas slutresultatet i det register vi angav. De två delarna av koden nedan visar ett bra exempel på varje OCH-funktion.

Initialen undersöker PORTA: s status, där vi måste kontrollera om ingångarna är 1100. Vi kan placera resultatet tillbaka i W-registret

movlw 1100
ANDWF 05h, 0 Den andra illustrationen kan nu verifiera innehållet i W-registret:
ANDLW 1100

ELLER

Vi har nu upptäckt en ELLER-funktion, för att vara exakt XOR. Detta utvecklas till en 1 om två bitar inte är desamma, men är olika. Du kan hitta en annan ELLER-funktion som heter IOR, vilket är den inkluderande ELLER. Denna funktion genererar en 1 om en bit är en 1, men dessutom om varje bit är 1. Nedan finns en tydlig sanningstabell för att illustrera detta:

A B O / P
0 0 0
0 1 1
1 0 1
1 1 1

Vad är aritmetiska operatörer

LÄGG TILL

Denna funktion åstadkommer vad som vanligtvis påstås. Det bidrar med två siffror! Om konsekvensen av att lägga till de två siffrorna överstiger 8 bitar kommer i så fall troligen en CARRY-flagga att ställas in. CARRY-flaggan finns på adressen 03h bit 0.

När denna bit är schemalagd överträffade de två siffrorna 8 bitar. När det är ett 0, ligger i så fall konsekvensen inom 8 bitar. Som tidigare levererar PIC oss två ADD-stilar, specifikt ADDLW och ADDWF. Som du kanske har antagit är det här som funktionen ovan. ADDLW erbjuder innehållet i W-registret enligt vad vi anger. Syntaxen är: ADDLW ADDWF lägg till innehållet i W-registret och något annat register som vi utser.

Syntaxen är: ADDWF, d är var

SUB

Vid den här tiden antar jag att du inte kan anta vad den här funktionen utför! Du misstänkte verkligen det, den här funktionen
subtraherar en bit från en annan. Återigen ger PIC oss två smaker: SUBLW och SUBWF. Syntaxen är precis som för ADD-funktionen, förutom att du uppenbarligen skriver SUB istället för ADD!

Inkrement Om vi ​​vill inkludera 1 till ett nummer i PIC, kan vi absolut använda ADD-funktionen och använda nummer ett. ~ Problemet med detta är att vi först måste placera figuren i W-registret och sedan använda ADDLW 1-kontrollen för att öka den. Om vi ​​ville inkludera 1 i ett register kan det vara värre. Vi måste först placera siffran 1 i W-registret, sedan använda ADDWF, 1. Därför, till exempel, för att inkludera 1 till plats 0C, säg, skulle vi behöva ha följande del av skriptet:

movlw 01
addwf 0c, 1

Det finns en enklare metod för att genomföra detta. Vi kan utöva kommandot INCF. Syntaxen är: INCF, d där, är registret eller platsen som vi berörs av, och d visar PIC där du ska placera resultatet. Om d = 0 ligger resultatet inom W-registret, och i fall d = 1 ställs konsekvensen i det register vi angav.

Genom att använda denna individuella instruktion kan vi faktiskt femtio procent av kodningen. Om vi ​​önskade att resultatet skulle återställas i W-registret, i det fallet där vi använde förekomsten ovan, hade vi kanske behövt inkludera ett extra kommando för att flytta objekten av 0C tillbaka till W-registret, varefter 0C-registret placeras tillbaka oavsett vad det var.

Det finns stegkommando. Det är INCFSZ. Detta kommando kan öka det register som vi anger, men om vi registret är lika med 0 efter inkrementet (som kommer att inträffa medan vi inkluderar 1 till 127) efter det kommer PIC troligen att klara den efterföljande instruktionen. Delen av koden nedan speglar detta:

Loop incfsz 0C
Goto Loop
:
:
Resten av programmet.

I ovanstående del av koden kommer 0C att ökas med 1. Vi äger sedan en instruktion som informerar PIC om att återvända till vår tagg med namnet Loop och öka 0C med 1 igen. Detta fortsätter tills 0C är lika med 127. Under denna omständighet, när vi ökar 0C med 1, kommer 0C nu att matcha 0. Vår INCFSZ-instruktion kan mycket väl informera PIC att utelämna den efterföljande instruktionen, som i detta fall är goto-deklarationen, följaktligen kommer PIC att gå vidare med resten av programmet.

Minskning

Vi har nu diskuterat minskningsfunktionen i tidigare träning, därför kommer jag inte att revidera den längre.

Komplement

Den slutliga instruktionen i denna diskussion skulle vända varje bit i registret som vi anger. Syntaxen är: COMF, d vari

Förstå bitoperationer

Detta kan till exempel användas för att snabbt byta ut stiften på en port från utgång till ingång och så vidare. Bitfunktioner tillåter oss att forma en enda bit i ett uttryck. De tillåter oss att fortsätta, ställa in och bli av med enstaka bitar i register eller nummer som vi anger.

Efter avslutad kurs kommer vi att avslöja ett program som är utformat för att skapa en uppsättning sekvenseringsljus som fortsätter framåt och sedan bakåt. Vi observerade att detta uppnåddes tidigare när vi undersökte den exklusiva ELLER-funktionen, där vi exklusivt ORDade portarna med ett uttryck. Vi har hittills märkt några bitfunktioner när vi etablerar portarna på PIC, och

Låt mig upprepa deras användning här.

BCF

Denna instruktion torkar bort lite som vi anger i ett register som vi utser. Syntaxen
är:
BCF,

Vi använde detta tidigare för att ändra från sida 1 till sida 0 genom att ta bort lite i STATUS-registret. Vi kan också använda den för att fixa lite till 0 i något annat register / plats. Om vi ​​till exempel vill ställa in den tredje biten i 11001101 som sparats i avsnitt 0C till 0, kan vi
Föra in:

BCF 0C, 03

BSF

Denna instruktion skulle fixa varje bit som vi anger till 1 i alla register som vi anger. Vi använde detta tidigare för att gå vidare från sida 0 till sida 1. Syntaxen är: BSF ,, och används i exakt samma metod som BCF ovan.

BTFSC Fram till nu kunde vi ställa in eller rensa lite i ett register. Tänk dig dock om vi i princip behöver kontrollera om en bit är en 1 eller en 0 i ett register?

Visst är det möjligt att använda BTFSC. Det anger bit testregister F och hoppa över om det är klart. Denna instruktion kommer att analysera den bit vi anger i registret. Om biten är 0, skulle instruktionen informera PIC att passera den efterföljande instruktionen.

Vi kan använda den här instruktionen om vi vill kontrollera en flagga, till exempel bärflaggan. Detta sparar oss för att behöva läsa STATUS-registret och söka efter de enskilda bitarna för att lära oss vilka flaggor som är fixerade. 29 Om vi ​​till exempel vill kontrollera om Carry-flaggan var satt till 1 efter att vi hade lagt till två siffror, kunde vi skriva följande:

BTFSC 03h, 0
fortsätt här om den är inställd på 1
eller här om den är inställd på 0

Om bitens status är 1, skulle instruktionen efter BTFSC slutföras. Om den är inställd på 0, hoppas den efterföljande instruktionen. Följande del av koden visar där den kan användas:

Loop:
:
:
BTFSC 03,0
Goto Loop

I ovanstående kod kommer PIC helt enkelt ut ur slingan om bit 0 i STATUS-registret (eller Carry-flaggan) definieras till 0. Annars skulle goto-kommandot genomföras.

BTFSS

Denna instruktion anger bit testregister F och hoppar över om inställd. Detta kan jämföras med BTFSC-instruktionen, förutom att PIC skulle utelämna den efterföljande instruktionen om biten vi har utvärderat är inställd på 1 istället för 0.

CLRF

Denna instruktion skulle fixa hela informationen i ett register till 0. Syntaxen är:

CLRF
Vi använde detta tidigare för att sätta ut portarna till 0 genom att använda CLRF 85h. Vi använde det vidare för att fixa portarna så att alla stift till utmatning inkluderades genom att använda CLRF
05h.

CLRW

Detta kan likna CLRF-instruktionen, förutom att rensa W-registret. Syntaxen är ganska enkelt:

CLRW

RLF och RRF

Dessa riktningar skulle transportera lite i ett register en enskild slits till vänster (RLF) eller höger (RRF) i ett register. Om vi ​​till exempel behövde 00000001 och vi använde RLF, skulle vi i så fall kanske ha 00000010. Vad händer nu om det finns 10000000 och tillämpade RLF-instruktionen? Visst skulle 1 placeras i bärflaggan. Om vi ​​använde RLF-instruktionen en gång till, skulle 1 visas igen i början. Det samma inträffar, dock tvärtom, för RRF-instruktionen. Fallet i punkten nedan visar detta för RLF-instruktionen, där Vi kan se de 8 bitarna i ett register, liksom bärflaggan:

C 87654321
0 00000001
RLF 0 00000010
RLF 0 00000100
RLF 0 00001000
RLF 0 00010000
RLF 0 00100000
RLF 0 01000000
RLF 0 10000000
RLF 1 00000000
RLF 0 00000001

Exempel på program

Vi kommer nu att se en exempelkod som man kan kompilera och köra. Det skulle generera ett sekvenseringsljus som börjar vid PortA bit 0 och går till PortB bit 8 och
sedan återvänder.
Anslut lysdioderna till var och en av portstiften. Vi kommer att ha lite av det
procedurer som påpekas i denna handledning.

TIME EQU 9FH Variabel för fördröjningsslingan.
PORTB EQU 06H Port B-adress.
TRISB EQU 86H Port B Tristate-adress.
PORTA EQU 05H Port A-adress.
TRISA EQU 85H Port A Tristate-adress.
STATUS EQU 03H Sida välj register.
COUNT1 EQU 0CH loopregister.
COUNT2 EQU 0DH loopregister.

BSF STATUS, 5 Gå till sida 1
MOVLW 00H och ställa in
MOVWF TRISB både portarna A och B.
MOVLW 00H för utgång,
MOVWF TRISA återvänder sedan till
BCF STATUS, 5 sida 0.
MOVLW 00H Rensa port A.
MOVWF DÖRR

Start av huvudprogrammet

RUNMOVLW
01H Ställ in den första bitMOVWF
PORTB på Port B.CALL
FÖRDRÖJNING Vänta en stundCALL
DRÖJSMÅL
Flytta biten på Port B till vänster och pausa sedan.RLF
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJ
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJ
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJ
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJ
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJ
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJ
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJ
PORTB, 1 Detta flyttar biten in i bärflaggan
Fortsätt nu till port A och flytta biten åt vänster.RLF
PORTA, 1 Detta flyttar biten från nollflaggan till PortACALL
DELAYCALL DELAYRLF
DÖRR, 1RING
FÖRDRÖJA
FÖRDRÖJ
DÖRR, 1RING
FÖRDRÖJA
FÖRDRÖJ
DÖRR, 1RING
FÖRDRÖJA
DRÖJSMÅL
Flytta tillbaka biten på Port ARRF
DÖRR, 1RING
FÖRDRÖJA
FÖRDRÖJNING
DÖRR, 1RING
FÖRDRÖJA
FÖRDRÖJNING
DÖRR, 1RING
FÖRDRÖJA
FÖRDRÖJNING
PORTA, 1 Detta flyttar biten till nollflaggan. Flytta nu biten
tillbaka på Port BRRF
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJNING
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJNING
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJNING
PORTB, 1CALL
DELAYCALL DELAYRRF
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJNING
PORTB, 1CALL
FÖRDRÖJA
FÖRDRÖJNING
PORTB, 1CALL
FÖRDRÖJA
DELAY Nu är vi tillbaka där vi började, GOTO
KÖR låt oss gå igen.

Det finns ett bra alternativ i träningsuppsättningen som gör att du kan använda en datatabell.

En datatabell är bara en lista över datacitat, där allt ses över baserat på några överväganden.
Du kan till exempel ha en krets som använder en PIC som räknar antalet instanser som en ingångsstift blir hög på 1 sekund. Därefter kan du visa numret på en 7-segmentsdisplay.

Så snart tidpunkten har startat börjar PIC räkna antalet tillfällen stiftet blir högt. Efter 1 sekund besöker den tabellen och tittar upp data, den måste visa numret på displayen som symboliserar mängden situationer som stiftet blev högt. Detta kan vara fördelaktigt eftersom vi inte bestämmer vad siffran kan vara förrän PIC har genomfört sin uppskattning.

Genom att använda en tabell kan vi låta PIC bestämma vilken figur som ska visas. Innan jag fortsätter att visa dig hur datatabellen fungerar kan jag behöva berätta för dig att PIC behåller var den befinner sig i programmet medan den är igång.

Det underlättar för dem som har utfört viss programmering i BASIC. Annars, var inte orolig, du kanske vill fortsätta lära dig mer om teorin. Föreställ dig att det finns ett BASIC-program som liknar det som presenteras nedan:

10 ÅR K = 0
11 K = K + 1
12 OM K> 10 DAN GOTO 20 ELSE GOTO 11
20 UTSKRIFT K
21 SLUT

Programmet börjar vid rad 10. Så snart K är schemalagd till 0, går det vidare till rad 11. När vi har inkluderat 1 till K fortsätter vi sedan till linje 12.

Vid denna tidpunkt kan vi vara nyfiken på om K är högre än 10. Om det är så går vi vidare till rad 20, annars går vi tillbaka till rad 11.

Rad 20 dokumenterar K och rad 21 avslutar programmet. BASIC använder linjestatistik för att hjälpa programmeraren att registrera var problem finns, eftersom etiketter inte är godkända. PIC använder etiketter för att fly mellan destinationer - eller kan det verkligen?

Vi använder etiketterna för att säkerställa att vi är medvetna om var problemen är, samt för att säkerställa att vi kan informera PIC på ett enkelt sätt var vi ska söka.

Precis vad som inträffar är att PIC utnyttjar en inre linjedisk som kallas Program Counter. Programräknarspåret (förkortat till PC) för minnesdestinationen där den aktuella instruktionen är.

När vi informerar PIC för att besöka en vald etikett förstår den minnesplatsen och förstärker därför datorn tills den ser den minnesdestinationen. Detta är exakt samma metod som vi tittar på BASIC-programmet ovan. Nedan följer ett kodsegment med minnesutrymmena eller objekten på datorn, bredvid varje instruktion:

PC-instruktion0000 movlw 03
0001 movwf 0C
0002 Loop decfsc 0C
0003 goto Loop
0004 slut

I demonstrationen ovan har vi fixat PC: n till 0000. På denna har vi instruktionen movlw 03. När PIC har implementerat dessa data ökar den PC: n för att den efterföljande instruktionen ska genomsökas. Vid denna tidpunkt ser PIC movwf 0C. Datorn ökas ännu en gång.

Nu studerar PIC decfsc 0C. Om detaljerna för 0C inte är 0, i så fall ökas PC: n med 1, liksom följande instruktion, goto Loop, informerar PC: n om att återgå till position 0003, där det finns nämnda loop. Om 0C-detaljerna är 0, rekommenderas PC: n att öka med 2, helt enkelt utelämna den efterföljande instruktionen.

Förstå datatabeller

Detta placerar PC: n vid position 0004, där programmet avslutas. Destinationerna fastställs av monteraren, och vi borde i allmänhet inte vara oroliga för vad datorn gör. Fram till finner vi behovet av att ta det under kontroll precis som när vi använder datatabeller. Det enklaste sättet att beskriva hur en datatabell fungerar är att börja med en illustration.

PC ekv 02
movlw 03
samtalstabell
:
tabell addwf PC
igen 01
åter 02
bakåt 03
bakåt 04
bakåt 05
bakåt 06
bakåt 07
lämna tillbaka

Den första instruktionen tilldelar etiketten PC med adressen till programräknaren (02h). Vi kommer snart efter att ha lagt värdet 03h i w-registret. Vi kommunicerar därefter till bordet. Den främsta raden i underrutintabellen förstärker detaljerna i W-registret (03h) till programräknaren.

Detta utlöser programräknaren för att höja med 3, eller för att uttrycka det på ett annat sätt, stimulerar programräknaren att fortsätta nedåt 3 rader. Medan räknaren anländer tre rader nedåt känner PIC igen instruktionen på nytt. Detta kommando skickar värdet som följer det till W-registret, varefter det kommer tillbaka från underrutinen. RETLW betyder i grunden Return, Literal till W.

Se jag lade ett komma efter ordet Return. Eftersom vi befinner oss i en subrutin behöver vi en returinstruktion för att ytan av den. Därför RET i instruktionen. Efter RETLW-instruktionen är ett nummer, och det är precis vad som läggs i W-registret.

I det här fallet är det figur 3. Vi kan ange vilken kvantitet som helst i W-registret, så länge som denna figur kombineras med Programräknaren i tabellens underrutin, kommer vi att upptäcka en instruktion om att återvända. I ovanstående illustration innebär detta att vi kan ha valfritt nummer från 1 till 7. Om vi ​​går förbi underrutinen kan vi kanske slutföra en ytterligare del av programmet. Av denna anledning är det vanligtvis ett smart drag att placera datatabellen exakt mot slutet av PIC-programmet, så om vi i så fall överskjuter i det fallet kommer vi ändå att avsluta programmet.

Ämnet avbrott kan mycket väl bli det längsta och tuffaste att gå igenom.

Du kan inte hitta någon okomplicerad metod för att specificera avbrott, men med lite tur mot slutet av denna del kan du kanske använda avbrott i dina egna program.
Vi har delat in sektionen i två steg. Det är för att göra det möjligt att separera ämnet i avsnitt, också för att ge dig en praktisk plit up för enkel förståelse.

Vad exakt är ett avbrott? Visst, som termen indikerar, är ett avbrott en teknik eller en signal som förhindrar en mikroprocessor / mikrokontroller från vilken sak som helst att den utför att något annat kan hända.

Tillåt mig att ge dig en daglig illustration. Tror att du kopplar av i ditt eget hem och pratar med en annan person. Plötsligt låter telefonen.

Du slutar prata och tar tag i telefonen för att prata med den som ringer. När du väl har haft din telefoninteraktion bestämmer du dig för att återvända till att prata med individen innan telefonen ringde. Det är möjligt att överväga den viktigaste rutinen medan du chattar med någon, telefonen ringer för att störa din konversation, och pausen i rutinen är metoden för att prata i telefon.

Medan telefondiskussionen avslutas, går du tillbaka till din primära chattrutin. Denna illustration är precis hur en avbryter en processor för att vidta åtgärder.

Det primära programmet är igång och utför viss funktion i en krets, men när ett avbrott äger rum avbryts det primära programmet medan en annan rutin utförs. rutin slutar, flyttar processorn tillbaka till den primära rutinen precis som tidigare.

Förstå avbrott

PIC har fyra avbrottskällor. De kunde delas upp i ett par grupper. Två är avbrottskällor som kan användas utåt till PIC, medan de andra två är inre processer. Låt mig klargöra de två externa typerna här. De andra två kommer att beskrivas i olika handledning när vi kommer fram till timers och lagrar data.

Om du kollar ut pin-out på PIC, kommer du att märka att pin 6 det är RB0 / INT. Vid denna punkt är RB0 helt klart Port B-bit 0. INT representerar att den lika gärna kan konfigureras som en extern avbrottsstift. Vidare kan port B-stift 4 till 7 (stift 10 till 13) också användas för avbrott. Innan vi kan använda INT eller andra Port B-stift måste vi utföra två uppgifter. Först måste vi informera PIC om att vi kommer att använda avbrott.

Därefter måste vi ange vilken port B-stift vi ska använda som ett avbrott snarare än som en I / O-stift. Inuti PIC kan du hitta ett register som kallas INTCON och finns på adressen 0Bh. I detta register kommer du att upptäcka åtta bitar som kan aktiveras eller inaktiveras. Bit 7 i INTCON är känd som GIE. Detta är Global Interrngupt Enable. Att fixa detta till 1 informerar PIC om att vi kommer att använda ett avbrott.

Bit 4 i INTCON kallas INTE, INTerrupt Enable. Att sätta denna bit till 1 förmedlar till PIC att RB0 kommer att bli en avbrottsstift. Konfigurera bit 3, kallad RBIE, informerar PIc om att vi kommer att använda Port B-bitar 4 till 7. Vid denna punkt förstår PIC när denna pin kan vara hög eller låg, måste stoppa vad den utför och fortsätta med ett avbrott rutin. Vid denna tidpunkt måste vi informera PIC huruvida avbrottet sannolikt kommer att vara på den stigande kanten (0V till + 5V) eller fallkanten (+ 5V till 0V) omvandlingen av signalen.

Enkelt uttryckt, vill vi att PIC ska avbryta varje gång signalen rör sig från låg till hög eller från hög till låg. Genom brottslighet kan detta fastställas för att placeras på den stigande kanten.

Kantutlösaren är schemalagd i ett ytterligare register som heter OPTION-registret, vid adress 81h. Biten vi är entusiastiska över är bit 6, ofta kallad INTEDG.

Om du ställer in detta på 1 aktiveras PIC-störningen vid monteringskanten (standardläge) och inställningen till 0 stimulerar PIC att störas på glidkanten. Om du vill att PIC ska aktiveras på den stigande kanten, behöver du verkligen inte göra något åt ​​den här biten.

Tyvärr är Option-registret tyvärr i Bank 1, vilket innebär att vi tycker om att ändra från bank 0 till bank 1, ställa in biten i Option-registret, efter att återvända till bank 0. Nyckeln här är att utföra varje bit av Bank 1 registreras i en enda strejk, till exempel upprättande av hamnstift, efter det att du återvänder till Bank 0 om du är klar.

Bra, följaktligen har vi meddelat PIC vilken pin som troligen kommer att vara avbrottet, och var kanten ska utlösas, vad händer i programmet och PIC närhelst avbrottet inträffar? Ett par saker äger rum. Allra första är en 'flagga' schemalagd.

Detta informerar PIC: s interna processor om att ett avbrott har inträffat. Därefter tipsar programräknaren (som jag pratade om i föregående handledning) till en specifik adress inom PIC. Låt oss snabbt kolla in alla dessa individuellt. Interrupt Flag I vårt INTCON-register är bit 1 interrupt-flaggan, kallad INTF. Vid denna tidpunkt, närhelst något avbrott uppstår, kommer denna flagga sannolikt att vara fixerad till 1.

När det inte finns något avbrott placeras flaggan till 0. Såväl som det är nästan alla prestationer. Vid den här tiden kanske du funderar på ”vad är poängen?” Trots att denna flagga är planerad till 1, kan PIC inte och kommer inte att reagera på en annan avbrott. Låt oss därför uttrycka att vi åstadkommer ett avbrott. Flaggan kommer sannolikt att vara fixerad till 1, och PIC kan gå till vår rutin för att arbeta avbrottet.

När den här flaggan inte var fixerad till 1 och PIC fick fortsätta att svara på avbrottet, kan kontinuerlig pulsering av stiftet hålla PIC tillbaka till början av vår avbrottsrutin och på intet sätt slutföra den. När jag återvänder till min illustration av telefonen, liknar det att lyfta telefonen, och omedelbart när du fortsätter att diskutera börjar den ringa igen eftersom en annan person vill prata med dig.

Det är tillrådligt att slutföra en dialog och sedan ta tag i telefonen igen för att prata med nästa person. Du kan hitta ett litet problem med den här flaggan. Även om PIC snabbt sätter denna flagga till 1 sätter den inte igen 0! Den aktiviteten måste utövas av programmeraren - dvs du. Detta kan enkelt uppnås, eftersom jag är säker på att jag antar och måste uppnås efter att PIC har genomfört avbrottsrutinen.

Minnesplats Varje gång du startar PIC: n, eller om det finns en återställning, tipsar programräknaren för att adressera 0000h, vilket kan vara omedelbart i början av programminnet. Men i händelse av avbrott skulle programräknaren ange adress 0004h.

Därför, medan vi komponerar vårt program som kommer att ha avbrott, måste vi först informera PIC att hoppa över adress 0004h och behålla avbrottsrutinen som börjar vid adress 0004h diskret från resten av programmet.

Detta kan vara problemfritt att utföra. Inledningsvis börjar vi vårt program med ett kommando som kallas ORG. Detta kommando indikerar Ursprung eller start. Vi håller fast vid det med en adress. Eftersom PIC börjar vid adress 0000h skriver vi ORG 0000h. Därefter måste vi kringgå adress 0004h. Vi åstadkommer detta genom att sätta en GOTO-instruktion tillsammans med en etikett som ger tips till vårt primära program.

Vi följer sedan detta GOTO-kommando med ytterligare en ORG, detta ögonblick med adressen 0004h. Efter detta kommando infogar vi vår avbrottsrutin. Vid denna punkt kan vi eventuellt skriva in vår avbrottsrutin direkt efter det andra ORG-kommandot, eller så kan vi placera ett GOTO-uttalande som pekar på avbrottsrutinen.

Det är verkligen relaterat till alternativ från din sida. För att informera den PIC som den erbjuder anlände till avslutningen av avbrottsrutinen måste vi placera kommandot RTFIE mot slutet av rutinen. Detta kommando betyder återkomst från avbrottsrutinen. Medan PIC märker detta indikerar programräknaren till den slutliga position PIC var vid innan avbrottet inträffade. Vi har upprättat nedan en kort kodsektion för att visa ovanstående:

Det finns ett par saker du bör informeras om när du använder avbrott. Initialen tenderar att vara att om du kanske använder samma register i ditt primära program och avbrottsrutinen, kom ihåg att detaljerna i registret sannolikt kommer att förändras när avbrottet äger rum.

Låt oss till exempel använda w-registret för att vidarebefordra data till Port A primärt program, därför kan du dessutom använda w-registret i avbrottsrutinen för att flytta data från en destination till en annan.

Om du inte är försiktig skulle w-registret innehålla det sista värdet det fick medan det hade varit i avbrottsrutinen, så när du återvänder från avbrottet kommer denna information att levereras till Port A snarare än det värde du hade tidigare avbrottet inträffade.

Medlet kring detta är att tillfälligt spara detaljerna i w-registret innan du använder det igen i avbrottsrutinen. Det andra är det faktum att du kan hitta en fördröjning mellan när en avbrott äger rum och när den efterföljande kan uppstå. Medan du förstår har PIC en yttre klocka, som möjligen kan vara en kristall eller det kan vara en motståndskondensatorkombination.

Oavsett vilken klockfrekvens, PIC delar den med 4 varefter den använder detta för sin inre timing. Till exempel om du har en 4MHz kristall kopplad till din PIC, skulle PIC i så fall utföra instruktionerna vid 1MHz. Denna inre timing är känd som en instruktionscykel. Vid denna tidpunkt hävdar databladet (utan tvekan i mindre utskrift) att du måste aktivera 3 till 4 instruktionsomgångar mellan avbrott.

Min skulle vara att aktivera fyra omgångar. Anledningen till förseningen är att PIC kräver tid att hoppa till avbrottsadressen, flaggan och komma tillbaka från avbrottsrutinen. Håll därför detta i åtanke om du arbetar med en alternativ krets för att aktivera ett avbrott för PIC.

Vid denna tidpunkt är en punkt till det faktum att om du använder bitar 4 till 7 i Port B som ett avbrott. Du kan inte välja specifika stift på port B för att fungera som ett avbrott.

Därför, om du tillåter dessa stift, kan de troligen vara alla tillgängliga. Därför kan du till exempel inte bara ha bitar 4 och 5 - bitar 6 och 7 kommer sannolikt att bemyndigas samtidigt. Vad är syftet med att få fyra bitar att representera ett avbrott? Visst kan du ha en krets ansluten till PIC, om någon av fyra rader går högt, i så fall kan detta vara ett problem som du kräver att PIC direkt påverkar.

En illustration av detta kan vara ett hemlarm, där fyra sensorer är kopplade till port B-stiften 4 till 7. Vilken specifik sensor som helst kan be PIC att utlösa ett larm, och larmsignaleringsrutinen är avbrottsrutinen. Detta reservdelar kontrollerar portarna ständigt och tillåter PIC att fortsätta med olika frågor. Under nästa handledning ska vi komponera ett program för att hantera ett avbrott.

Vi behandlade en hel del grunder under den senaste handledningen, därför känner jag att det är dags att vi komponerade vårt första program.

Programmet vi kommer att skriva skulle räkna antalet tillfällen vi slår på en strömbrytare och sedan visa upp numret.

Programmet skulle räknas från 0 till 9, kan visas på 4 lysdioder i binär form, tillsammans med ingången eller avbrottet kommer sannolikt att vara på RB0.

Det viktigaste vi måste göra är att informera PIC att hoppa över adressen där programräknaren pekar på när ett avbrott äger rum.

Du kommer att observera att vi använder en unik metod för att visa hexadecimala tal. Innan jag hände, använd F9h där h indikerade hexadecimalt. Vi kan skriva detta som 0xF9, vilket är den struktur vi ska använda från och med nu.

Nu måste vi berätta för PIC att vi ska använda avbrott, och vi använder RB0-stift 6 som en avbrottsstift:

bsf INTCON, 7GIE - Global avbrytningsaktivering (1 = aktivera)
bsf INTCON, 4INTE - RB0 avbrottsaktivering (1 = aktivera)
Jag ska rensa avbrottsflaggan för alla fall (jag litar aldrig på någonting!)
bcf INTCON, 1INTF - Rensa flaggbit i fallet

För närvarande måste vi etablera våra två hamnar. Tänk på att eftersom vi nu använder RB0 som en avbrottsstift måste detta fastställas som en ingång:

Vi ska använda en variabel som heter COUNT för att lagra antalet switchantal. Vi kan helt enkelt öka värdet på Port A, men du kommer att se varför jag använder en variabel när vi skriver vår avbrottsrutin.

Därför är vårt huvudprogram sammansatt, och vid denna tidpunkt måste vi informera PIC hur man ska fortsätta när ett avbrott äger rum. Inom detta exempel kommer troligen vårt avbrott att vara omkopplaren. Precis vad vi vill att PIC: n ska vara en till det justerbara COUNT varje gång omkopplaren är begränsad.

Ändå vill vi bara visa hur många tillfällen strömbrytaren stängs från 0 till 9. Ovan sa jag att vi kanske kunde ha helt enkelt ökat värdet på Port A varje gång det är ett avbrott. Port A har dock 5 bitar, om vi helt enkelt ökade porten kommer vi att ha det högsta antalet 31. Det finns ett par förklaringar till varför jag valde att inte flytta upp till 31.

Inledningsvis kommer vi att använda en 7-segment skärm, som högst bara kan gå från 0 till 15 (0 till F i hex). Därefter vill jag dessutom visa dig några av de aritmetiska kommandona som du snubblat på under de senaste lektionerna.

Därför kommer vi att fortsätta med vår avbrottsrutin. För närvarande är det första vi måste åstadkomma att kort lagra detaljerna i vårt w-register, eftersom vi har använt detta för att flytta innehållet i COUNT till PORTA. Om vi ​​inte sparar det kan vi i så fall leverera ett helt annat nummer på grund av vår aritmetik. Låt oss därför åstadkomma det först:

Vid denna tidpunkt förstår vi om värdet på COUNT är 9 eller mer. Precis vad vi behöver åstadkomma nu är om COUNT är mer än 9, placerar den tillbaka till 0 eller annars återgår till huvudprogrammet för att säkerställa att vi kan leverera det till Port A. BTFSS-kommandot eftersom du förstår skulle det följande
instruktion om bärflaggan är schemalagd dvs COUNT = 10:

Det enda som återstår att göra nu är att gå in kollektivt samt bestämma värden för våra konstanter, som vi kan utföra redan i början av vårt program.

Varje gång du aktiverar omkopplaren kommer lysdioderna att räknas upp i binär från 0000 till 1010 och sedan tillbaka till 0000.

Följande bild visar kretsschemat som är kompatibelt med ovanstående förklarade kod. Intressant kommer du att upptäcka att tidskondensatorn har inkluderats i designen. Detta är en trevlig liten knep genom vilken du får friheten att undvika att kondensatorn inkluderas om du inte har någon med dig under den tiden.

Här kommer kapacitansen till spel via den avvikande kapacitansen över oscillatorstiftet och marken.
Naturligtvis verkar det kanske inte vara ett mycket intelligent sätt att undvika en kondensator praktiskt taget eftersom det lösa värdet kan variera med olika givna förhållanden.

Ett annat avsnitt som kan bevittnas i kretsen är det fördömande nätverket över omkopplaren. Detta förhindrar störningar vid mekanisk omkoppling och förhindrar att PIC blir förvirrad om omkopplingen var en enda växling eller flera växlar.




Tidigare: Programmerbar dubbelriktad motortimerkrets Nästa: Hur Buck-Boost-kretsar fungerar