PIC-veiledning - fra registre til avbrudd

Prøv Instrumentet Vårt For Å Eliminere Problemer





Før du går inn i detaljene i PIC-programmering, ville det være viktig å lære noen gode programmeringsmetoder.

Forståelse av registre

Til å begynne med antar du at du skriver inn et (semikolon) når som helst i programmet, at alt som kommer etter dette semikolonet blir ignorert av kompilatoren, til selvfølgelig vognen kommer tilbake i posisjon.



Funksjonen ovenfor lar oss legge til kommentarer eller bemerkninger slik at de ikke blir en del av programmet, men likevel gjør det mulig for oss å identifisere programmet ved hjelp av kommentarene ved siden av. Å sette kommentarer er en anbefalt praksis mens du programmerer hvilken som helst IC.

Den neste viktige tingen i kurset er å tildele navn til de forskjellige konstantene (du vil lære dem senere forseggjort). Dette gjør det enklere å forstå hva som blir skrevet til, eller angående de involverte verdiene, i stedet for å bli forvirret med de inkluderte tallene.



Ovennevnte må gjøres i form av faktiske navn for øyeblikkelig gjenkjenning, for eksempel COUNT. Det ville være viktig å merke seg at her brukes alle store bokstaver for å gjøre det tydelig og indikerer også at det er en konstant verdi.


Som vi kan se, er det ovennevnte gjort i form av en boks laget av semikolon, dette gjør at den bare ser renere ut. I tillegg kan du prøve å dokumentere programmet på papir også. Denne øvelsen vil hjelpe deg å forstå ting på en trinnvis måte.

2. Registerene.

Registret i en PIC er et område som godtar skriftlige detaljer og tillater lesing fra det. Du kan sammenligne det med et ark der du kan visualisere innholdet og også legge til ved å skrive over det.

Figuren nedenfor viser et typisk registerfilkart innebygd i en PIC16F84. Formatet er ikke noe som faktisk er satt inne i PIC, det er ganske enkelt for å indikere hvordan bitene kan ordnes inne i brikken og for å forstå noen av de involverte kommandoene.

Du kan se at det i utgangspunktet er delt inn i Bank 0 og Bank 1. Bank 1 er ansvarlig for å kontrollere den faktiske driften av PIC, for eksempel tlf PIC hvilke biter i Port A som er tildelt som innganger og hvilke som utganger.

Bank 2 er bare for å manipulere informasjonen.

La oss forstå dette gjennom følgende eksempel:

Anta at vi ønsker å tildele en bit på PortA high. For dette må vi først gå til Bank 1 for å sette den spesifiserte biten eller pinnen i Port A i form av en utgang. Etter dette returnerer vi til Bank 0 og leverer en logikk 1 (bit 1) til den spesifikke pinnen.

De vanligste registrene som vi ønsker å bruke i Bank 1 er STATUS, TRISA og TRISB.

STATUS hjelper oss å gå tilbake til Bank 0, TRISA tillater oss å velge hvilke pinner på port A som er utganger og hvilke som kan være innganger, mens TRISB gjør det mulig å velge mellom utgang og inngangspinne ved port B. SELECT-registeret i BANK 0 tillater brukeren å bla til Bank 1.

La oss oppsummere hele konseptet med følgende beskrivelse:

STATUS:

For å bytte fra Bank 0 til Bank 1 kommanderer vi STATUS-registeret. Dette implementeres ved å sette bit # 5 i STATUS-registeret til 1. For å returnere tilbake til Bank 0, tildeler vi bit 5 i STATUS-registeret til 0. STATUS-registeret er plassert på adresse 03h, her betyr h tat tallet kan være i heksadesimal.

TRISA og TRISB:

Disse ligger på adresse 85h og 86h tilsvarende. For å programmere en pin som en utgang eller en inngang, leverer vi bare en null eller en til den bestemte biten i registeret. Nå kan dette gjøres på to måter, via binær eller Hex. I tilfelle man ikke klarer å konvertere parameteren, kan han eller hun gå for en vitenskapelig kalkulator for å implementere verdiene.

Nå har vi 5 pinner ved port A, som tilsvarer 5 pinner. Hvis vi har tenkt å fikse en av pinnene som innganger, leverer vi en '1' til den bestemte biten.

I tilfelle vi ønsket å tilordne en av pinnene som utganger, ville vi sette den spesifikke pinnen til '0'. Bitene er hjelpemiddel ned nøyaktig tilsvarende bitene, eller mer presis bit 0 er RA0, bit 1 vil være RA1, bit 2 = RA2 og så videre. La oss forstå det på denne måten:

Anta at du ønsker å fikse RA0, RA3 og RA4 som utganger, mens RA1 / RA2 som i / ps, vil du gjøre dette ved å sende 00110 (06h). Sjekk at bit 0 er mot høyre som angitt her:

Port A Pin RA4 RA3 RA2 RA1 RA0

Bitnummer 4 3 2 1 0

Binær 0 0 1 1 0

Det samme gjelder TRISB.

PORTA og PORTB

For å levere en av utgangsstiftene høyt, tilbyr vi bare en '1' til respektive bit i vårt PORTA- eller PORTB-register. En identisk prosedyre kan også følges for TRISA- og TRISB-registre. Før vi går inn i vårt første eksempelkoding, la oss bare forstå en kupé med flere registre, nemlig w og f.

W og F

W-registeret er et vanlig register som lar deg tilordne hvilken som helst verdi du ønsker. Så snart du tilordner en størrelse til W, kan du fortsette med å legge dette til en annen verdi eller bare flytte den. Med en annen verdi tildelt blir detaljene bare overskrevet på W.

F-registeret videresender sin skriftlige sak til et register. Vi vil kreve at dette F-registeret tilordner en verdi over et register, kan være over STATUS- eller TRISA-registerene, da disse ikke tillater oss å legge verdiene direkte over dem. Et eksempel på program

La oss undersøke følgende eksempelkode som viser oss hvordan instruksjonen ovenfor implementeres og også vil være vitne til noen av instruksjonene i løpet.

La oss begynne med å fikse port A som diskutert ovenfor.

For dette må vi skifte fra Bank 0 til Bank1, dette gjøres ved å sette opp STATUS-registeret som ligger på adresse 03h, bit 5 til 1.

BSF 03h, 5

BSF betyr bitsett F. Vi bruker to tall etter denne instruksjonen - 03h, som er STATUS-registeradressen, og tallet 5 som tilsvarer bitnummeret.

Så det vi sier er “Sett bit 5 i adresse 03h til 1”.

Vi er nå i Bank 1.

MOVLW 00110b

Vi setter den binære verdien 00110 (bokstaven b betyr at tallet er i binær) i vårt generelle register W. Jeg kunne selvfølgelig ha gjort dette i hex, i så fall ville vår instruksjon være:

MOVLW 06h

Enten fungerer. MOVLW betyr 'Move Literal Value Into W', som på engelsk betyr å sette verdien som følger direkte inn i W-registeret.

Nå må vi sette denne verdien i TRISA-registeret vårt for å sette opp porten:

MOVWF 85h

Denne instruksjonen indikerer 'Flytt innholdet av W til registeradressen som følger', i dette tilfellet refererer adressen til TRISA.

TRISA-registeret vårt på dette punktet bærer figuren 00110, eller presenteres grafisk:

Port A Pin RA4 RA3 RA2 RA1 RA0

Binær 0 0 1 1 0

Inngang / utgang O O I I O

Så nå har vi Port A-pinnene, vi må tilbake til Bank 0 for å justere en av informasjonen.

BCF 03h, 5

Denne instruksjonen oppnår omvendt av BSF. Det innebærer 'Bit Clear F'. Et tallpar som tilsvarer er adressen til registeret, her STATUS-registeret, så vel som bitfiguren, i dette tilfellet bit fem. Hva vi akkurat har fullført for øyeblikket er, definert bit fem på vår

STATUS registrer deg til 0

Vi har nå kommet tilbake i bank 0.
Følgende er koden alt i en blokk:

BSF 03h, 5 Gå til Bank 1
MOVLW 06h Sett 00110 i W
MOVWF 85h Flytt 00110 inn på TRISA
BCF 03h, 5 Kom tilbake til Bank 0

