PIC-vejledning - Fra registre til afbrydelser

Prøv Vores Instrument Til At Fjerne Problemer





Før du går ind i de detaljerede detaljer i PIC-programmering, ville det først være vigtigt at lære et par gode programmeringsmetoder.

Forståelse af registre

Til at begynde med antager du at du skriver a (semikolon) på ethvert tidspunkt i programmet, at alt, der kommer efter dette semikolon, bliver ignoreret af kompilatoren, indtil vognen naturligvis kommer tilbage i position.



Ovenstående funktion giver os mulighed for at tilføje kommentarer eller bemærkninger, så de ikke bliver den del af programmet, men alligevel letter os med at identificere programmet ved hjælp af kommentarerne ved siden af ​​det. At fremsætte kommentarer er en anbefalet praksis, mens du programmerer enhver IC.

Den næste vigtige ting i kurset er at tildele navne til de forskellige konstanter (du lærer dem senere udførligt). Dette gør det også lettere at forstå, hvad der skrives til, eller om de involverede værdier, i stedet for at blive forvirret med de medfølgende tal.



Ovenstående skal gøres i form af egentlige navne til øjeblikkelig genkendelse, for eksempel COUNT, det ville være vigtigt at bemærke, at her bruges alle store bogstaver for at gøre det tydeligt og også angive, at det er en konstant værdi.


Som vi kan se, foregår ovenstående i form af en kasse lavet af semikoloner, hvilket får det til at se renere ud. Prøv også at dokumentere programmet på papir, denne praksis hjælper med at forstå tingene på en trinvis måde.

2. Registerene.

Registret inden for en PIC er et område, der accepterer skriftlige detaljer og tillader læsning fra det. Du kan sammenligne det med et ark papir, hvor du kan visualisere indholdet og også tilføje ved at skrive over det.

Figuren nedenfor viser et typisk registerfilkort indlejret i en PIC16F84. Formatet er ikke noget, der faktisk er indstillet inde i PIC, det er simpelthen for at indikere, hvordan bitene kan arrangeres inde i chippen og for at forstå et par af de involverede kommandoer.

Du kan se, at det grundlæggende er opdelt i Bank 0 og Bank 1. Bank 1 er ansvarlig for at kontrollere den faktiske funktion af PIC, for eksempel tæller den PIC, hvilke bits i Port A, der er tildelt som input og hvilke som output.

Bank 2 er bare til at manipulere oplysningerne.

Lad os forstå dette gennem følgende eksempel:

Antag, at vi ønsker at tildele en bit ved PortA high. Til dette skal vi først gå til Bank 1 for at indstille den specificerede bit eller pin ved Port A i form af en output. Herefter vender vi tilbage til Bank 0 og leverer en logik 1 (bit 1) til den specifikke pin.

De mest almindelige registre, som vi gerne vil bruge i Bank 1, er STATUS, TRISA og TRISB.

STATUS hjælper os med at vende tilbage til Bank 0, TRISA giver os mulighed for at vælge, hvilke stifter på Port A der er udgange, og hvilke der kan være input, mens TRISB letter at vælge mellem output og input pin ved Port B. SELECT-registeret i BANK 0 tillader brugeren at vende til Bank 1.

Lad os sammenfatte hele konceptet med følgende beskrivelse:

STATUS:

For at skifte fra Bank 0 til Bank 1 kommanderer vi STATUS-registeret. Dette implementeres ved at sætte bit # 5 i STATUS-registeret til 1. For at vende tilbage til Bank 0 tildeler vi bit 5 i STATUS-registeret til 0. STATUS-registeret er placeret ved adresse 03h, her betyder h at tat antallet kan være i hexadecimal.

TRISA og TRISB:

Disse er placeret på adresse 85h og 86h tilsvarende. Til programmering af en pin som output eller input leverer vi bare nul eller en til den bestemte bit i registret. Nu kan dette gøres på to måder, via binær eller Hex. Hvis man ikke er i stand til at konvertere parameteren, kan han eller hun gå til en videnskabelig regnemaskine til implementering af værdierne.

Nu har vi 5 ben ved port A, hvilket svarer til 5 ben. Hvis vi har til hensigt at rette en af ​​benene som input, leverer vi en '1' til den bestemte bit.

Hvis vi ønskede at tildele en af ​​benene som output, ville vi indstille den specifikke pin til “0”. Bitene er hjælp ned nøjagtigt svarende til bitene, eller mere præcist bit 0 er RA0, bit 1 ville være RA1, bit 2 = RA2 og så videre. Lad os forstå det på denne måde:

Antag at du ønsker at rette RA0, RA3 og RA4 som output, mens RA1 / RA2 som i / ps, ville du gøre dette ved at sende 00110 (06h). Tjek at bit 0 er mod højre som angivet her:

Port A Pin RA4 RA3 RA2 RA1 RA0

Bit nummer 4 3 2 1 0

Binær 0 0 1 1 0

Det samme gælder for TRISB.

PORTA og PORTB

For at aflevere en af ​​udgangsstifterne højt, tilbyder vi bare en '1' til henholdsvis bit i vores PORTA- eller PORTB-register. En identisk procedure kan også følges for TRISA- og TRISB-registre. Før vi går ind i vores første eksempelkodning, lad os bare forstå en kupon med flere registre, nemlig w og f.

W og F

W-registeret er et almindeligt register, der giver dig mulighed for at tildele enhver værdi efter eget valg. Så snart du tildeler W en størrelse, kan du fortsætte med at tilføje denne til en anden værdi eller blot flytte den. Med en anden værdi tildelt overskrives detaljerne simpelthen på W.

F-registeret videresender sit skriftlige materiale til et register. Vi ville kræve, at dette F-register tildeler en værdi over et register, kan være over STATUS- eller TRISA-registre, da disse ikke tillader os at placere værdierne direkte over dem. Et eksempel på et program

Lad os undersøge følgende eksempelkode, der viser os, hvordan ovenstående instruktion implementeres og også vil være vidne til nogle få af instruktionerne i kurset.

Lad os begynde med at rette Port A som beskrevet ovenfor.

Til dette er vi nødt til at skifte fra Bank 0 til Bank1, dette gøres ved at oprette STATUS-registeret på adresse 03h, bit 5 til 1.

BSF 03h, 5

BSF betyder bitsæt F. Vi bruger to tal efter denne instruktion - 03h, som er STATUS-registeradressen, og tallet 5, der svarer til bitnummeret.

Så hvad vi siger er 'Sæt bit 5 i adresse 03h til 1'.

Vi er nu i Bank 1.

MOVLW 00110b

Vi sætter den binære værdi 00110 (bogstavet b betyder, at tallet er i binært) i vores generelle register W. Jeg kunne selvfølgelig have gjort dette i hex, i hvilket tilfælde vores instruktion ville være:

MOVLW 06h

Enten fungerer. MOVLW betyder 'Flyt bogstavelig værdi ind i W', hvilket på engelsk betyder at placere den følgende værdi direkte i W-registeret.

Nu skal vi sætte denne værdi i vores TRISA-register for at opsætte porten:

MOVWF 85h

Denne instruktion angiver 'Flyt indholdet af W til registeradressen, der følger', i dette tilfælde henviser adressen til TRISA.

Vores TRISA-register bærer på dette tidspunkt figur 00110 eller præsenteres grafisk:

Port A Pin RA4 RA3 RA2 RA1 RA0

Binær 0 0 1 1 0

Input / Output O O I I O

Så nu har vi vores Port A-ben, vi skal vende tilbage til Bank 0 for at justere en af ​​oplysningerne.

BCF 03h, 5

Denne instruktion udfører omvendt af BSF. Det indebærer 'Bit Clear F'. Det et par tal, der svarer til, er registerets adresse, her STATUS-registeret, såvel som bitfiguren, i dette tilfælde bit fem. Hvad vi nøjagtigt har afsluttet på nuværende tidspunkt er, defineret bit fem på vores

STATUS registrer til 0

Vi er på dette tidspunkt vendt tilbage i bank 0.
Følgende er koden alt sammen i en blok:

BSF 03h, 5 Gå til Bank 1
MOVLW 06h Sæt 00110 i W
MOVWF 85 t Flyt 00110 til TRISA
BCF 03h, 5 Kom tilbage til Bank 0