I løpet av den siste instruksjonen, bekreftet vi deg måten å etablere IO-portpinnene på PIC for å være mulig inn- eller utgang.

Gjennom dette kurset, la meg hjelpe deg med å sende data til portene.

Sende data til porter

I den påfølgende opplæringen skal vi fullføre ved å blinke en LED på og av som består av en fullstendig programdetaljering og et greit kretsdiagram slik at du kan se PIC utføre akkurat det vi forventer.

Ikke prøv å sette sammen og programmere PIC-en din med resultatene nedenfor, siden de bare er illustrasjoner. Opprinnelig vil vi etablere Port A bit 2 som en utgang:

Dette kan gjenkjennes fra forrige instruksjon. Det eneste skillet kan være at vi har fikset hver bit av pinnene på A som utgang, ved å levere 0h til tri-state-registeret. Så det han nå må gjøre er å slå på en LED.

Vi oppnår dette ved å planlegge en av pinnene (den med LED-en koblet til den) høy. For å si det annerledes, bruker vi en ‘1’ på pinnen. Dette er nøyaktig nøyaktig hvordan det utføres (observer kommentarene for en avklaring for hver linje):

Derfor, det vi nå har oppnådd, er å slå lysdioden på og av en gang. Det vi ønsker er at LED-lampen slås på kontinuerlig.

Vi oppnår dette ved å skaffe oss programmet for å gå tilbake til starten. Vi oppnår dette ved å først etablere en tag i begynnelsen av programmet vårt, og deretter informere programmet om å gå videre dit. Vi spesifiserer en tag ganske enkelt.

Vi skriver inn et begrep, si START, skriv inn koden:

Som vist, nevnte vi opprinnelig uttrykket ‘Start’ umiddelbart i begynnelsen av programmet.

Neste, helt på slutten av programmet, nevnte vi tydelig ‘goto Start’. Instruksjonen 'goto' utfører akkurat det den erklærer.

Dette programmet vil kontinuerlig slå lysdioden på og av når vi slår på kretsen, og har en tendens til å slå seg AV når vi fjerner strøm. Kanskje vi burde sjekke programmet vårt igjen:

Vi har helt sikkert utelatt kommentarene, men vi kan fortsatt følge instruksjonene og tallene.

Dette kan være litt forvirrende senere hvis du prøver å feilsøke programmet og mens du skriver koden, husker du alle adressene.

Selv om kommentarene kan plasseres fremdeles, kan det bli litt rotete. Dette vil kreve navn på tallene og kan oppnås med en ekstra instruksjon: 'equ' Instruksjonen 'equ' antyder at noen ting kan være lik en annen ting.

Det kan ikke være en instruksjon for PIC, heller for montøren. Denne instruksjonen gjør det lettere å tilordne navn til en registeradresseplassering eller en konstant til en programmeringsperiode.

Vi vil etablere noen konstanter for programmet vårt og også være vitne til hvor mye rett det leser programmet.

Siden nå har vi fikset de konstante verdiene vi kan fortsette ved å sette dem opp i vårt program. De konstante verdiene må angis før du bruker dem.

Sørg derfor for å alltid plassere dem i begynnelsen av programmet. Vi vil omskrive programmet med unntak av kommentarene igjen, for å sammenligne den tidligere merkingen med den siste.

Det kan hende du er i stand til å legge merke til at konstantene muliggjør litt lettere forståelse av programmet, men vi er fremdeles uten kommentarene, men ingen bekymringer, siden vi ennå ikke er ferdige.

Det kan være en mindre ulempe med vårt blinkende LED-program.
Hver instruksjon trenger en klokkesekvens for å fullføre. I tilfelle vi bruker en 4MHz krystall, krever hver instruksjon 1 / 4MHz eller 1uS for å fullføre.

Siden vi bare har brukt fem instruksjoner, vil LED-lampen aktiveres og deretter slukkes i 5uS. Dette kan være for raskt for folk å legge merke til, i tillegg vil det virke som om LED-lampen er helt på.

Det vi i stedet bør oppnå, er å produsere en hemming mellom å slå på LED-en og å slå av LED-en. Teorien om inhiberingen er at vi teller ned fra en tidligere mengde, så når den blir null, slutter vi å telle.

Nullverdien betyr avslutningen på forsinkelsen, og vi fortsetter å jobbe prosessen vår gjennom hele programmet. Derfor er det første vi må gjøre å bestemme en konstant å bruke som vår teller.

La oss betegne dette konstante ANTALET. Etter det må vi bestemme hvor viktig et tall å begynne å telle fra. Sikkert, den største figuren vi kan inkludere er 255, eller FFh i heks., Som jeg snakket om i den tidligere opplæringen, tilordner equ-instruksjonen et uttrykk til en registersituasjon.

Dette innebærer at uansett hvilken mengde vi tildeler TELLEN vår, vil den matche elementene i et register. I tilfelle vi prøver å betegne verdien FFh, kommer vi til å få en feil når vi først har satt sammen programmet.

Årsaken til stedet FFh er, derfor kan vi ikke få tilgang til det. Derfor, hvordan må vi utpeke et ekte nummer? Gjerne, det vil kreve en liten mengde sideveis grubling.

Hvis vi for eksempel betegner TELLINGEN vår til adressen 08h, vil dette indikere en grunnleggende målregistreringsdestinasjon. Som standard er de urørte områdene satt til FFh. Følgelig, hvis COUNT fører til 08h, vil du støte på verdien av FFh mens vi først slår på. Likevel, jeg deg, hvordan kan vi fikse COUNT til et annet nummer ?, alt vi bruker er å 'flytte' en verdivurdering til dette målet først.

Som en illustrasjon, antar at vi ønsket at COUNT skulle ha en verdi på 85h, kan vi ikke nevne COUNT equ 85h, siden det er posisjonen til vårt Tri-State-register for Port A. Nøyaktig hva vi oppnår er følgende: movlw 85hFirst put verdien av 85h i W-registeret movwf 08h

Flytt det nå til vårt 08h-register. I tilfelle vi uttrykker COUNT ekv 08h, vil COUNT deretter matche verdien 85h. Delikat, er det ikke! Derfor bestemmer vi først vår konstant: COUNT equ 08h Følgende må vi redusere dette COUNT med en til den blir null.

Det hender rett og slett at det eksisterer en instruksjon som er utformet for å oppnå dette for oss, ved å bruke en 'goto' og en tag.