Inden for den sidste instruktion bekræftede vi dig, hvordan du opretter IO-portstifterne på PIC for muligvis at blive input eller output.

Gennem dette kursus, lad mig hjælpe dig med at sende data til havnene.

Afsendelse af data til porte

I den efterfølgende vejledning skal vi gennemføre ved at blinke en LED til og fra, der består af en komplet programdetalje og et ligefrem kredsløbsdiagram, så du kan se PIC udføre præcis, hvad vi forventer.

Forsøg ikke at sammensætte og programmere din PIC med nedenstående resultater, da de kun er illustrationer. Oprindeligt etablerer vi Port A bit 2 som output:

Dette kunne genkendes fra den tidligere instruktion. Den eneste forskel kunne være. Vi har rettet hver bit af benene på A som output ved at levere 0 timer til tri-state-registeret. Så hvad nu skal han gøre er at tænde en LED.

Vi opnår dette ved at planlægge en af ​​stifterne (den med LED'en forbundet til den) højt. For at sige det anderledes anvender vi en '1' på stiften. Dette er nøjagtigt, hvordan det udføres (observer kommentarerne for en afklaring for hver linje):

Derfor, hvad nu vi har opnået, er at tænde lysdioden og derefter slukke en gang. Det, vi ønsker, er, at LED'en tændes efterfølgende kontinuerligt.

Vi opnår dette ved at få programmet til at vende tilbage til starten. Vi opnår dette ved oprindeligt at oprette et mærke i starten af ​​vores program og derefter informere programmet om at fortsætte derhen. Vi angiver et mærke ret ligetil.

Vi indtaster et udtryk, siger START, skriv derefter koden:

Som det fremgår, nævnte vi oprindeligt udtrykket 'Start' straks i starten af ​​programmet.

Dernæst i slutningen af ​​programmet nævnte vi tydeligt 'goto Start'. 'Goto' instruktionen udfører lige hvad den erklærer.

Dette program tænder og slukker konstant for LED'en, når vi tænder for kredsløbet og har tendens til at slukke, når vi fjerner elektricitet. Måske skulle vi kontrollere vores program igen:

Vi har helt sikkert udeladt kommentarerne, men vi kan stadig overholde instruktionerne og numrene.

Dette kan være lidt forvirrende senere, hvis du prøver at foretage fejlfinding af programmet, og mens du skriver koden, skal du huske alle adresserne.

Selvom kommentarerne muligvis placeres stadig, kan det blive lidt rodet. Dette vil kræve navngivning af numrene og kan opnås ved en yderligere instruktion: 'equ' Instruktionen 'equ' antyder, at nogle ting kan svare til en anden ting.

Det er muligvis ikke en instruktion til PIC, snarere til samleren. Denne instruktion letter tildeling af navn til en registeradresseplacering eller en konstant til et programmeringsudtryk.

Vi vil etablere et par konstanter til vores program og også være vidne til, hvor meget ligetil det læser programmet.

Siden nu har vi rettet de konstante værdier, vi kan fortsætte med at sætte dem op i vores program. De konstante værdier skal angives, inden de bruges.

Sørg derfor for altid at placere dem i starten af ​​programmet. Vi omskriver programmet med undtagelse af kommentarerne igen for at sammenligne den tidligere mærkning med den nyeste.

Måske er du i stand til at bemærke, at konstanterne muliggør en lettere forståelse af programmet, men vi er stadig uden kommentarer, dog ingen bekymringer, da vi endnu ikke er færdige.

Der kan være en mindre ulempe ved vores blinkende LED-program.
Hver instruktion har brug for 1 ursekvens for at afslutte. Hvis vi bruger en 4MHz krystal, kræver hver instruktion 1 / 4MHz eller 1uS til at afslutte.

Da vi kun har brugt fem instruktioner, vil lysdioden blive aktiveret og derefter slukket i 5uS. Dette kan være alt for hurtigt for folk at bemærke. Derudover ser det ud til, at LED'en er helt tændt.

Hvad vi i stedet skal udrette er at producere en hæmning mellem at tænde LED'en og slukke for LED'en. Teorien om inhiberingen er, at vi tæller ned fra en tidligere mængde, så når det bliver nul, holder vi op med at tælle.

Nulværdien betyder slutningen af ​​forsinkelsen, og vi fortsætter med at arbejde med vores proces igennem hele programmet. Derfor er det første, vi skal gøre, at bestemme en konstant, der skal bruges som vores tæller.

Lad os betegne dette konstante TÆL. Derefter skal vi bestemme, hvor vigtigt et tal der skal begynde at tælle fra. Det største tal, vi kunne inkludere, er helt sikkert 255 eller FFh i hex. Som jeg talte om i den tidligere tutorial, tildeler equ-instruktionen et udtryk til en registersituation.

Dette indebærer, at uanset hvilken mængde vi tildeler vores TÆLLE, ville det matche elementerne i et register. Hvis vi forsøger at betegne værdien FFh, får vi en fejl, når vi først har kompileret programmet.

Årsagen er placeringen FFh er, derfor kan vi ikke få adgang til den. Derfor, hvordan skal vi udpege et ægte nummer? Bestemt vil det kræve en lille mængde lateral overvejelse.

Hvis vi f.eks. Udpeger vores TÆLLING til adressen 08h, vil dette indikere en grundlæggende målregistreringsdestination. Som standard er de uberørte områder indstillet til FFh. Derfor, hvis COUNT fører til 08h, vil du støde på værdien af ​​FFh, mens vi først tænder. Ikke desto mindre, jeg dig, hvordan kan vi fastsætte TÆLLE til et andet nummer ?, alt hvad vi anvender er at 'flytte' først en værdiansættelse til denne destination.

Antag som illustration, at vi ønskede, at COUNT skulle have en værdi på 85h, vi kan ikke nævne COUNT equ 85h, da det er placeringen af ​​vores tre-statslige register for havn A. Præcis hvad vi opnår er følgende: movlw 85hFirst put værdien af ​​85 timer i W-registeret movwf 08h

Flyt det nu til vores 08h-register. Efterfølgende, hvis vi udtrykker COUNT svarer til 08h, ville COUNT matche værdien 85h. Delikat, er det ikke! Derfor bestemmer vi oprindeligt vores konstant: COUNT equ 08h Herefter skal vi reducere dette COUNT med en, indtil den bliver nul.

Det forekommer ganske enkelt, at der findes en instruktion, der er designet til at opnå dette for os ved at bruge en 'goto' og et tag.

Den instruktion, vi skal anvende, er: DECFSZ COUNT, 1 Denne instruktion siger 'Reducer registeret (her er det COUNT) med antallet, der sporer kommaet. Hvis vi når nul, skal du hoppe to pletter fremad. ”Lad os først finde det i aktion, inden vi placerer det i vores kurs.

Det, vi har udført, er oprindeligt at etablere vores konstante TÆLLING til 255. Det efterfølgende segment placerer et mærke, kaldet LABEL tæt på vores decfsz-instruktion.

Decfsz COUNT, 1 reducerer værdien af ​​COUNT med en og bevarer slutresultatet lige til COUNT. Desuden bekræfter det at kontrollere, om COUNT har en værdi på 0.

Hvis det ikke gør det, udløser det i så fald programmet til at skifte til den efterfølgende linje. Nu har vi en 'goto' erklæring, der leverer os tilbage til vores decfsz instruktion.

Hvis værdien af ​​COUNT fungerer ens, resulterer decfsz-instruktionen i vores program til at springe 2 pletter fremad og sendes til det sted, hvor vi har hævdet 'Fortsæt her'.

Derfor, da du kan observere, har vi fået programmet til at sidde på et sted i en forudbestemt tid, før du fortsætter. Dette kunne kaldes en forsinkelsessløjfe.

Forståelse af forsinkelsessløjfer

Hvis vi har brug for en større forsinkelse, kan vi forfølge den ene løkke ved den næste. De ekstra sløjfer, jo længere forsinkelsen. Lad os mindst to, forudsat at vi vil observere LED-blitzen. Vi placerer disse forsinkelsessløjfer i vores program og opnår ved at gøre det til et ægte program ved at introducere kommentarer:

Det er muligt at kompilere dette program, efter hvilket program PIC. Sørg naturligvis for, at du forsøger kredsløbet for at kontrollere, om det virkelig fungerer. Følgende er et kredsløbsdiagram, som du skal konstruere, så snart du har programmeret PIC.


Godt gået, du kunne faktisk have komponeret dit første PIC-program samt konstrueret et kredsløb til at blinke en LED til og fra. Indtil nu, i tilfælde af at du har fulgt disse kurser, har du måske lært et samlet antal af syv instruktioner ud af 35, men uden tvivl indtil videre styrer du muligvis I / O-porte!

Vil du forsøge at ændre forsinkelsessløjferne for at gøre LED-flashen hurtigere - hvad synes den minimale værdi af COUNT for i det væsentlige at se LED-flashen? Eller måske vil du medtage en tredje eller supplerende forsinkelsessløjfer efter den indledende for at stabilisere LED'en ned. en unik konstant for hver forsinkelsessløjfe.

Du kan muligvis så faktisk fikle med dine forsinkelsessløjfer for at gengive LED-flashen med en bestemt hastighed, for eksempel efter et sekund. Lad os inden for den næste instruktion se, hvordan vi er i stand til at udnytte noget kendt som en subrutine til at opretholde programmet kompakt og grundlæggende. En subrutine er en integreret del af kode eller program, der kan blive omtalt som, og hvornår du muligvis har brug for det. Underrutiner anvendes i tilfælde, hvor du ofte udfører den samme funktion.

Hvad er subrutiner

Fordelene ved at anvende en subrutine er, at det sandsynligvis vil være enklere at ændre værdien en gang inde i en subrutine i stedet for f.eks. Ti gange hele dit program, såvel som det bidrager meget til at mindske niveauet af hukommelse, som dit program bruger inde i PIC. Vi tjekker en underrutine:

Oprindeligt er vi nødt til at give vores underrutine en betegnelse, og i denne situation har vi valgt RUTINE. Vi skriver derefter den kode, som vi gerne vil udføre som normalt. Derfor har vi valgt forsinkelsen i vores blinkende ledede program. Endelig afslutter vi underrutinen ved at indtaste RETURN-instruktionen.

For at starte subrutinen hvor som helst i vores program, skriver vi hurtigt instruktionen CALL og derefter betegnelsen subrutine.

Vi vil overveje dette lidt mere dybt. Når vi først er kommet til den del af vores program, der CALL xxx, hvor xxx er navnet på vores underrutine, springer programmet til et hvilket som helst sted, hvor subrutinen xxx er installeret. Instruktionerne inde i subrutinen udføres.

Hver gang instruktionen RETURN er gennemført, springer programmet tilbage til vores hovedprogram til instruktionen efter vores CALL xxx instruktion.

Det er muligt at kalde den samme subrutine flere gange, som du ønsker, hvilket forklarer, hvorfor brugen af ​​subrutiner mindsker den generelle varighed af vores program.

Ikke desto mindre er der et par faktorer, du bør vide om. Oprindeligt, som med vores hovedprogram, skal alle specifikke konstanter anerkendes, før du kan bruge dem.

Disse kan muligvis anerkendes i selve underrutinen eller direkte i starten af ​​hovedprogrammet. Jeg foreslår dig, at du anerkender alt i begyndelsen af ​​dit hovedprogram, siden du anerkender, at tingene er i en identisk position. Dernæst skal man sørge for, at hovedprogrammet springer over subrutinen.

Hvad jeg antyder med dette er, hvis du placerer subrutinen direkte ved afslutningen af ​​dit primære program, undtagen hvis du bruger en 'Goto' -erklæring til at springe væk fra, hvor subrutinen er, vil programmet fortsætte og implementere subrutinen uanset om du kræve det til eller på anden måde.

PIC skelner ikke mellem en subrutine og hovedprogrammet. Vi vil tjekke vores blinkende ledede program, men denne gang skal vi bruge en subrutine til forsinkelsessløjfen. Ideelt set vil du opdage, hvor meget mindre kompliceret programmet ser ud, såvel som du måske finder ud af, hvordan subrutinen gælder praktisk.

Til sidst kan du se, at ved at bruge en underrutine til vores forsinkelsessløjfe, har vi muligvis mindsket programmets dimensioner.

Hver gang vi ønsker en forsinkelse, muligvis når lysdioden er tændt eller slukket, kalder vi grundlæggende forsinkelsen underrutine. Ved afslutningen af ​​subrutinen fører programmet tilbage til linjen efter vores 'Call' instruktion. I illustrationen ovenfor tænder vi LED'en.

Vi kontakter derefter subrutinen. Programmet kommer derefter tilbage, så vi er i stand til at slukke lysdioden. Vi kalder subrutinen igen, bare hvis subrutinen måske er afsluttet, kommer programmet tilbage, og den efterfølgende instruktion, det genkender, er 'goto Start'. For alle, der kan være fascinerede, var vores første program 120 byte langt.

Ved hjælp af subrutinen kunne vi reducere vores programstørrelse ned til 103 byte. Dette kunne ikke lyde for at være så fantastisk, men i betragtning af det faktum, at vi kun har 1024 bytes samlet inde i PIC, har hvert lille beløb fordel.

Lad os inden for den næste instruktion tjekke læsning fra havnene.

Indtil videre har vi komponeret til Port A, så vi er i stand til at tænde og slukke for en LED. På dette tidspunkt vil vi se, hvordan vi læser I / O-benene på portene.

Læsning af input / output-porte

Dette er nøjagtigt for at sikre, at vi er i stand til at forbinde et eksternt kredsløb og påvirke eventuelle specifikke output, det tilbyder.

Hvis du vil huske fra vores tidligere kurser, hvis du ønsker at etablere I / O-porte, var vi nødt til at hoppe fra Bank 0 til Bank 1. Vi opnår det oprindeligt:

På dette tidspunkt har vi fast bit 0 af Port A til input. vi skal nu undersøge, om stiften er høj eller lav. For at opnå dette kan man kun bruge en af ​​to instruktioner:

BTFSC og BTFSS.

BTFSC-instruktionen betyder 'Udfør en bit-test i registret såvel som den bit, vi udpeger.

Hvis det er et 0, udelader vi i så fald den efterfølgende instruktion '. BTFSS indebærer 'Lav en bit test i registret og den bit, vi opretter. Hvis det er indstillet til en 1, omgår vi den efterfølgende instruktion.

Hvilken vi bruger, bestemmes af præcist, hvordan vi ønsker, at vores program skal reagere, mens vi studerer input. Som en illustration, hvis vi bare venter på, at input skal være en 1, kan vi muligvis bruge BTFSS-instruktionen på følgende måde:

Kode her:

BTFSS PortA, 0 Gå til start Fortsæt her:
:

Programmet skifter bare til 'Fortsæt her' forudsat at bit 0 på PortA er planlagt til 1.

Vi vil i øjeblikket skrive et program, der kan bede en LED med en hastighed, men hvis en switch er begrænset, vil den blinke LED to gange så langsommere.

Det er muligt måske at udøve dette program på egen hånd, stadig Vi har indarbejdet listen på en eller anden måde.

Du kan prøve og oprette hele programmet for at kontrollere, om du har forstået principperne. Vi bruger det ækvivalente kredsløb som før med inkluderingen af ​​en switch tilsluttet RA0 af PIC og den positive skinne af vores forsyning.

Det, vi har opnået her, er at tænde lysdioden. Jeg bestemmer efterfølgende, om kontakten er lukket.

Hvis det er begrænset, opretter jeg forbindelse til vores forsinkelsesundervisning. Dette giver os den tilsvarende forsinkelse som før, men vi er på dette tidspunkt i kontakt med den to gange.

Den samme ting gælder, når LED'en er slukket. Hvis kontakten ikke er lukket, har vi vores tidligere optaget til og fra-perioder.

Har du fulgt disse lektioner fra starten, forsøger du måske at forstå, at du i øjeblikket har opdaget ti af de 35 instruktioner til PIC 16F84! Og hver eneste bit af disse læres kun ved at tænde og slukke for en LED.

Indtil nu har vi komponeret PIC blink en LED til og fra.

Derefter var vi i stand til med vores PIC ved at inkludere en switch, og derfor varierede flashhastigheden.

Brug af hukommelsesplads effektivt

Det eneste problem er, at programmet er ret langt og ret ineffektivt hukommelsesplads. Det virkede ok, mens jeg inkluderede kommandoerne for første gang, men der burde være en lettere måde at udføre den på. Positivt er der, vi analyserer, hvordan vi bogstaveligt talt tænder og slukker for lysdioden.

movlw 02hmovwf PORTAmovlw 00hmovlw PORTA

Først fyldte vi vores w-register med 02h, derefter overførte det det til vores PortA-register for at tænde lysdioden. For at slukke for det pakket vi w med 00 timer, hvorefter det flyttede det til vores PortA-register.

Ind imellem alle disse rutiner blev vi tvunget til at komme i kontakt med en subrutine for at sikre, at vi kunne observere LED blinker.

Derfor var vi nødt til at overføre to sæt info et par gange (en gang i w-registret og derefter til PORTA) samt ringe til en subrutine to gange (en gang til og derefter en gang til off). Hvordan kunne vi således opnå dette med ekstra effektivitet? Meget simpelt.

Vi bruger en anden instruktion kendt som XORF. XORF-instruktionen fungerer som en eksklusiv ELLER-funktion i det register, som vi angiver med de oplysninger, vi leverer. Jeg tror, ​​jeg er nødt til at afklare, hvad der i verden er en eksklusiv ELLER, før vi fortsætter. Hvis vi har to indgange og en udgang, kan indgangen kun være 1, hvis og så længe de to indgange er forskellige. Mens de er de samme, vil output sandsynligvis være 0. Følgende er en sandhedstabel for enkeltpersoner, der vælger at tjekke disse:

A B F0 0 00 1 11 0 11 1 0

Vi vil på dette tidspunkt tjekke, hvad der foregår, hvis vi gengiver B ligesom vores tidligere output og blot ændrer værdien af ​​A:

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

Hvis vi opretholder værdien af ​​A samme som 1, og vi eksklusiv ELLER den med output, skiftes output. Hvis du ikke kan lægge mærke til dette fra sandhedstabellen, kan du se det benytte binært:

0 Nuværende output
EX-ELLER med 1 1 Ny output
EX-ELLER Med 1 0 ny output

Måske kan du finde ud af, at ved eksklusiv ORing af output med 1, skifter vi nu output fra 0 til 1 til 0.
Derfor skal vi kun bruge et par sætninger for at tænde og slukke for vores LED:

MOVLW 02h
XORWF-DØR, 1

Hvad vi netop vil opnå er at tilføje vores w-register med 02h. Vi er i så fald eksklusivt ELLER bestiller dette nummer uanset hvad der er på vores PortA. Hvis bit 1 er en 1, ændres den til en 0. Hvis bit 1 er en 0, ændres den til en 1. Lad os undersøge denne kode en eller to gange for at vise, hvordan den kører binært:

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

Vi behøver faktisk ikke indlæse den samme værdi i vores w-register hver gang, derfor er det muligt at udføre dette en gang i starten og blot springe tilbage til vores skiftekommando. Derudover skal vi ikke fastsætte en værdi i vores PortA-register. Grunden? Sikkert, da det i tilfælde af tænding er en 1, kan vi let skifte det. Jeg, alternativt en 0 på power up, vi ville endda nu skifte det.

Derfor vil du gerne se vores nyoprettede kode. Den første repræsenterer vores blinkende LED-kode, mens den anden viser den med tilføjelse af kontakten:

Lad os ønske, at du kan finde ud af, at vi simpelthen ved at bruge en nem instruktion har skåret ned på skalaen for vores program. Sandheden er, for at vise, hvor meget vi kunne reducere vores programmer med, har vi demonstreret de to programmer, netop hvad der blev sammensat, og deres dimensioner i nedenstående tabel:

Program Alter Dimensions (Bytes)
Blinkende LED Original 120
Blinkende LED-underrutine tilføjet 103
Blinkende LED XOR-funktion brugt 91
LED med switch original 132
LED med switch XOR-funktion brugt 124.

Derfor har vi ikke bare opdaget et par nye instruktioner, vi har desuden reduceret størrelsen på vores scripting!

Nedenfor analyserer vi, hvordan du kan vrikke individuelle bits, udføre visse enkle aritmetikker samt datatabeller.

Logiske ledere

Inden for den sidste tutorial præsenterede jeg Exclusive OR-operationen. ExOR-funktionen forstås som en logisk operator.

Inden for denne tutorial vil jeg oplyse de yderligere logiske operatorer, som PIC fremmer. Der vil ikke være nogen form for tilfælde i punktprogrammer, men vi lærer nemme metoder til at bruge operatørerne ved at anvende små kodeområder.

OG Funktionen AND analyserer grundlæggende to bits og leverer en 1, om de er ens, og en 0, hvis de er karakteristiske. For eksempel, hvis vi nævnte 1 OG 1, er resultatet 1, mens hvis vi erklærede 1 OG 0, ville konsekvensen være 0.

Det er overflødigt at sige, at vi også er i stand til at evaluere ord, såvel som hele AND-funktionen opnår, er at gennemgå de to termer lidt efter lidt. Eksemplet nedenfor viser, at to 8-bit ord bliver ANDed sammen med produktet:

11001011
OG 10110011
Lig med 10000011

Jeg håber, du er enig, resultatet vil simpelthen have en 1, hver gang 2 1'ere hånd i hånd med hinanden i et par ord. Vi er i stand til at bruge AND-funktionen til at verificere portene, for eksempel.

Hvis vi kontrollerer et par I / O-ben, der er knyttet til et kredsløb, og vi skal holde øje med en bestemt situation, hvor kun få af benene er høje, i så fald er vi i stand til stort set at læse port, hvorefter OG resultatet med den betingelse, vi har undersøgt for, identisk med ovenstående forekomst.

PIC giver os to ingredienser til AND.
De er ANDLW og ANDWF. ANDLW tillader os at udføre en AND-funktion med detaljerne i W-registret og et beløb, som vi fastsætter.

Syntaksen er: ANDLW hvor er nøjagtigt hvad vi skal OG indholdet af W med.

Konsekvensen af ​​AND-funktionen lagres direkte i W-registeret.
ANDWF tillader os at udføre en AND-funktion i W-registeret og et andet register, for eksempel en PORT. Syntaksen er: ANDWF, d i hvilket register er vi begejstrede, f.eks. PORTA, og d viser PIC, hvor du skal placere resultatet. Hvis d = 0, placeres resultatet i W-registeret, og af d = 1 gemmes slutresultatet i det register, vi har angivet. De to dele af koden nedenfor viser et godt eksempel på hver AND-funktion.

Initialen undersøger status for PORTA, hvor vi skal kontrollere, om input er 1100. Vi kan placere resultatet tilbage i W-registeret

movlw 1100
ANDWF 05h, 0Den anden illustration bekræfter muligvis indholdet af W-registeret:
ANDLW 1100

ELLER

Vi har nu opdaget en ELLER-funktion, for at være præcis XOR. Dette udvikler sig til en 1, hvis to bits ikke er ens, men er forskellige. Du kan finde en anden ELLER-funktion kaldet IOR, som er den inklusive ELLER. Denne funktion genererer en 1, hvis begge bit er en 1, men hvis hver bit er 1. Nedenfor er en klar sandhedstabel, der illustrerer dette:

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

Hvad er aritmetiske operatører

TILFØJE

Denne funktion udfører, hvad der normalt kræves. Det bidrager med to tal! I tilfælde af at konsekvensen af ​​tilføjelse af de to figurer overstiger 8 bit, vil der sandsynligvis blive sat et CARRY-flag. CARRY-flaget er placeret på adresse 03h bit 0.

Når denne bit er planlagt, overgik de to figurer 8 bit. Når det er et 0, er konsekvensen i så fald placeret inden for 8 bit. Som før leverer PIC os to ADD-stilarter, specifikt ADDLW og ADDWF. Som du måske har antaget, er dette ligesom ovenstående funktion. ADDLW tilbyder indholdet af W-registeret, som vi foreskriver. Syntaksen er: ADDLW ADDWF tilføj indholdet af W-registeret og et andet register, som vi udpeger.

Syntaksen er: ADDWF, d er hvor

SUB

På dette tidspunkt antager jeg, at du ikke kan antage, hvad denne funktion udfører! Faktisk har du mistanke om det, denne funktion
trækker en bit fra en anden. Igen giver PIC os to smag: SUBLW og SUBWF. Syntaksen er nøjagtigt den samme som for ADD-funktionen, bortset fra åbenbart skriver du SUB i stedet for ADD!

Forøgelse Hvis vi ønsker at inkludere 1 til et nummer i PIC, kunne vi absolut bruge ADD-funktionen og bruge nummer et. ~ Vanskeligheden med dette er, at vi først skal placere figuren i W-registeret og derefter bruge ADDLW 1-kontrol til at øge den. Hvis vi ønskede at inkludere 1 i et register, kan det stadig være værre. Vi skal først placere nummer 1 i W-registeret, derefter bruge ADDWF, 1. Derfor, for eksempel, at inkludere 1 til placering 0C, siger, at vi bliver nødt til at have følgende del af scriptet:

movlw 01
addwf 0c, 1

Der findes en lettere metode til at gennemføre dette. Vi kan udøve kommandoen INCF. Syntaksen er: INCF, d hvor, er det register eller sted, som vi er bekymret for, og d viser PIC, hvor du skal placere resultatet. I tilfælde af d = 0 er resultatet inden for W-registeret, og i tilfælde af d = 1 er konsekvensen angivet i det register, vi har angivet.

Ved at bruge denne individuelle instruktion er vi i stand til faktisk halvtreds procent af kodningen. Hvis vi ønskede, at resultatet blev gendannet i W-registeret, i det tilfælde ved anvendelse af ovenstående forekomst, måtte vi muligvis medtage en ekstra kommando for at skifte elementerne af 0C tilbage til W-registeret, hvorefter 0C-registret placeres tilbage til ingen ligegyldigt hvad det var.

Der findes kommandoen til trin. Det er INCFSZ. Denne kommando kan forøge det register, som vi angiver, men hvis vi registret er lig med 0 efter inkrementet (det vil ske, mens vi inkluderer 1 til 127), efter at PIC sandsynligvis vil passere den efterfølgende instruktion. Den del af koden nedenfor afspejler dette:

Loop incfsz 0C
Gå til løkke
:
:
Resten af ​​programmet.

I ovenstående del af koden øges 0C med 1. Vi ejer derefter en instruktion, der informerer PIC om at vende tilbage til vores tag, der hedder Loop, og forøge 0C med 1 igen. Dette fortsætter indtil 0C er lig med 127. I denne situation, når vi øger 0C med 1, vil 0C nu matche 0. Vores INCFSZ-instruktion kunne meget vel informere PIC om at udelade den efterfølgende instruktion, som i dette tilfælde er goto-erklæringen, derfor fortsætter PIC med den resterende del af programmet.

Nedgang

Vi har nu diskuteret nedbrydningsfunktionen i tidligere træning, derfor vil jeg ikke revidere den længere.

Supplement

Den sidste instruktion i denne diskussion ville vende hver eneste bit i det register, som vi angiver. Syntaksen er: COMF, d hvor

Forståelse af bitoperationer

Dette kan f.eks. Bruges til hurtigt at bytte stifter på en port fra output til input og så videre. Bitfunktioner tillader os at forme en enkelt bit i et udtryk. De tillader os at fortsætte, indstille og slippe af med enkelte bits i registre eller tal, som vi angiver.

Ved afslutningen af ​​dette kursus vil vi afsløre et program designet til at skabe et sæt sekventeringslys, der fortsætter fremad og derefter omvendt. Vi observerede dette opnået tidligere, da vi undersøgte den eksklusive ELLER-funktion, hvor vi eksklusivt ORede portene med et udtryk. Vi har indtil nu bemærket et par bitfunktioner, når vi opretter porte på PIC, og

Lad mig gentage deres anvendelse her.

BCF

Denne instruktion sletter af en smule, som vi fastsætter i et register, som vi udpeger. Syntaksen
er:
BCF,

Vi har brugt dette tidligere til at ændre fra side 1 til side 0 ved at fjerne en smule i STATUS-registeret. Vi er i stand til på samme måde at bruge den til at rette en smule til 0 i ethvert andet register / sted. For eksempel, hvis vi ønsker at indstille 3. bit i 11001101 gemt i sektion 0C til 0, kan vi muligvis
indsæt:

BCF 0C, 03

BSF

Denne instruktion vil rette enhver bit, vi fastsætter, til 1 i ethvert register, som vi angiver. Vi benyttede dette tidligere til at gå fra side 0 til side 1. Syntaksen er: BSF ,, og bruges i nøjagtig samme metode som BCF ovenfor.

BTFSC Indtil nu kunne vi indstille eller rydde lidt i et register. Forestil dig dog, om vi dybest set skal kontrollere, om en bit er en 1 eller en 0 i et register?

Det er helt sikkert muligt at bruge BTFSC. Den angiver bit testregister F, og spring over, hvis det er klart. Denne instruktion skal analysere den bit, vi udpeger i registret. Hvis biten er 0, vil instruktionen informere PIC om at passere den efterfølgende instruktion.

Vi kan muligvis bruge denne instruktion, hvis vi ønsker at kontrollere et flag, for eksempel bæreflagget. Dette sparer os for at skulle læse STATUS-registeret og søge efter de enkelte bits for at lære, hvilke flag der er rettet. 29 Hvis vi f.eks. Ville kontrollere, om Carry-flagget var sat til 1, efter at vi havde tilføjet 2 figurer, kunne vi skrive følgende:

BTFSC 03h, 0
fortsæt her hvis indstillet til 1
eller her, hvis indstillet til 0

Hvis bitens status er 1, ville instruktionen efter BTFSC være afsluttet. Hvis det er sat til 0, springes den efterfølgende instruktion i så fald over. Den følgende del af koden viser, hvor den kan anvendes:

Sløjfe:
:
:
BTFSC 03,0
Gå til løkke

I ovenstående kode vil PIC simpelthen komme ud af sløjfen, hvis bit 0 i STATUS-registret (eller Carry-flag) er defineret til 0. Ellers vil goto-kommandoen blive udført.

BTFSS

Denne instruktion angiver bit testregister F, og spring over hvis indstillet. Dette kan sammenlignes med BTFSC-instruktionen, bortset fra at PIC ville udelade den efterfølgende instruktion, hvis den bit, vi har evalueret, er indstillet til 1 i stedet for 0.

CLRF

Denne instruktion vil rette alle detaljerne i et register til 0. Syntaksen er:

CLRF
Vi anvendte dette tidligere for at indstille output fra havnene til 0 ved at anvende CLRF 85h. Vi anvendte det desuden til at fastgøre porte til at inkludere alle ben til output ved at bruge CLRF
05 timer

CLRW

Dette kan ligne CLRF-instruktionen, bortset fra at rydde W-registret. Syntaksen er ret simpel:

CLRW

RLF og RRF

Disse retninger vil transportere lidt i et register et enkelt spor til venstre (RLF) eller højre (RRF) i et register. For eksempel, hvis vi havde brug for 00000001 og vi ansatte RLF, i så fald kan vi have 00000010. På dette tidspunkt, hvad foregår der, hvis der er 10000000 og anvendte RLF-instruktionen? Sikkert ville 1 være placeret i bæreflagget. Hvis vi anvendte RLF-instruktionen igen, ville 1 igen dukke op i starten. Det samme forekommer dog i modsat retning for RRF-instruktionen. Tilfældet i punktet nedenfor viser dette for RLF-instruktionen, hvor Vi kan se de 8 bits i et register såvel som 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 ser nu et eksempel på en kode, som man kan kompilere og køre. Det ville generere et sekventeringslys, der begynder ved PortA bit 0, går til PortB bit 8 og
derefter vender tilbage.
Tilslut lysdioder til hver af portstifterne. Vi har noget af det
procedurer påpeget i denne vejledning.

TIME EQU 9FH Variabel til forsinkelsessløjfen.
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 Side vælg register.
COUNT1 EQU 0CH loop-register.
COUNT2 EQU 0DH Loop-register.

BSF STATUS, 5 Gå til side 1
MOVLW 00H og opsæt
MOVWF TRISB både porte A og B
MOVLW 00H til output,
MOVWF TRISA vend derefter tilbage til
BCF STATUS, 5 side 0.
MOVLW 00H Ryd port A.
MOVWF-DØR

Start af hovedprogram

RUNMOVLW
01H Indstil den første bitMOVWF
PORTB på Port B.CALL
FORSINK Vent et stykke tid OPKALD
FORSINKE
Flyt biten på Port B til venstre, og sæt derefter pause.RLF
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINK
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINK
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINK
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINK
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINK
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINK
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINK
PORTB, 1 Denne bevæger bit ind i bæreflagget
Gå nu videre til Port A, og flyt biten til venstre.RLF
PORTA, 1 Dette flytter bit fra nul-flag til PortACALL
DELAYCALL DELAYRLF
DØR, 1OPKALD
FORSINKEL OPKALD
FORSINK
DØR, 1OPKALD
FORSINKEL OPKALD
FORSINK
DØR, 1OPKALD
FORSINKEL OPKALD
FORSINKE
Flyt bit tilbage på Port ARRF
DØR, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
DØR, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
DØR, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
PORTA, 1 Dette flytter biten ind i nulflagget Flyt nu biten
tilbage på Port BRRF
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
PORTB, 1OPKALD
DELAYCALL DELAYRRF
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
PORTB, 1OPKALD
FORSINKEL OPKALD
FORSINKELSE
PORTB, 1OPKALD
FORSINKEL OPKALD
DELAY Nu er vi tilbage, hvor vi startede, GOTO
KØR, lad os gå igen.

Der findes en god mulighed i træningssættet, der giver dig mulighed for at bruge en datatabel.

En datatabel er kun en liste over datacitater, hvor alt er set over baseret på et par overvejelser.
For eksempel kan du have et kredsløb, der bruger en PIC, der tæller antallet af forekomster, hvor en indgangsstift bliver høj på 1 sekund. Derefter kan du udstille nummeret på et 7-segment display.

Så snart timingen er lanceret, begynder PIC at tælle antallet af lejligheder, pinen bliver høj. Efter 1 sekund besøger den tabellen og kigger op på dataene, den skal vise nummeret på displayet, der symboliserer antallet af situationer, pinen blev høj. Dette kan være gavnligt, da vi ikke bestemmer, hvad tallet kan være, før PIC har gennemført sit skøn.

Ved at bruge en tabel er vi i stand til at lade PIC bestemme, hvilken figur der skal skildres. På dette tidspunkt, inden jeg fortsætter med at vise dig, hvordan datatabellen fungerer, er jeg muligvis nødt til at fortælle dig, at PIC opretholder stien til, hvor i programmet det er, mens programmet kører.

Det letter for dem, der har udført en vis programmering i BASIC. Ellers vær ikke bekymret, du vil måske fortsætte med at lære om teorien. Forestil dig, at der er et BASIC-program svarende til det nedenfor:

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

Programmet begynder ved linje 10. Så snart K er planlagt til 0, fortsætter det videre til linje 11. Når vi har inkluderet 1 til K, fortsætter vi derefter til linje 12.

På dette tidspunkt kan vi være nysgerrige, hvis K er højere end 10. Hvis det er tilfældet, kører vi næste til linje 20, ellers vender vi tilbage til linje 11.

Linje 20 dokumenterer K, og linje 21 afslutter programmet. BASIC anvender linjestatistikker for at hjælpe programmøren med at registrere, hvor problemer er, da etiketter ikke er autoriserede. PIC bruger etiketter til at flygte mellem destinationer - eller kan det virkelig?

Vi bruger etiketterne for at sikre, at vi er opmærksomme på, hvor problemer er, samt for at sikre, at vi er i stand til at informere PIC på en enkel måde, hvor vi skal søge.

Præcis hvad der sker er PIC drager fordel af en indre linjetæller kaldet Program Counter. Programtælleren (forkortet PC) -sporet over hukommelsesdestinationen, hvor den nuværende instruktion er.

Hver gang vi informerer PIC'en om at besøge en valgt etiket, forstår den hukommelsesstedet og udvider derfor pc'en, indtil den ser den hukommelsesdestination. Dette er nøjagtigt den samme metode, som vi tjekker BASIC-programmet ovenfor. Nedenfor er et kodesegment med hukommelsesrum eller pc'ens emner ved siden af ​​hver instruktion:

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

I demonstrationen ovenfor har vi rettet pc'en til 0000. På denne har vi instruktionen movlw 03. Når PIC har implementeret disse data, forøger den pc'en for at den efterfølgende instruktion scannes. På dette tidspunkt ser PIC movwf 0C. PC'en er steget endnu en gang.

Nu afviser PIC decfsc 0C. Hvis detaljerne i 0C ikke er 0, i så fald forøges pc'en med 1, såvel som den følgende instruktion, goto Loop, informerer pc'en om at vende tilbage til position 0003, som der er den nævnte loop. Hvis detaljerne i 0C er 0, rådes pc'en til at øge med 2, sæt simpelthen ud af den efterfølgende instruktion.

Forståelse af datatabeller

Dette placerer pc'en på position 0004, hvor programmet afsluttes. Destinationerne fastlægges af samleren, og vi burde generelt ikke bekymre os om, hvad pc'en opnår. Indtil vi finder behovet for at bringe det under kontrol ligesom mens vi gør, når vi bruger datatabeller. Den mest bekvemme måde at beskrive, hvordan en datatabel fungerer, er at begynde med en illustration.

PC ækv. 02
movlw 03
opkaldstabel
:
tabel addwf pc
ret 01
ret 02
ret 03
ret 04
ret 05
igen 06
igen 07
Vend tilbage

Den indledende instruktion tildeler etiketten pc med adressen på programtælleren (02h). Vi er snart efter at sætte værdien af ​​03h i w-registeret. Vi kommunikerer derefter til bordet. Den forreste linje i subrutintabellen forøger detaljerne i W-registret (03h) til programtælleren.

Dette udløser programtælleren til at hæve med 3, eller for at sige det på en anden måde, stimulerer programtælleren til at gå ned 3 linjer. Mens tælleren ankommer 3 linjer ned, genkender PIC instruktionen retlw. Denne kommando sender den efterfølgende værdi til W-registeret, hvorefter den kommer tilbage fra underrutinen. RETLW betyder dybest set Return, Literal til W.

Se Jeg placerede et komma efter ordet Return. Da vi er i en subrutine, kræver vi en returinstruktion for at overfladen af ​​den. Derfor RET i instruktionen. Efter RETLW-instruktionen er der et tal, og det er præcis, hvad der sættes i W-registeret.

I dette tilfælde er det figur 3. Vi kunne angive en hvilken som helst størrelse til W-registeret, så længe denne figur er kombineret med Programtælleren i tabelundervisningen, vil vi finde en retlw-instruktion. I ovenstående illustration indebærer dette, at vi er i stand til at have et hvilket som helst nummer fra 1 til 7. Hvis vi går forbi subrutinen, kan vi muligvis afslutte udførelsen af ​​en ekstra del af programmet. Af denne grund er det normalt et smart træk at placere datatabellen nøjagtigt mod slutningen af ​​PIC-programmet, så hvis vi i så fald overskrid, når vi alligevel til programmets afslutning.

Emnet for afbrydelser kan godt være det længste og sværeste at gennemgå.

Du kan ikke finde nogen ukompliceret metode til at specificere afbrydelser, men med lidt held mod slutningen af ​​denne del kan du muligvis anvende afbrydelser i dine egne programmer.
Vi har opdelt sektionen i 2 faser. Det er for at muliggøre adskillelse af emnet i sektioner, også for at give dig en praktisk plit op til nem forståelse.

Hvad er en afbrydelse? Som af udtrykket indikerer, er en afbrydelse helt sikkert en teknik eller et signal, der forhindrer en mikroprocessor / mikrocontroller i, hvad som helst den udfører, at noget andet kan ske.

Tillad mig at give dig en daglig illustration. Tror du slapper af i dit eget hjem og snakker med en anden person. Pludselig lyder telefonen.

Du holder op med at tale og griber telefonen for at tale med den, der ringer op. Når du har haft din telefoninteraktion, beslutter du at vende tilbage til at tale med den enkelte, inden telefonen ringede. Det er muligt at overveje den vigtigste rutine, mens du chatter med nogen, telefonens ringning medfører forstyrrelse af din samtale, og pause i rutinen er metoden til at tale i telefonen.

Mens telefondiskussionen slutter, går du tilbage til din primære rutine for chatter. Denne illustration er netop, hvordan en afbryder en processor for at tage handling.

Det primære program kører og udfører en bestemt funktion i et kredsløb, men når en afbrydelse finder sted, stopper det primære program, mens en anden rutine udføres. rutine slutter, bevæger processoren sig tilbage til den primære rutine som før.

Forståelse for afbrydelser

PIC har 4 kilder til afbrydelse. De kunne opdeles i et par grupper. To er kilder til afbrydelser, som kan bruges udad til PIC, mens de to andre er indre processer. Lad mig afklare de to eksterne typer her. De to andre vil blive beskrevet i forskellige selvstudier, når vi når frem til timere og lagrer data.

Hvis du tjekker pin-out på PIC, vil du bemærke, at pin 6 er RB0 / INT. På dette tidspunkt er RB0 tydeligvis Port B bit 0. INT repræsenterer, at det lige så godt kan være konfigurationer som en ekstern afbrydelsesstift. Endvidere kan port B-ben 4 til 7 (ben 10 til 13) også anvendes til afbrydelser. Før vi er i stand til at anvende INT eller en anden Port B-ben, skal vi udføre to opgaver. Allerførst skal vi informere PIC om, at vi vil bruge afbrydelser.

Dernæst skal vi udpege, hvilken port B-pin vi skal bruge som en afbrydelse snarere end som en I / O-pin. Inde i PIC kan du finde et register kendt som INTCON og er på adresse 0Bh. I dette register vil du opdage 8 bits, der kan aktiveres eller deaktiveres. Bit 7 i INTCON er kendt som GIE. Dette er Global Interrngupt Enable. At rette dette til 1 informerer PIC om, at vi vil anvende en afbrydelse.

Bit 4 i INTCON er kendt som INTE, INTerrupt Enable. At sætte denne bit til 1 formidler til PIC, at RB0 vil være en afbrydelsesstift. Konfiguration af bit 3, kaldet RBIE, informerer PIc'en om, at vi vil bruge Port B bit 4 til 7. På dette tidspunkt forstår PIC, når denne pin kan være høj eller lav, skal stoppe, hvad den udfører, og fortsætte med en afbrydelse rutine. På dette tidspunkt skal vi informere PIC, om afbrydelsen sandsynligvis vil være på den stigende kant (0V til + 5V) eller den faldende kant (+ 5V til 0V) transformation af signalet.

Enkelt sagt, ønsker vi, at PIC afbryder hver gang signalet bevæger sig fra lav til høj eller fra høj til lav. Ved kriminalitet kan dette etableres for at blive placeret på den stigende kant.

Kanten 'triggering' er planlagt i et ekstra register kaldet OPTION-registeret på adresse 81h. Den bit, vi er begejstrede for, er bit 6, ofte omtalt som INTEDG.

Hvis dette indstilles til 1, udløses PIC for at afbryde på monteringskanten (standardtilstand) og indstilling til 0 stimulerer PIC til at afbryde på glidekanten. Hvis du gerne vil have, at PIC aktiveres i stigende kant, behøver du bestemt ikke gøre noget ved denne bit.

Desværre er Option-registeret i Bank 1, hvilket betyder, at vi nyder at ændre fra bank 0 til bank 1, indstille bit i Option-registeret, efter at vende tilbage til bank 0. Nøglen her er at udføre hver bit af Bank 1 registrerer sig i en enkelt strejke, f.eks. oprettelse af havnestifter, hvorefter de vender tilbage til Bank 0, hvis du er færdig.

Fint, derfor har vi underrettet PIC, hvilken pin der sandsynligvis vil være afbrydelsen, og hvor kanten skal udløses, hvad foregår der i programmet og PIC, når afbrydelsen sker? Et par ting finder sted. Allerførst er et 'flag' planlagt.

Dette informerer PIC's interne processor om, at en afbrydelse er sket. Dernæst tip til programtælleren (som jeg talte om i den foregående tutorial) til en bestemt adresse i PIC. Lad os hurtigt tjekke alle disse individuelt. Interrupt Flag I vores INTCON-register er bit 1 interrupt-flag, kaldet INTF. På dette tidspunkt, når der opstår afbrydelser, vil dette flag sandsynligvis blive fastgjort til 1.

Når der ikke er et afbrydelse, placeres flaget til 0. Såvel som det er næsten alle udførte. På dette tidspunkt overvejer du muligvis 'hvad er pointen?' Selvom dette flag er planlagt til 1, er PIC ikke i stand til og vil ikke reagere på en anden afbrydelse. Lad os derfor udtrykke, at vi får afbrydelse. Flagget vil sandsynligvis blive fastgjort til 1, og PIC kan gå til vores rutine for at arbejde med afbrydelsen.

Når dette flag ikke var fastgjort til 1, og PIC fik lov til at fortsætte med at besvare afbrydelsen, kunne kontinuerlig pulsering af stiften holde PIC tilbage til begyndelsen af ​​vores afbrydelsesrutine og på ingen måde fuldføre det. Når jeg vender tilbage til min illustration af telefonen, svarer det til at løfte telefonen, og straks når du fortsætter med at diskutere, begynder den at ringe igen, da en anden person ønsker at tale med dig.

Det tilrådes at afslutte en dialog og derefter gribe telefonen igen for at tale med den efterfølgende person. Du kan finde et lille problem med dette flag. Selvom PIC hurtigt sætter dette flag til 1, sætter det ikke det igen 0! Denne aktivitet skal udøves af programmøren - dvs. dig. Dette kan let gennemføres, da jeg er sikker på, at det er nødvendigt og skal opnås, når PIC har udført afbrydelsesrutinen.

Hukommelsesplacering Når du oprindeligt tænder for PIC'en, eller hvis der findes en nulstilling, giver Programtælleren tip til at adressere 0000h, hvilket kan være umiddelbart i starten af ​​programhukommelsen. Men hvis der er et afbrydelse, angiver programtælleren adresse 0004h.

Derfor, mens vi komponerer vores program, der vil have afbrydelser, skal vi først informere PIC om at hoppe over adresse 0004h og opretholde afbrydelsesrutinen, der begynder ved adresse 0004h, adskilt fra resten af ​​programmet.

Dette kan være problemfrit at udføre. Oprindeligt starter vi vores program med en kommando kendt som ORG. Denne kommando angiver oprindelse eller start. Vi holder fast ved det med en adresse. Da PIC begynder ved adresse 0000h, skriver vi ORG 0000h. Derefter skal vi omgå adresse 0004h. Vi opnår dette ved at sætte en GOTO-instruktion ledsaget af en etiket, der giver tip til vores primære program.

Vi overholder derefter denne GOTO-kommando med endnu en ORG, dette øjeblik med adressen 0004h. Det er efter denne kommando, at vi indsætter vores afbrydelsesrutine. På dette tidspunkt kan vi muligvis skrive vores afbrydelsesrutine lige efter den anden ORG-kommando, eller vi er i stand til at placere en GOTO-sætning, der peger på afbrydelsesrutinen.

Det er virkelig relateret til valg fra din side. For at informere PIC, det tilbyder, ankom til afslutningen af ​​afbrydelsesrutinen, skal vi placere kommandoen RTFIE mod slutningen af ​​rutinen. Denne kommando betyder retur fra afbrydelsesrutinen. Mens PIC bemærker dette, angiver programtælleren til den endelige position, PIC var på, før afbrydelsen opstod. Vi har oprettet nedenfor et kort afsnit med kode for at vise ovenstående:

Der er et par ting, du skal informeres om, når du bruger afbrydelser. Den oprindelige tendens til at være, at hvis du muligvis bruger det samme register i dit primære program og afbrydelsesrutinen, skal du huske at detaljerne i registret sandsynligvis vil ændre sig, når afbrydelsen finder sted.

Lad os f.eks. Bruge w-registeret til at videresende data til Port A primært program, derfor kan du desuden bruge w-registeret i afbrydelsesrutinen til at skifte data fra en destination til en anden.

Hvis du ikke er forsigtig, vil w-registret indeholde den sidste værdi, den modtog, mens den havde været i afbrydelsesrutinen, så når du vender tilbage fra afbrydelsen, vil disse oplysninger blive leveret til Port A snarere end den værdi, du havde før afbrydelsen opstod.

Midlet omkring dette er at øjeblikkeligt gemme detaljerne i w-registret, inden du igen bruger det i afbrydelsesrutinen. Det andet er, at du kan finde en forsinkelse mellem, hvornår en afbrydelse finder sted, og når den efterfølgende kan opstå. Mens du forstår, har PIC et udvendigt ur, der muligvis kan være en krystal, eller det kan være en modstandskondensatorkombination.

Ligegyldigt hvad frekvensen af ​​dette ur er, deler PIC det med 4, hvorefter det bruges til det indre tidspunkt. For eksempel i tilfælde af at du har en 4MHz krystal knyttet til din PIC, i så fald udfører PIC instruktionerne ved 1MHz. Denne indvendige timing er kendt som en instruktionscyklus. På dette tidspunkt hævder databladet (utvivlsomt med mindre udskrivning), at du skal aktivere 3 til 4 instruktionsrunder mellem afbrydelser.

Min ville være at aktivere 4 runder. Årsagen til forsinkelsen er, at PIC kræver tid til at springe til afbrydelsesadressen, flaget og komme tilbage væk fra afbrydelsesrutinen. Husk derfor dette, hvis du arbejder med et alternativt kredsløb for at aktivere en afbrydelse for PIC.

På dette tidspunkt er et punkt til det faktum, at hvis du bruger bits 4 til 7 i Port B som en afbrydelse. Du kan ikke vælge bestemte stifter på Port B for at fungere som en afbrydelse.

Derfor, hvis du tillader disse ben, kan de sandsynligvis være alle tilgængelige. Derfor kan du for eksempel ikke bare have bits 4 og 5 - bits 6 og 7 vil sandsynligvis blive bemyndiget på samme tid. Hvad er præcis formålet med at få fire bits til at repræsentere en afbrydelse? Du kan helt sikkert have et kredsløb tilsluttet PIC, hvis nogen af ​​fire linjer går højt, i så fald kan dette være et problem, som du kræver, at PIC straks påvirker.

En illustration af dette kunne være en alarm til hjemmets sikkerhed, hvor fire sensorer er forbundet til Port B ben 4 til 7. Enhver specifik sensor kan bede PIC om at udløse en alarm, og alarmsignalerutinen er afbrydelsesrutinen. Dette sparer konstant kontrol af havne og tillader PIC at fortsætte med forskellige forhold. Inden for den næste tutorial skal vi komponere et program til at styre en afbrydelse.

Vi behandlede en masse grundlæggende inden for den sidste tutorial, derfor føler jeg, at tiden er kommet, at vi sammensatte vores første program.

Det program, vi skriver, tæller antallet af lejligheder, hvor vi tænder en kontakt, og viser derefter nummeret.

Programmet tæller fra 0 til 9, kan ses på 4 lysdioder i binær form sammen med input eller afbrydelse sandsynligvis på RB0.

Den første ting, vi skal udføre, er at informere PIC om at springe over den adresse, som programtælleren peger på, hver gang et afbrydelse finder sted.

Du vil bemærke, at vi anvender en unik metode til at udstille hexadecimale tal. Før jeg skete, skal du anvende F9h, hvor h angiver hexadecimal. Vi kunne skrive dette som 0xF9, hvilket er den struktur, vi vil anvende fra nu af.

Nu er vi nødt til at fortælle PIC, at vi skal bruge afbrydelser, og vi bruger RB0 pin 6 som en interrupt pin:

bsf INTCON, 7GIE - Global afbrydelsesaktivering (1 = aktivering)
bsf INTCON, 4INTE - RB0 afbryd aktivering (1 = aktiv)
Jeg vil rydde afbrydelsesflagget i tilfælde af (jeg stoler aldrig på noget!)
bcf INTCON, 1INTF - Ryd flagbit bare i tilfælde

I øjeblikket skal vi etablere vores 2 porte. Husk, at da vi nu bruger RB0 som en afbrydelsesstift, skal dette etableres som et input:

Vi skal bruge en variabel kaldet COUNT til at gemme antallet af switchantal. Vi kunne bare simpelthen øge værdien på Port A, men du vil se, hvorfor jeg bruger en variabel, når vi skriver vores afbrydelsesrutine.

Derfor er vores hovedprogram sammensat, og på dette tidspunkt skal vi informere PIC, hvordan vi skal fortsætte, hver gang et afbrydelse finder sted. Inden for dette eksempel vil vores afbrydelse sandsynligvis være kontakten. Lige hvad vi gerne vil have PIC til, er en til det justerbare COUNT hver gang kontakten er begrænset.

Ikke desto mindre vil vi bare vise, hvor mange lejligheder kontakten lukker fra 0 til 9. Ovenstående sagde jeg, at vi muligvis simpelthen kunne have øget værdien på Port A, hver gang der er et afbrydelse. Port A har dog 5 bits, hvis vi simpelthen forøgede porten, vil vi have det højeste antal på 31. Der er et par forklaringer på, hvorfor jeg valgte ikke at gå op til 31.

Oprindeligt vil vi anvende en 7-segment skærm, som højst kun kan gå fra 0 til 15 (0 til F i hex). Dernæst vil jeg desuden vise dig et par af de aritmetiske kommandoer, som du snuble over i de sidste par lektioner.

Derfor fortsætter vi med vores afbrydelsesrutine. I øjeblikket er det første, vi skal opnå, kortvarigt at gemme detaljerne i vores w-register, da vi har anvendt dette for at flytte indholdet af COUNT til PORTA. Hvis vi ikke gemmer det, kan vi i så fald muligvis levere et helt andet antal på grund af vores aritmetik. Lad os derfor opnå det første:

På dette tidspunkt forstår vi, om værdien af ​​COUNT er 9 eller mere. Bare hvad vi skal udføre nu er, hvis COUNT er mere end 9, skal du placere det tilbage til 0 eller ellers vende tilbage til hovedprogrammet for at sikre, at vi er i stand til at levere det til Port A. BTFSS-kommandoen, da du forstår, ville den efterfølgende
instruktion i tilfælde af, at transportflagget er planlagt, dvs. COUNT = 10:

Det eneste der er tilbage at gøre nu er at gå ind kollektivt samt bestemme værdier til vores konstanter, som vi er i stand til at udføre lige i starten af ​​vores program.

Hver gang du aktiverer tændingen, tælles lysdioderne op i binær fra 0000 til 1010 og derefter tilbage til 0000.

Følgende figur viser kredsløbsdiagrammet, der er kompatibelt med den ovenfor forklarede kode. Interessant vil du opdage, at tidskondensatoren er inkluderet i designet. Dette er et dejligt lille trick, hvorigennem du får friheden til at undgå at medtage kondensatoren, hvis du ikke har nogen med dig i løbet af den tid.

Her kommer kapacitansen i spil via den omstrejfende kapacitans over oscillatorstiften og jorden.
Selvfølgelig ser det måske ikke ud til at være en meget intelligent måde at undgå en kondensator på, da den omstrejfende værdi kan variere med forskellige givne forhold.

Et andet afsnit, som man kan se i kredsløbet, er det opsigende netværk på tværs af kontakten. Dette forhindrer interferens under mekanisk skift og forhindrer PIC i at blive forvirret, hvis skiftet var en enkelt skifte eller flere skifter.




Forrige: Programmerbar tovejsmotortimerkreds Næste: Hvordan Buck-Boost-kredsløb fungerer