Instruksjonen vi skal bruke er: DECFSZ COUNT, 1 Denne instruksjonen sier ‘Decrement the register (here it's COUNT) by the number that track the komma. Hvis vi oppnår null, kan du hoppe to plasser foran oss. ’La oss finne det i aksjon først, før vi legger det inn i kurset vårt.

Det vi har utført, er først å etablere vårt konstante TELL til 255. Det etterfølgende segmentet plasserer en tag, kalt LABEL nær vår decfsz-instruksjon.

Decfsz COUNT, 1 reduserer verdien på COUNT med en, og beholder sluttresultatet rett inn i COUNT. Videre verifiserer det å sjekke om COUNT har verdien 0.

Hvis den ikke gjør det, utløser det i så fall programmet til å skifte til den påfølgende linjen. Nå har vi en 'goto' erklæring som gir oss tilbake til vår decfsz instruksjon.

I tilfelle verdien av COUNT utfører det samme, resulterer decfsz-instruksjonen i at programmet vårt hopper to plasser foran, og sendes dit vi har hevdet ‘Fortsett her’.

Derfor, siden du kan observere, har vi fått programmet til å sitte på ett sted i en forutbestemt tid før du fortsetter. Dette kan kalles en forsinkelsessløyfe.

Forstå forsinkelsessløyfer

I tilfelle vi trenger en større forsinkelse, kan vi forfølge den ene løkken etter den neste. De ekstra løkkene, jo utvidet forsinkelsen. La oss minst to, forutsatt at vi vil observere LED-blitsen. Vi vil plassere disse forsinkelsessløyfene i vårt program, og oppnå ved å gjøre det til et ekte program ved å introdusere kommentarer:

Det er mulig å kompilere dette programmet etter hvilket program PIC. Sørg åpenbart for at du prøver kretsen for å sjekke om den virkelig fungerer. Følgende er et kretsskjema som du bør konstruere så snart du har programmert PIC.


Vel gjort, du kunne faktisk ha komponert ditt første PIC-program, samt konstruert en krets for å blinke en LED på og av. Inntil nå, i tilfelle du har fulgt disse kursene, har du kanskje lært totalt syv instruksjoner av 35, men uten tvil så langt kan du kontrollere I / O-portene!

Vil du prøve å endre forsinkelsessløyfene for å gjøre LED-blitsen raskere - hva synes den minimale verdien av COUNT for å se LED-blitsen? Eller kanskje du vil inkludere en tredje eller supplerende forsinkelsessløyfe etter den første for å stabilisere LED-en. en unik konstant for hver forsinkelsessløyfe.

Du kan potensielt faktisk fikle med forsinkelsessløyfene dine for å gjengi LED-blitsen med en bestemt hastighet, for eksempel etter et sekund. La oss i neste instruksjon se hvordan vi er i stand til å bruke noe kjent som en subrutine for å opprettholde programmet kompakt og grunnleggende. En subrutine er en integrert del av koden eller programmet, som kan bli referert til og når du trenger det. Underrutiner brukes i tilfeller der du ofte utfører den samme funksjonen.

Hva er underrutiner

Fordelene med å bruke en subrutine er at det sannsynligvis vil være enklere å endre verdien en gang i en subrutine i stedet for for eksempel ti ganger gjennom hele programmet ditt, i tillegg til at det i stor grad bidrar til å redusere nivået av minne programmet bruker inne i PIC. Vi vil sjekke ut en underrutine:

I utgangspunktet må vi gi vår underrutine en betegnelse, og i denne situasjonen har vi valgt RUTINE. Vi skriver inn koden som vi ønsker å utføre som normalt. Derfor har vi valgt forsinkelsen i vårt blinkende ledede program. Til slutt avslutter vi underrutinen ved å taste RETURN-instruksjonen.

For å starte subrutinen hvor som helst i programmet vårt, skriver vi raskt instruksjonen CALL og deretter subrutinen.

Vi vil vurdere dette litt mer dypt. Når vi kommer til delen av programmet vårt som CALL xxx, der xxx er navnet på underrutinen vår, hopper programmet til hvor som helst subrutinen xxx er installert. Instruksjonene inne i underrutinen blir utført.

Hver gang instruksjonen RETURN er fullført, hopper programmet tilbake til vårt hovedprogram til instruksjonen etter vår CALL xxx-instruksjon.

Det er mulig å ringe lignende subrutine flere ganger som du ønsker, noe som forklarer hvorfor bruk av subrutiner reduserer den generelle varigheten av programmet vårt.

Likevel er det et par faktorer du bør vite om. I utgangspunktet, som med vårt hovedprogram, må alle spesifikke konstanter anerkjennes før du kan bruke dem.

Disse kan muligens bli anerkjent i selve underrutinen, eller direkte i begynnelsen av hovedprogrammet. Jeg foreslår at du anerkjenner alt i begynnelsen av hovedprogrammet, siden du anerkjenner at ting er i en identisk posisjon. Deretter bør man sørge for at hovedprogrammet hopper over underrutinen.

Det jeg antyder med dette er at hvis du plasserer subrutinen direkte ved avslutningen av ditt primære program, bortsett fra hvis du bruker en 'Goto' -erklæring for å hoppe av der subrutinen er, vil programmet fortsette og implementere subrutinen uansett om du krever det til eller på annen måte.

PIC skiller ikke mellom en subrutine og hovedprogrammet. Vi vil sjekke ut vårt blinkende ledede program, men denne gangen skal vi bruke en underrutine for forsinkelsessløyfen. Ideelt sett vil du oppdage hvor mye mindre komplisert programmet ser ut, så vel som du kan finne ut hvordan subrutinen gjelder praktisk talt.

Til slutt kan du se at ved å bruke en underrutine for forsinkelsessløyfen, kan vi ha redusert dimensjonene til programmet.

Hver gang vi ønsker en forsinkelse, muligens når lysdioden er på eller av, kaller vi i utgangspunktet forsinkelsen underrutine. Ved avslutningen av underrutinen fører programmet tilbake til linjen etter vår ‘Call’ instruksjon. I illustrasjonen ovenfor slår vi lysdioden på.

Vi kontakter deretter rutinen. Programmet kommer deretter tilbake for at vi skal kunne slå av LED-lampen. Vi kaller subrutinen en gang til, bare i tilfelle subrutinen kan ha fullført, kommer programmet tilbake og den påfølgende instruksjonen det gjenkjenner er ‘goto Start’. For alle som kan bli fascinert, var vårt første program 120 byte langt.

Gjennom bruk av underrutinen kunne vi redusere programstørrelsen ned til 103 byte. Dette kan ikke høres så fantastisk ut, men med tanke på det faktum at vi bare har 1024 byte samlet inne i PIC, har alle fordeler.

I løpet av neste instruksjon, la oss sjekke ut lesing fra portene.

Så langt har vi komponert til Port A for at vi skal kunne slå en LED på og av. På dette punktet vil vi se hvordan vi skal lese I / O-pinnene på portene.

Lese inngangs- / utgangsporter

Dette er nøyaktig for å sikre at vi er i stand til å koble til en ekstern krets, og påvirke eventuelle spesifikke utganger den tilbyr.

Hvis du vil huske fra de tidligere kursene våre, hvis du ønsker å etablere I / O-portene, måtte vi hoppe fra Bank 0 til Bank 1. Vi vil oppnå det først:

På dette punktet har vi fikset bit 0 av Port A til inngang. vi må nå undersøke om tappen er høy eller lav. For å oppnå dette kan man bare bruke en av to instruksjoner:

BTFSC og BTFSS.

BTFSC-instruksjonen betyr 'Gjør litt test på registeret så vel som bit vi betegner.

I tilfelle det er en 0, utelater vi i så fall den påfølgende instruksjonen ’. BTFSS innebærer ‘Gjør litt test i registeret og biten vi etablerer. I tilfelle den er satt til 1, så omgår vi den påfølgende instruksjonen.

Hvilken vi bruker, bestemmes av nøyaktig hvordan vi ønsker at programmet vårt skal svare mens vi studerer innspillene. Som en illustrasjon, i tilfelle vi bare venter på at inngangen skal være 1, kan vi kanskje bruke BTFSS-instruksjonen på følgende måte:

Kode her:

BTFSS PortA, 0 Gå til start Fortsett her:
:

Programmet vil bare skifte til 'Fortsett her' forutsatt at bit 0 på PortA er planlagt til 1.

Vi vil for øyeblikket skrive et program som kan be om en LED i samme takt, men hvis en bryter er begrenset, vil den blinke LED to ganger så saktere.

Det er mulig å kanskje utøve dette programmet på egen hånd, likevel. Vi har innlemmet oppføringen på en eller annen måte.

Du kan prøve og lage hele programmet for å sjekke om du har forstått prinsippene. Vi vil bruke tilsvarende krets som før, med inkludering av en bryter festet RA0 av PIC og den positive skinnen til vår forsyning.

Det vi har oppnådd her er å slå på LED-lampen. Jeg avgjør deretter om bryteren er lukket.

Hvis det er begrenset, kobler jeg meg til forsinkelsesrutinen vår. Dette gir oss den tilsvarende forsinkelsen som før, men vi kontakter nå to ganger.

Det samme gjelder når LED-lampen er av. Hvis bryteren ikke er slått av, har vi registrert vår tidligere på- og av-periode.

Har du fulgt disse leksjonene fra begynnelsen, prøver du kanskje å forstå at du for øyeblikket har oppdaget ti av de 35 instruksjonene for PIC 16F84! Og hver eneste bit av disse læres bare ved å slå en LED på og av.

Inntil nå har vi komponert PIC-blink og en LED på og av.

Deretter var vi i stand til med vår PIC ved å inkludere en bryter, og derfor varierte blitshastigheten.

Bruke minneplass effektivt

Det eneste problemet er at programmet er ganske langt og ganske lite effektivt med minne. Det virket ok mens jeg inkluderte kommandoene for første gang, men det burde være en enklere måte å utføre den på. Positivt det er, vil vi analysere hvordan vi bokstavelig talt slo LED-en på og av.

movlw 02hmovwf PORTAmovlw 00hmovlw PORTA

Først fylte vi w-registeret vårt med 02h, etter det overførte det til PortA-registeret vårt for å slå på LED-en. For å slå den av, pakket vi w med 00h, hvoretter flyttet den til PortA-registeret vårt.

Innimellom alle disse rutinene ble vi tvunget til å komme i kontakt med en underrutine for å sikre at vi kunne observere LED-blinkingen.

Derfor trengte vi å overføre to sett med info et par ganger (en gang inn i w-registeret og deretter til PORTA), samt ringe en subrutine to ganger (en gang for og deretter en gang for av). Dermed, hvordan kunne vi oppnå dette med ekstra effektivitet? Veldig enkelt.

Vi bruker en annen instruksjon kjent som XORF. XORF-instruksjonen fungerer som en eksklusiv ELLER-funksjon i registeret som vi angir med informasjonen vi gir. Jeg tror jeg må avklare hva i all verden en eksklusiv ELLER er før vi fortsetter. I tilfelle vi har to innganger og en utgang, kan inngangen bare være 1 hvis, og så lenge de to inngangene er forskjellige. Mens de er de samme, vil produksjonen sannsynligvis være 0. Følgende er en sannhetstabell for enkeltpersoner som velger å sjekke ut disse:

A B F0 0 00 1 11 0 11 1 0

Vi vil på dette punktet sjekke ut hva som skjer hvis vi gjengir B ​​akkurat som vår tidligere produksjon, og ganske enkelt endrer verdien av A:

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

Hvis vi opprettholder verdien på A som 1, og vi Eksklusiv ELLER den med utgangen, vil utgangen veksle. I tilfelle du ikke kan legge merke til dette fra sannhetstabellen, kan du se det nedenfor ved hjelp av binær:

0 Strømutgang
EX-ELLER Med 1 1 Ny utgang
EX-ELLER Med 1 0 ny utgang

Kanskje du kan finne at ved å eksklusiv ELLER utgangen med 1, vil vi nå bytte utdata fra 0 til 1 til 0.
Derfor, for å slå LED-en på og av, trenger vi bare et par setninger:

MOVLW 02h
XORWF-DØR, 1

Det vi skal oppnå, er å legge til w-registeret vårt med 02h. Vi er i så fall Eksklusivt ELLER å bestille dette nummeret uansett hva som er på vår PortA. I tilfelle bit 1 er en 1, vil den endre seg til en 0. Hvis bit 1 er en 0, vil den endre seg til en 1. La oss undersøke denne koden en eller to ganger for å vise hvordan den kjører binær:

DØR
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

Vi trenger faktisk ikke å laste den samme verdien i w-registeret hver gang, derfor er det mulig å oppnå dette en gang i starten, og ganske enkelt hoppe tilbake til vår vekselkommando. I tillegg burde vi ikke sette en verdi i PortA-registeret vårt. Grunnen? Sikkert, siden i tilfelle strøm er 1, kan vi enkelt bytte den. Jeg, alternativt en 0 på strøm, vi ville til og med nå slå den på.

Derfor vil du se vår nyopprettede kode. Den første representerer vår blinkende LED-kode, mens den andre viser den med tillegg av bryteren:

La oss ønske at du kan finne ut at ved å bruke en enkel instruksjon, har vi nå kuttet ned skalaen til programmet vårt. Sannheten er at for å vise hvor mye vi kunne redusere programmene våre, har vi vist de to programmene, akkurat hva som ble komponert, og dimensjonene i tabellen nedenfor:

Program Alter Dimensions (Bytes)
Blinkende LED Original 120
Blinkende LED-subrutine lagt til 103
Blinkende LED XOR-funksjon brukt 91
LED med bryter original 132
LED med bryter XOR-funksjon brukt 124.

Derfor har vi ikke bare oppdaget noen nye instruksjoner, vi har i tillegg redusert størrelsen på skriptene våre!

Nedenfor vil vi analysere hvordan du kan vri individuelle biter, utføre visse enkle aritmetikker, samt datatabeller.

Logiske ledere

I løpet av den siste veiledningen presenterte jeg Exclusive OR-operasjonen. ExOR-funksjonen forstås som en logisk operator.

I denne opplæringen vil jeg opplyse om de ekstra logiske operatørene som PIC fremmer. Det vil ikke være noen sak i punktprogrammer, men vi lærer enkle metoder for å bruke operatørene ved å bruke små kodeområder.

OG-funksjonen analyserer i utgangspunktet to biter og leverer en 1 om de er like, og en 0 i tilfelle de er særegne. For eksempel, hvis vi nevnte 1 OG 1, blir resultatet 1, mens i tilfelle vi erklærte 1 OG 0, ville konsekvensen være 0.

Det er unødvendig å si at vi også kan evaluere ord, i tillegg til at alle AND-funksjonene oppnår er å gjennomgå de to begrepene litt etter litt. Forekomsten nedenfor viser to 8-biters ord som blir ANDed sammen med produktet:

11001011
OG 10110011
Tilsvarer 10000011

Jeg håper du er enig, resultatet vil ganske enkelt ha en 1 når 2 1s hånd i hånd med hverandre i et par ord. Vi er i stand til å bruke AND-funksjonen til å verifisere portene, for eksempel.

I tilfelle vi sjekker noen få I / O-pinner som er koblet til en krets, og vi bør holde øye med en bestemt situasjon der bare noen få av pinnene er høye, i så fall kan vi ganske mye lese port, hvoretter OG utfallet med tilstanden vi har undersøkt for, identisk med forekomsten ovenfor.

PIC gir oss to ingredienser for AND.
De er ANDLW og ANDWF. ANDLW tillater oss å utføre en AND-funksjon med detaljene i W-registeret, og et beløp som vi fastsetter.

Syntaksen er: ANDLW hvor er akkurat det vi skal OG innholdet i W med.

Konsekvensen av AND-funksjonen vil bli lagret direkte i W-registeret.
ANDWF tillater oss å utføre en AND-funksjon i W-registeret og et annet register, for eksempel en PORT. Syntaksen er: ANDWF, d der er registeret vi er begeistret for, f.eks. PORTA, og d viser PIC hvor du skal plassere resultatet. Hvis d = 0, blir resultatet satt i W-registeret, og av d = 1 blir sluttresultatet lagret i registeret vi fastsatte. De to delene av koden nedenfor viser et godt eksempel på hver OG-funksjon.

Initialen undersøker statusen til PORTA, der vi må sjekke om inngangene er 1100. Vi kan plassere resultatet tilbake i W-registeret

movlw 1100
ANDWF 05h, 0Den andre illustrasjonen kan nå bekrefte innholdet i W-registeret:
ANDLW 1100

ELLER

Vi har nå oppdaget en ELLER-funksjon, for å være nøyaktig XOR. Dette utvikler seg til en 1 hvis to biter ikke er like, men er forskjellige. Du kan finne en annen ELLER-funksjon kalt IOR, som er den inkluderende ELLER. Denne funksjonen vil generere en 1 i tilfelle en bit er en 1, men i tillegg hvis hver bit er 1. Nedenfor er en oversiktlig sannhetstabell for å illustrere dette:

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

Hva er aritmetiske operatører

LEGG TIL

Denne funksjonen oppnår det som den vanligvis hevder. Det bidrar med to figurer! I tilfelle konsekvensen av å legge til de to figurene overgår 8 bits, vil i så fall sannsynligvis et CARRY-flagg bli satt. CARRY-flagget ligger på adresse 03h bit 0.

Når denne biten er planlagt, overgikk de to figurene 8 bits. Når det er en 0, ligger konsekvensen i så fall innen 8 bits. Som før leverer PIC oss to ADD-stiler, spesielt ADDLW og ADDWF. Som du kanskje antok, er dette ganske som funksjonen ovenfor. ADDLW tilbyr innholdet i W-registeret som vi foreskriver. Syntaksen er: ADDLW ADDWF legg til innholdet i W-registeret og et annet register som vi betegner.

Syntaksen er: ADDWF, d er hvor

UNDER

På dette tidspunktet antar jeg at du ikke kan anta hva denne funksjonen utfører! Du mistenkte det, denne funksjonen
trekker en bit fra en annen. Igjen gir PIC oss to smaker: SUBLW og SUBWF. Syntaksen er nøyaktig den samme som for ADD-funksjonen, bortsett fra at du tydeligvis skriver SUB i stedet for ADD!

Inkrement I tilfelle vi ønsket å inkludere 1 til et nummer i PIC, kunne vi absolutt bruke ADD-funksjonen og bruke nummer én. ~ Vanskeligheten med dette er at vi først må plassere figuren i W-registeret, og deretter bruke ADDLW 1-kontrollen for å øke den. I tilfelle vi ønsket å inkludere 1 i et register, kan det være verre. Vi må først plassere nummer 1 i W-registeret, deretter bruke ADDWF, 1. Derfor, for eksempel, for å inkludere 1 til plassering 0C, si, må vi ha følgende del av skriptet:

movlw 01
addwf 0c, 1

Det finnes en enklere metode for å gjennomføre dette. Vi kan utøve kommandoen INCF. Syntaksen er: INCF, d hvor, er det registeret eller stedet vi er opptatt av, og d viser PIC hvor du skal plassere utfallet. I tilfelle d = 0 er resultatet innenfor W-registeret, og i tilfelle d = 1 blir konsekvensen satt i registeret vi fastsatte.

Ved å bruke denne individuelle instruksjonen er vi i stand til faktisk femti prosent av kodingen. I tilfelle vi ønsket at resultatet ble gjenopprettet i W-registeret, i så fall ved å bruke forekomsten ovenfor, måtte vi kanskje ha med en ekstra kommando for å flytte elementene på 0C tilbake til W-registeret, hvoretter 0C-registeret tilbake til nei uansett hva det var.

Det finnes økningskommando. Det er INCFSZ. Denne kommandoen kan øke registeret som vi forutsetter, men hvis vi registret er lik 0 etter inkrementet (som vil skje mens vi inkluderer 1 til 127), vil PIC sannsynligvis passere den påfølgende instruksjonen. Delen av koden nedenfor gjenspeiler dette:

Sløyfe incfsz 0C
Gå til løkken
:
:
Resten av programmet.

I den ovennevnte delen av koden vil 0C økes med 1. Vi eier deretter en instruksjon som informerer PIC om å gå tilbake til taggen vår som heter Loop, og øke 0C med 1 igjen. Dette fortsetter til 0C er lik 127. Under denne omstendigheten, når vi øker 0C med 1, vil 0C nå matche 0. Vår INCFSZ-instruksjon kan veldig godt informere PIC om å utelate den påfølgende instruksjonen, som i dette tilfellet er goto-erklæringen, derfor vil PIC gå videre med den gjenværende delen av programmet.

Nedgang

Vi har nå diskutert reduksjonsfunksjonen i tidligere trening, derfor vil jeg ikke revidere den lenger.

Komplement

Den siste instruksjonen i denne diskusjonen ville reversere hver eneste bit i registeret som vi fastsetter. Syntaksen er: COMF, d hvor

Forstå bitoperasjoner

Dette kan for eksempel brukes til å raskt bytte pinnene til en port fra utgang til inngang og så videre. Bitfunksjoner tillater oss å forme en enkelt bit i et uttrykk. De tillater oss å fortsette, sette og kvitte oss med enkeltbiter i registre eller tall som vi angir.

Ved avslutningen av dette kurset vil vi avsløre et program designet for å lage et sett med sekvenseringslys som går fremover, og deretter motsatt vei. Vi observerte dette oppnådd tidligere da vi undersøkte den eksklusive ELLER-funksjonen, hvor vi eksklusivt ORte portene med et uttrykk. Vi har til nå lagt merke til noen få bitfunksjoner når vi etablerer portene på PIC, og

La meg gjenta bruken her.

BCF

Denne instruksjonen vil tørke av litt som vi fastsetter i et register som vi utpeker. Syntaksen
er:
BCF,

Vi brukte dette tidligere for å endre fra side 1 til side 0 ved å fjerne litt i STATUS-registeret. Vi kan også bruke den til å fikse litt til 0 i et hvilket som helst annet register / sted. For eksempel, i tilfelle vi ønsket å sette den tredje biten i 11001101 lagret i seksjon 0C til 0, kan vi
sett inn:

BCF 0C, 03

BSF

Denne instruksjonen vil fikse hvilken bit vi bestemmer til 1 i ethvert register som vi angir. Vi brukte dette tidligere for å gå fra side 0 til side 1. Syntaksen er: BSF ,, og blir brukt i nøyaktig samme metode som BCF ovenfor.

BTFSCHittil kunne vi stille eller tømme litt i et register. Tenk deg om vi i utgangspunktet trenger å sjekke om litt er en 1 eller en 0 i et register?

Det er sikkert mulig å bruke BTFSC. Det står Bit Test Register F, og hopp over hvis det er klart. Denne instruksjonen skal analysere biten vi betegner i registeret. Hvis biten er 0, vil instruksjonen informere PIC om å passere den påfølgende instruksjonen.

Vi kan bruke denne instruksjonen i tilfelle vi ønsker å sjekke et flagg, for eksempel bæreflagget. Dette sparer oss for å måtte lese STATUS-registeret og søke etter de enkelte bitene for å lære hvilke flagg som er faste. 29 Hvis vi for eksempel ville sjekke om Carry-flagget var satt til 1 etter at vi hadde lagt til 2 figurer, kunne vi skrive inn følgende:

BTFSC 03h, 0
fortsett her hvis den er satt til 1
eller her hvis den er satt til 0

I tilfelle bitens status er 1, vil i så fall instruksjonen etter BTFSC bli fullført. I tilfelle den er satt til 0, hoppes den påfølgende instruksjonen i så fall. Følgende del av koden viser hvor den kan brukes:

Løkke :
:
:
BTFSC 03,0
Gå til løkken

I ovennevnte kode vil PIC ganske enkelt komme seg ut av sløyfen i tilfelle bit 0 i STATUS-registeret (eller Carry-flagget) er definert til 0. Ellers vil goto-kommandoen bli utført.

BTFSS

Denne instruksjonen angir bit testregister F, og hopp over hvis angitt. Dette kan sammenlignes med BTFSC-instruksjonen, bortsett fra at PIC ville utelate den påfølgende instruksjonen hvis biten vi har evaluert er satt til 1, i stedet for 0.

CLRF

Denne instruksjonen vil fikse hele detaljene i et register til 0. Syntaksen er:

CLRF
Vi benyttet dette tidligere for å sette produksjonen til havnene til 0 ved å bruke CLRF 85h. Vi brukte den videre for å fikse portene slik at de inkluderer alle pinner som skal sendes ut ved å bruke CLRF
05h.

CLRW

Dette kan ligne CLRF-instruksjonen, med unntak av å fjerne W-registeret. Syntaksen er ganske enkelt:

CLRW

RLF og RRF

Disse retningene vil transportere litt i et register et enkelt spor til venstre (RLF) eller høyre (RRF) i et register. For eksempel, hvis vi trengte 00000001 og vi brukte RLF, ville vi i så fall kanskje ha 00000010. På dette tidspunktet, hva skjer hvis det er 10000000 og brukte RLF-instruksjonen? Sikkert ville 1 være plassert i bæreflagget. I tilfelle vi brukte RLF-instruksjonen en gang til, ville 1 dukke opp igjen i starten. Det samme skjer, men motsatt, for RRF-instruksjonen. Tilfellet i punkt nedenfor viser dette for RLF-instruksjonen, der Vi kan se de 8 bitene i et register, samt bæreflagget:

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

Eksempel på program

Vi skal nå se en eksempelkode som man kan kompilere og kjøre. Det vil generere et sekvenseringslys som begynner på PortA bit 0, går til PortB bit 8 og
deretter tilbake.
Koble opp lysdioder til hver av portpinnene. Vi vil ha noe av det
prosedyrer påpekt i denne veiledningen.

TIME EQU 9FH Variabel for forsinkelsessløyfen.
PORTB EQU 06H Port B-adresse.
TRISB EQU 86H Port B Tristate-adresse.
PORTA EQU 05H Port A-adresse.
TRISA EQU 85H Port A Tristate-adresse.
STATUS EQU 03H Velg side for register.
COUNT1 EQU 0CH loop-register.
COUNT2 EQU 0DH Loop-register.

BSF STATUS, 5 Gå til side 1
MOVLW 00H og sett opp
MOVWF TRISB både porter A og B
MOVLW 00H til utgang,
MOVWF TRISA og kom tilbake til
BCF STATUS, 5 side 0.
MOVLW 00H Fjern port A.
MOVWF-DØR

Start av hovedprogram

RUNMOVLW
01H Still inn den første bitMOVWF
PORTB på Port B.CALL
FORSINK Vent litt RING
FORSINKELSE
Flytt biten på Port B til venstre, og pause.RLF
PORTB, 1CALL
FORSINKELSE
FORSINK
PORTB, 1CALL
FORSINKELSE
FORSINK
PORTB, 1CALL
FORSINKELSE
FORSINK
PORTB, 1CALL
FORSINKELSE
FORSINK
PORTB, 1CALL
FORSINKELSE
FORSINK
PORTB, 1CALL
FORSINKELSE
FORSINK
PORTB, 1CALL
FORSINKELSE
FORSINK
PORTB, 1 Dette beveger seg litt inn i bæreflagget
Gå nå til Port A, og flytt biten til venstre.RLF
PORTA, 1 Dette flytter biten fra nullflagget til PortACALL
DELAYCALL DELAYRLF
DØR, 1RING
FORSINKELSE
FORSINK
DØR, 1RING
FORSINKELSE
FORSINK
DØR, 1RING
FORSINKELSE
FORSINKELSE
Flytt biten tilbake på Port ARRF
DØR, 1RING
FORSINKELSE
FORSINKELSE
DØR, 1RING
FORSINKELSE
FORSINKELSE
DØR, 1RING
FORSINKELSE
FORSINKELSE
PORTA, 1 Dette flytter biten inn i nullflagget. Flytt nå biten
tilbake på Port BRRF
PORTB, 1CALL
FORSINKELSE
FORSINKELSE
PORTB, 1CALL
FORSINKELSE
FORSINKELSE
PORTB, 1CALL
FORSINKELSE
FORSINKELSE
PORTB, 1CALL
DELAYCALL DELAYRRF
PORTB, 1CALL
FORSINKELSE
FORSINKELSE
PORTB, 1CALL
FORSINKELSE
FORSINKELSE
PORTB, 1CALL
FORSINKELSE
FORSINKELSE Nå er vi tilbake der vi startet, GOTO
LØP la oss dra igjen.

Det finnes et flott alternativ i treningssettet som gjør at du kan bruke en datatabell.

En datatabell er bare en liste over datatilbud, der alt blir sett over basert på noen få hensyn.
For eksempel kan du ha en krets som bruker en PIC som teller antall tilfeller en inngangspinne blir høy på 1 sekund. Etter det kan du vise nummeret på et 7-segment display.

Så snart timingen er lansert, begynner PIC å telle antall anledninger pinnen blir høy. Etter 1 sekund besøker den tabellen og ser opp dataene, den må vise nummeret på skjermen som symboliserer antall situasjoner pinnen ble høy. Dette kan være gunstig, siden vi ikke bestemmer hva tallet kan være før PIC har oppnådd estimatet.

Ved å bruke en tabell, er vi i stand til å la PIC bestemme hvilken figur som skal skildres. På dette tidspunktet, før jeg fortsetter å vise deg hvordan datatabellen fungerer, må jeg kanskje fortelle deg at PIC opprettholder banen i programmet den er mens programmet kjører.

Det tilrettelegger for de som har utført viss programmering i BASIC. Ellers ikke vær engstelig, du vil kanskje fortsette å lære om teorien. Se for deg at det er et grunnleggende program som ligner det som presenteres nedenfor:

10 ÅR K = 0
11 K = K + 1
12 HVIS K> 10 DAN GETO 20 ELSE GOTO 11
20 SKRIV UT K
21 SLUTT

Programmet begynner på linje 10. Så snart K er planlagt til 0, går det videre til linje 11. Etter at vi har tatt med 1 til K fortsetter vi videre til linje 12.

På dette punktet kan vi være nysgjerrige på om K er høyere enn 10. I tilfelle det er, går vi videre til linje 20, ellers kommer vi tilbake til linje 11.

Linje 20 dokumenterer K, og linje 21 avslutter programmet. BASIC bruker linjestatistikk for å hjelpe programmereren med å registrere hvor problemene er, ettersom etiketter ikke er autoriserte. PIC bruker etiketter for å unnslippe mellom destinasjoner - eller kan det virkelig?

Vi bruker etikettene for å sikre at vi er klar over hvor problemene er, samt for å sikre at vi er i stand til å informere PIC på en enkel måte hvor vi skal søke.

Nettopp det som skjer er at PIC utnytter en indre linjeteller som kalles Programteller. Programtelleren (forkortet til PC) for minnedestinasjonen der den nåværende instruksjonen er.

Hver gang vi informerer PIC om å besøke en valgt etikett, forstår den minnepunktet og utvider derfor PCen til den ser den minnedestinasjonen. Dette er nøyaktig den samme metoden som vi sjekker ut BASIC-programmet ovenfor. Nedenfor er et kodesegment med minneplasser eller elementene på PC-en, ved siden av hver instruksjon:

PC-instruksjon0000 movlw 03
0001 movwf 0C
0002 Loop decfsc 0C
0003 goto Loop
0004 slutt

I demonstrasjonen ovenfor har vi fikset PCen til 0000. På denne har vi instruksjonen movlw 03. Når PIC har implementert disse dataene, øker den PC-en slik at den påfølgende instruksjonen blir skannet. På dette punktet viser PIC movwf 0C. PC-en økes igjen.

Nå studerer PIC decfsc 0C. I tilfelle detaljene til 0C ikke er 0, i så fall inkrementeres PC-en med 1, samt følgende instruksjon, goto Loop, informerer PC-en om å gå tilbake til posisjon 0003, der det er nevnte Loop. Hvis detaljene i 0C er 0, anbefales det at PC-en øker med 2, bare la den neste instruksjonen utelates.

Forstå datatabeller

Dette plasserer PC-en i posisjon 0004, hvor programmet avsluttes. Destinasjonene løses av samleren, og vi burde generelt ikke være bekymret for hva PC-en oppnår. Inntil vi finner behovet for å bringe det under kontroll akkurat som mens vi gjør når vi bruker datatabeller. Den mest praktiske måten å beskrive hvordan en datatabell fungerer på, er å begynne med en illustrasjon.

PC ekv 02
movlw 03
ringetabell
:
tabell addwf PC
tilbake 01
tilbake 02
tilbake 03
bak 04
tilbake 05
tilbake 06
tilbake til 07
komme tilbake

Den første instruksjonen tildeler etiketten PC med adressen til programtelleren (02h). Vi vil være snart etter å ha satt verdien på 03h i w-registeret. Vi kommuniserer etter det til bordet. Den fremste linjen i underrutinetabellen øker detaljene i W-registeret (03h) til programtelleren.

Dette utløser programtelleren til å øke med 3, eller for å si det på en annen måte, stimulerer programtelleren til å fortsette nedover 3 linjer. Mens telleren kommer tre linjer nedover, gjenkjenner PIC instruksjonen på nytt. Denne kommandoen sender verdien som følger den til W-registeret, hvoretter kommer tilbake fra underrutinen. RETLW betyr i utgangspunktet Return, bokstavelig for W.

Se jeg la et komma etter ordet Return. Siden vi er i en underrutine, trenger vi en returinstruksjon for å overflaten av den. Derfor RET i instruksjonen. Etter at RETLW-instruksjonen er et tall, og det er akkurat det som blir satt inn i W-registeret.

I dette tilfellet er det figur 3. Vi kan betegne hvilken som helst mengde til W-registeret, så lenge denne figuren er kombinert med Programtelleren i tabellundervisningen, skal vi oppdage en ny instruksjon. I illustrasjonen ovenfor antyder dette at vi er i stand til å ha et hvilket som helst tall fra 1 til 7. I tilfelle vi går forbi underrutinen, kan vi kanskje fullføre oppføringen av en ekstra del av programmet. Av denne grunn er det vanligvis et smart trekk å plassere datatabellen nøyaktig mot slutten av PIC-programmet, så hvis vi i så fall overskytter, kommer vi til å avslutte programmet uansett.

Temaet for avbrudd kan godt være det lengste og tøffeste å gå gjennom.

Du kan ikke finne noen ukomplisert metode for detaljering av avbrudd, men med litt flaks mot slutten av denne delen kan du kanskje bruke avbrudd i dine egne programmer.
Vi har delt seksjonen i to trinn. Dette er for å gjøre det mulig å skille emnet inn i seksjoner, også for å gi deg en praktisk opplegging for enkel forståelse.

Hva er egentlig et avbrudd? Sikkert, som begrepet indikerer, er et avbrudd en teknikk eller et signal som forhindrer en mikroprosessor / mikrokontroller fra hva som helst det utfører at noe annet kan skje.

Tillat meg å gi deg en daglig illustrasjon. Tror du slapper av i ditt eget hjem og snakker med en annen person. Plutselig høres telefonen ut.

Du slutter å snakke, og tar tak i telefonen for å snakke med den som ringer. Når du har hatt telefoninteraksjonen din, bestemmer du deg for å gå tilbake til å snakke med den enkelte før telefonen ringte. Det er mulig å vurdere hovedrutinen mens du chatter med noen, telefonen som ringer fører til å forstyrre samtalen din, og pause i rutinen er metoden for å snakke i telefonen.

Mens telefonsamtalen slutter, går du tilbake til din primære rutine for å chatte. Denne illustrasjonen er nøyaktig hvordan en avbryter en prosessor for å iverksette tiltak.

Primærprogrammet er i drift, og utfører en viss funksjon i en krets, men når et avbrudd finner sted stopper det primære programmet mens en annen rutine utføres. rutinen ender, beveger prosessoren seg tilbake til den primære rutinen akkurat som før.

Forstå avbrudd

PIC har fire kilder til avbrudd. De kan deles inn i et par grupper. To er kilder til avbrudd som kan brukes utad til PIC, mens de to andre er indre prosesser. La meg avklare de to eksterne typene her. De to andre kommer til å bli beskrevet i forskjellige veiledninger når vi kommer til tidtakere og lagrer data.

Skulle du sjekke ut pin-out på PIC, vil du legge merke til at pin 6 er RB0 / INT. På dette punktet er RB0 helt klart Port B bit 0. INT representerer at den like godt kan være konfigurasjoner som en utvendig avbruddspinne. Videre kan port B-pinner 4 til 7 (pinner 10 til 13) også benyttes for avbrudd. Før vi kan bruke INT eller en annen Port B-pinner, må vi utføre to oppgaver. Aller først må vi informere PIC om at vi vil bruke avbrudd.

Deretter må vi angi hvilken port B-pin vi skal bruke som en avbrudd i stedet for som en I / O-pin. Inne i PIC kan du finne et register kjent som INTCON, og er på adressen 0Bh. I dette registeret vil du oppdage 8 bits som kan aktiveres eller deaktiveres. Bit 7 av INTCON er kjent som GIE. Dette er Global Interrngupt Enable. Å fikse dette til 1 informerer PIC om at vi vil bruke et avbrudd.

Bit 4 av INTCON er kjent som INTE, INTerrupt Enable. Å sette denne biten til 1 formidler til PIC at RB0 kommer til å være en avbruddspinne. Konfigurering av bit 3, kalt RBIE, informerer PIc om at vi skal bruke Port B-bitene 4 til 7. På dette punktet forstår PIC når denne pinnen kan være høy eller lav, må stoppe hva den utfører og fortsette med et avbrudd rutine. På dette punktet må vi informere PIC om avbruddet sannsynligvis vil være på den stigende kanten (0V til + 5V) eller fallkanten (+ 5V til 0V) transformasjonen av signalet.

Enkelt sagt, ønsker vi at PIC avbryter hver gang signalet beveger seg fra lav til høy, eller fra høy til lav. Ved kriminalitet kan dette etableres for å bli plassert på den stigende kanten.

Kantutløseren er planlagt opp i et tilleggsregister kalt OPTION-registeret på adresse 81h. Biten vi er begeistret for er bit 6, ofte referert til som INTEDG.

Hvis du setter dette til 1, utløses PIC for å forstyrre på monteringskanten (standardtilstand) og sette den til 0 stimulerer PIC til å forstyrre på glidekanten. Hvis du vil at PIC skal aktiveres på den stigende kanten, trenger du absolutt ikke å gjøre noe for denne biten.

På dette punktet er dessverre alternativregisteret i bank 1, noe som betyr at vi liker å endre fra bank 0 til bank 1, sette biten i opsjonsregisteret, etter at retur til bank 0. Nøkkelen her er å oppnå hver bit av Bank 1 registrerer seg i en enkelt streik, for eksempel å etablere havnepinnene, og deretter returnere til Bank 0 hvis du er ferdig.

Fint, derfor har vi varslet PIC hvilken pin som sannsynligvis vil være avbruddet, og hvor kanten skal utløses, hva skjer i programmet og PIC når avbruddet skjer? Et par ting finner sted. Aller aller første er et 'flagg' planlagt.

Dette informerer den interne prosessoren til PIC om at et avbrudd har skjedd. Deretter tipser programtelleren (som jeg snakket om i forrige opplæring) til en spesifikk adresse i PIC. La oss raskt sjekke ut alle disse individuelt. Interrupt Flag I vårt INTCON-register er bit 1 interrupt flagg, kalt INTF. På dette punktet vil dette flagget sannsynligvis bli satt til 1 når det oppstår avbrudd.

Når det ikke er noe avbrudd, blir flagget satt til 0. I tillegg til at det er omtrent alt som oppnås. På dette punktet kan du tenke på 'hva er poenget?' Selv om dette flagget er planlagt til 1, er ikke PIC i stand til og vil ikke reagere på en annen avbrudd. La oss derfor uttrykke at vi får til et avbrudd. Flagget vil sannsynligvis være festet til 1, og PIC kan gå til vår rutine for å jobbe avbruddet.

Når dette flagget ikke var festet til 1, og PIC fikk lov til å fortsette å svare på avbruddet, kan kontinuerlig pulsering av pinnen holde PIC tilbake til begynnelsen av vår avbruddsrutine, og på ingen måte fullføre det. Når jeg kommer tilbake til illustrasjonen av telefonen, ligner det på å løfte telefonen, og umiddelbart når du fortsetter å diskutere, begynner den å ringe igjen, siden en annen person ønsker å snakke med deg.

Det anbefales å fullføre en dialog, og ta deretter telefonen igjen for å snakke med den påfølgende personen. Du kan finne et lite problem med dette flagget. Selv om PIC raskt setter dette flagget til 1, setter det ikke det igjen 0! Denne aktiviteten må utøves av programmereren - dvs. deg. Dette kan enkelt oppnås, siden jeg er sikker på at jeg antar, og må oppnås etter at PIC har utført avbruddsrutinen.

Minneplassering Når du først slår på PIC-en, eller i tilfelle det foreligger en tilbakestilling, tipser programtelleren for å adressere 0000h, som kan være umiddelbart i begynnelsen av programminnet. Men i tilfelle det oppstår et avbrudd, vil programtelleren indikere adresse 0004h.

Derfor, mens vi komponerer vårt program som vil ha avbrudd, må vi først informere PIC om å hoppe over adresse 0004h, og opprettholde avbruddsrutinen som begynner på adresse 0004h diskret fra resten av programmet.

Dette kan være problemfritt å utføre. I utgangspunktet starter vi programmet vårt med en kommando kjent som ORG. Denne kommandoen indikerer Opprinnelse, eller start. Vi holder oss til det med en adresse. Siden PIC begynner på adresse 0000h, skriver vi ORG 0000h. Etter det må vi omgå adressen 0004h. Vi oppnår dette ved å sette en GOTO-instruksjon, ledsaget av en etikett som gir tips til vårt primære program.

Vi følger etter denne GOTO-kommandoen med en ORG til, dette øyeblikket med adressen 0004h. Det vil være etter denne kommandoen at vi setter inn vår avbruddsrutine. På dette punktet kan vi muligens skrive inn vår avbruddsrutine rett etter den andre ORG-kommandoen, eller vi kan posisjonere en GOTO-setning som peker på avbruddsrutinen.

Det er virkelig relatert til alternativ fra din side. For å informere PIC det tilbyr kom til slutten av avbruddsrutinen, må vi plassere kommandoen RTFIE mot slutten av rutinen. Denne kommandoen betyr retur fra avbruddsrutinen. Mens PIC merker dette, indikerer programtelleren til den endelige posisjonen PIC var på før avbruddet skjedde. Vi har etablert en kort kodeseksjon for å vise ovenstående:

Det er et par ting du bør informeres om når du bruker avbrudd. Initialen har en tendens til å være at hvis du kanskje bruker det samme registeret i ditt primære program og avbruddsrutinen, må du huske at detaljene i registeret mest sannsynlig vil endre seg når avbruddet finner sted.

La oss for eksempel bruke w-registeret til å videresende data til Port A primært program, derfor kan du i tillegg bruke w-registeret i avbruddsrutinen for å flytte data fra en destinasjon til en annen.

Hvis du ikke er forsiktig, vil w-registeret inkludere den siste verdien den mottok mens den hadde vært i avbruddsrutinen, så når du kommer tilbake fra avbruddet, vil denne informasjonen bli levert til Port A i stedet for verdien du hadde før avbruddet skjedde.

Midlet rundt dette er å øyeblikkelig lagre detaljene i w-registeret før du bruker det igjen i avbruddsrutinen. Det andre er det faktum at du kan finne en forsinkelse mellom når en avbrudd finner sted og når den påfølgende kan oppstå. Mens du forstår, har PIC en utvendig klokke, som muligens kan være en krystall, eller det kan være en motstandskondensatorkombinasjon.

Uansett frekvens på denne klokken, deler PIC den med 4, hvoretter den benyttes for den indre timingen. For eksempel i tilfelle du har en 4MHz krystall koblet til PIC-en din, i så fall vil PIC-en utføre instruksjonene på 1MHz. Denne interiørtimingen er kjent som en instruksjonssyklus. På dette punktet hevder databladet (utvilsomt i liten utskrift) at du trenger å aktivere 3 til 4 instruksjonsrunder mellom avbrudd.

Min ville være å aktivere 4 runder. Årsaken bak forsinkelsen er at PIC krever tid til å hoppe til avbruddsadressen, flagget og komme tilbake vekk fra avbruddsrutinen. Husk derfor dette hvis du jobber med en alternativ krets for å aktivere et avbrudd for PIC.

På dette punktet er et poeng til det faktum at hvis du bruker bits 4 til 7 i Port B som et avbrudd. Du kan ikke velge spesifikke pinner på port B for å fungere som et avbrudd.

Derfor, hvis du tillater disse pinnene, kan de sannsynligvis være tilgjengelige. Derfor kan du for eksempel ikke bare ha bits 4 og 5 - bits 6 og 7 vil sannsynligvis bli bemyndiget samtidig. Hva er egentlig hensikten med å få fire biter til å representere et avbrudd? Du kan sikkert ha en krets koblet til PIC, i tilfelle noen av fire linjer går høyt, i så fall kan dette være et problem du trenger at PIC skal påvirke umiddelbart.

En illustrasjon på dette kan være en alarm for hjemmet, der fire sensorer er koblet til port B-pinner 4 til 7. En hvilken som helst spesifikk sensor kan be PIC om å utløse en alarm, og alarmsignalerutinen er avbruddsrutinen. Dette sparer å sjekke havnene konstant og tillater PIC å fortsette med forskjellige saker. I løpet av neste opplæring skal vi komponere et program for å håndtere et avbrudd.

Vi har jobbet med mange grunnleggende ting i løpet av den siste opplæringen, derfor føler jeg tiden er inne for at vi har laget vårt første program.

Programmet vi vil skrive vil telle antall anledninger vi slår på en bryter, og viser deretter nummeret.

Programmet vil telle fra 0 til 9, som kan vises på 4 lysdioder i binær form, sammen med inngangen eller avbruddet vil trolig være på RB0.

Den viktigste tingen vi må utføre er å informere PIC om å hoppe over adressen Programtelleren peker på når et avbrudd finner sted.

Du vil observere at vi bruker en unik metode for å vise heksadesimale tall. Før jeg skjedde, bruk F9h der h indikerte heksadesimal. Vi kan skrive dette som 0xF9, som er strukturen vi skal bruke fra nå av.

Nå må vi fortelle PIC at vi skal bruke avbrudd, og vi bruker RB0 pin 6 som en avbruddspinne:

bsf INTCON, 7GIE - Global avbrytelsesaktivering (1 = aktivering)
bsf INTCON, 4INTE - RB0 avbryte aktivering (1 = aktivere)
Jeg skal fjerne avbruddsflagget i tilfelle (jeg stoler aldri på noe!)
bcf INTCON, 1INTF - Fjern flaggbit bare i tilfelle

Foreløpig må vi etablere våre to porter. Husk at ettersom vi nå bruker RB0 som en avbruddsstift, må dette etableres som en inngang:

Vi skal bruke en variabel kalt COUNT for å lagre antall byttetall. Vi kan bare øke verdien på Port A, men du vil se hvorfor jeg bruker en variabel når vi skriver vår avbruddsrutine.

Derfor er vårt hovedprogram sammensatt, og på dette tidspunktet må vi informere PIC hvordan vi skal gå frem når et avbrudd finner sted. Innenfor dette eksemplet vil avbruddet vårt sannsynligvis være bryteren. Akkurat det vi ønsker at PIC-en skal være, er en til det justerbare ANTALET hver gang bryteren er begrenset.

Likevel ønsker vi bare å vise hvor mange anledninger bryteren lukkes fra 0 til 9. Ovenfor sa jeg at vi kanskje bare kunne ha økt verdien på Port A hver gang det er et avbrudd. Port A har imidlertid 5 biter. I tilfelle vi bare økte porten, vil vi ha det høyeste antallet på 31. Det er et par forklaringer på hvorfor jeg valgte å ikke flytte opp til 31.

I utgangspunktet vil vi bruke en 7-segment skjerm, som maksimalt bare kan gå fra 0 til 15 (0 til F i hex). Deretter vil jeg i tillegg vise deg noen av de aritmetiske kommandoene du snublet over de siste timene.

Derfor vil vi fortsette med vår avbruddsrutine. For tiden er det første vi må oppnå, å lagre detaljene i w-registeret vårt, siden vi har brukt dette for å flytte innholdet i COUNT til PORTA. I tilfelle vi ikke lagrer det, kan vi i så fall levere et helt annet tall på grunn av aritmetikken. La oss derfor oppnå det først:

På dette tidspunktet forstår vi om verdien av COUNT er 9 eller mer. Akkurat det vi trenger å oppnå nå er hvis COUNT er mer enn 9, plasserer den tilbake til 0, eller ellers går tilbake til hovedprogrammet for å sikre at vi er i stand til å levere det til Port A. BTFSS-kommandoen siden du forstår at den påfølgende
instruksjon i tilfelle bæreflagget er planlagt, dvs. COUNT = 10:

Det eneste som gjenstår å gjøre er å gå inn kollektivt og bestemme verdiene til konstantene våre, som vi er i stand til å utføre rett ved starten av programmet.

Hver gang du aktiverer bryteren, vil lysdiodene telle opp i binær fra 0000 til 1010 og deretter tilbake til 0000.

Følgende figur viser kretsskjemaet som er kompatibelt med den ovenfor forklarte koden. Interessant vil du finne at tidskondensatoren er inkludert i designet. Dette er et fint lite knep som du får frihet til å unngå å inkludere kondensatoren i tilfelle du ikke har noen med deg i løpet av den tiden.

Her kommer kapasitansen til spill via den villfarne kapasitansen over oscillatorpinnen og bakken.
Selvfølgelig ser det kanskje ikke ut til å være en veldig intelligent måte å unngå en kondensator praktisk talt på siden avvikverdien kan variere med forskjellige gitte forhold.

En annen seksjon som kan være vitne til i kretsen er det oppsigende nettverket over bryteren. Dette forhindrer interferens under mekanisk svitsjing og forhindrer at PIC blir forvirret hvis byttingen var en enkelt bryter eller flere brytere.




Forrige: Programmerbar toveis motortimerkrets Neste: Hvordan Buck-Boost-kretser fungerer