Tutorial PIC- De la registre la întreruperi

Încercați Instrumentul Nostru Pentru Eliminarea Problemelor





Înainte de a intra în detaliile minuțioase ale programării PIC, ar fi mai întâi important să învățați câteva metode bune de programare.

Înțelegerea registrelor

Pentru început, să presupunem că tastați un (punct și virgulă) în orice punct al programului, toate cele care vin după acest punct și virgulă vor fi ignorate de compilator, până când, bineînțeles, trăsura revine în poziție.



Funcția de mai sus ne permite să adăugăm comentarii sau observații astfel încât acestea să nu devină parte a programului, dar ne facilitează identificarea programului cu ajutorul comentariilor de lângă acesta. Punerea comentariilor este o practică recomandată în timpul programării oricărui IC.

Următorul lucru important în curs este să atribuiți numele diferitelor constante (le veți învăța mai târziu în detaliu). Astfel, este mai ușor să înțelegeți la ce se scrie sau cu privire la valorile implicate, în loc să vă confundați cu numerele incluse.



Cele de mai sus trebuie făcute sub formă de nume reale pentru recunoașterea instantanee, de exemplu COUNT, ar fi important să rețineți că aici toate literele majuscule sunt folosite pentru a o face distinctă și, de asemenea, indică faptul că este o valoare constantă.


După cum putem vedea, cele de mai sus se realizează sub forma unei cutii din punct și virgulă, ceea ce îl face să pară mai curat. În plus, încercați să documentați și programul pe hârtie, această practică vă va ajuta să înțelegeți lucrurile într-un mod înțelept.

2. Registrele.

Registrul dintr-un PIC este un domeniu care acceptă detalii scrise și permite citirea din acesta. Puteți să-l comparați cu o foaie de hârtie unde puteți vizualiza conținutul și, de asemenea, adăuga scriind peste el.

Figura de mai jos prezintă o hartă tipică a fișierului de registru încorporată într-un PIC16F84. Formatul nu este setat de fapt în interiorul PIC, ci pur și simplu pentru a indica modul în care biții pot fi aranjați în interiorul cipului și pentru a înțelege câteva dintre comenzile implicate.

Puteți vedea că este practic împărțit în Banca 0 și Banca 1. Banca 1 este responsabilă pentru controlul funcționării reale a PIC, de exemplu, transmite PIC-ului care biți din Portul A sunt atribuiți ca intrări și care sunt ca ieșiri.

Banca 2 este doar pentru manipularea informațiilor.

Să înțelegem acest lucru prin următorul exemplu:

Să presupunem că dorim să alocăm un bit la PortA high. Pentru aceasta, ar trebui mai întâi să mergem la Banca 1 pentru setarea bitului sau pinului specificat la Portul A sub forma unei ieșiri. După aceasta ne întoarcem la Banca 0 și livrăm o logică 1 (bit 1) la acel pin specific.

Cele mai frecvente registre pe care am dori să le folosim în Banca 1 sunt STATUS, TRISA și TRISB.

STATUS ne ajută să ne întoarcem la Banca 0, TRISA ne permite să alegem care pinii din portul A sunt ieșiri și care pot fi intrări, în timp ce TRISB facilitează selectarea dintre ieșire și pinul de intrare în portul B. Registrul SELECT din BANK 0 permite utilizatorului pentru a răsfoi la Banca 1.

Să rezumăm întregul concept cu următoarea descriere:

STARE:

Pentru a trece de la Banca 0 la Banca 1 comandăm registrul STATUS. Acest lucru este implementat prin setarea bitului 5 al registrului STATUS la 1. Pentru a reveni la Banca 0, atribuim bitul 5 al registrului STATUS la 0. Registrul STATUS este poziționat la adresa 03h, aici h înseamnă numărul poate fi în hexazecimal.

TRISA și TRISB:

Acestea sunt situate la adresa 85h și 86h corespunzător. Pentru programarea unui pin ca o ieșire sau o intrare, livrăm doar un zero sau unul pe bitul specific din registru. Acum, acest lucru se poate face în două moduri, prin binar sau Hex. În cazul în care cineva nu este capabil să convertească parametrul, el sau ea poate alege un calculator științific pentru implementarea valorilor.

Acum avem 5 pini la portul A, care corespunde la 5 pini. Dacă intenționăm să fixăm unul dintre pini ca intrări, livrăm un „1” la bitul respectiv.

În cazul în care am vrut să atribuim unul dintre pini ca ieșiri, am seta pinul specific la „0”. Biții sunt de ajutor exact în funcție de biți, sau mai precis bitul 0 este RA0, bitul 1 ar fi RA1, bitul 2 = RA2 și așa mai departe. Să o înțelegem în acest fel:

Să presupunem că doriți să reparați RA0, RA3 și RA4 ca ieșiri, în timp ce RA1 / RA2 ca i / ps, veți face acest lucru trimițând 00110 (06h). Verificați dacă bitul 0 este spre dreapta, după cum se indică aici:

Port A Pin RA4 RA3 RA2 RA1 RA0

Numărul de biți 4 3 2 1 0

Binar 0 0 1 1 0

Același lucru este valabil și pentru TRISB.

PORTA și PORTB

Pentru a livra unul dintre pinii de ieșire, oferim doar un „1” pentru a trece bitul respectiv în registrul PORTA sau PORTB. O procedură identică poate fi urmată și pentru registrele TRISA și TRISB. Înainte de a accesa primul exemplu de codare, să înțelegem doar un cupe de mai multe registre, și anume: w și f.

W și F

Registrul W este un registru obișnuit care vă permite să atribuiți orice valoare la alegere. De îndată ce atribuiți o magnitudine lui W, puteți continua adăugând aceasta la o altă valoare sau pur și simplu mutați-o. Cu o altă valoare atribuită, detaliile sunt pur și simplu suprascrise pe W.

Registrul F transmite materia scrisă către un registru. Am cere ca acest registru F să atribuie o valoare peste un registru, poate fi peste registrele STATUS sau TRISA, deoarece acestea nu ne vor permite să punem valorile direct peste ele. Un exemplu de program

Să examinăm următorul exemplu de cod care ne va arăta cum este implementată instrucțiunea de mai sus și care ar fi, de asemenea, martor la câteva dintre instrucțiunile din curs.

Să începem prin remedierea portului A așa cum s-a discutat mai sus.

Pentru aceasta trebuie să trecem de la Banca 0 la Banca 1, acest lucru se face prin configurarea registrului STATUS situat la adresa 03h, bitul 5 la 1.

BSF 03h, 5

Setul de biți înseamnă BSF F. Folosim două numere după această instrucțiune - 03h, care este adresa de registru STATUS și numărul 5 care corespunde numărului de biți.

Deci, ceea ce spunem este „Setați bitul 5 la adresa 03h la 1”.

Acum suntem în Banca 1.

MOVLW 00110b

Introducem valoarea binară 00110 (litera b înseamnă că numărul este în binar) în registrul nostru de uz general W. Aș fi putut desigur să fac acest lucru în hex, caz în care instrucțiunea noastră ar fi:

MOVLW 06h

Fie funcționează. MOVLW înseamnă „Mutați valoarea literală în W”, ceea ce în engleză înseamnă să introduceți valoarea care urmează direct în registrul W.

Acum trebuie să punem această valoare în registrul nostru TRISA pentru a configura portul:

MOVWF 85h

Această instrucțiune indică „Mutați conținutul lui W în adresa de înregistrare care urmează”, în acest caz adresa se referă la TRISA.

Registrul nostru TRISA în acest moment poartă cifra 00110 sau prezentat grafic:

Port A Pin RA4 RA3 RA2 RA1 RA0

Binar 0 0 1 1 0

Intrare / Ieșire O O I I O

Deci, acum posedăm pinii portului A, trebuie să ne întoarcem la Banca 0 pentru a regla una dintre informații.

BCF 03h, 5

Această instrucțiune realizează inversul BSF. Aceasta implică „Bit Clear F”. O pereche de numere care corespund sunt adresa registrului, aici registrul STATUS, precum și cifra de biți, în acest caz bitul cinci. Ceea ce am realizat exact în prezent este, bitul cinci definit pe al nostru

STATUS înregistrați la 0

În acest moment, am revenit în Banca 0.
Următorul este codul într-un singur bloc:

BSF 03h, 5 Accesați Banca 1
MOVLW 06h Puneți 00110 în W
MOVWF 85h Mutați 00110 pe TRISA
BCF 03h, 5 Reveniți la Banca 0

În cadrul ultimei instrucțiuni, v-am confirmat modalitatea de a stabili pinii portului IO pe PIC pentru a fi posibil de intrare sau ieșire.

Prin acest curs, permiteți-mi să vă ajut să trimiteți date către porturi.

Trimiterea datelor către porturi

În tutorialul următor, vom finaliza intermitent un LED aprins și oprit care constă într-un detaliu complet al programului și o diagramă simplă a circuitului, astfel încât să puteți vedea PIC efectuând exact ceea ce anticipăm.

Nu încercați să puneți împreună și să programați PIC cu rezultatele de mai jos, deoarece acestea sunt doar ilustrații. Inițial, vom stabili Portul bit 2 ca ieșire:

Acest lucru ar putea fi recunoscut din instrucțiunile anterioare. Singura distincție ar putea fi Am fixat fiecare bit al pinilor pe A ca ieșire, livrând 0h la registrul tri-stare. Deci, acum ce trebuie să facă este să aprindă un LED.

Realizăm acest lucru programând unul dintre pini (cel cu LED-ul conectat la acesta) înalt. Pentru a o spune diferit, aplicăm un „1” la pin. Acesta este exact modul în care se desfășoară (respectați comentariile pentru o clarificare pentru fiecare linie):

Prin urmare, ceea ce am realizat acum este să aprindem LED-ul, apoi să-l oprim o dată. Ceea ce dorim este ca LED-ul să se aprindă ulterior continuu.

Obținem acest lucru obținând programul pentru a reveni la început. Realizăm acest lucru stabilind inițial o etichetă la începutul programului nostru, informând ulterior programul să continue înapoi acolo. Specificăm o etichetă destul de simplu.

Introducem un termen, să spunem START, apoi tastați codul:

După cum se demonstrează, am menționat inițial expresia „Începeți” imediat la începutul programului.

Apoi, chiar la sfârșitul programului am menționat clar „Go Start”. Instrucțiunea „merge” execută exact ceea ce declară.

Acest program ar aprinde și opri LED-ul în mod constant ori de câte ori pornim circuitul, având tendința să se oprească odată ce scoatem electricitatea. Poate că ar trebui să ne verificăm programul din nou:

Cu siguranță am omis comentariile, însă putem respecta instrucțiunile și numerele.

Acest lucru poate fi ușor nedumeritor mai târziu în cazul în care încercați să depanați programul și în timp ce scrieți codul, ați memorat toate adresele.

Deși comentariile pot fi plasate totuși, ar putea deveni puțin aglomerate. Acest lucru va necesita denumirea numerelor și ar putea fi realizat printr-o instrucțiune suplimentară: „equ” Instrucțiunea „equ” sugerează că unele lucruri ar putea fi egale cu alte lucruri.

Este posibil să nu fie o instrucțiune pentru PIC, mai degrabă pentru asamblare. Această instrucțiune facilitează atribuirea numelui unei locații de adrese de registru sau a unei constante a unui termen de programare.

Vom stabili câteva constante pentru programul nostru și vom asista, de asemenea, la cât de simplu citeste programul.

De acum am fixat valorile constante pe care le putem continua configurându-le în programul nostru. Valorile constante trebuie să fie desemnate înainte de a le utiliza.

prin urmare, asigurați-vă că le poziționați întotdeauna la începutul programului. Vom rescrie din nou programul, excluzând comentariile, pentru a compara etichetarea anterioară cu cea mai recentă.

Poate că sunteți capabil să observați că constantele permit o înțelegere ușor mai ușoară a programului, cu toate acestea, suntem încă fără comentarii, însă nu ne facem griji, deoarece încă nu am terminat.

Este posibil să existe un dezavantaj minor al programului nostru LED intermitent.
Fiecare instrucțiune are nevoie de o secvență de ceas pentru a termina. În cazul în care utilizăm un cristal de 4 MHz, atunci fiecare instrucțiune necesită 1/4 MHz sau 1 uS pentru a finaliza.

Deoarece folosim doar cinci instrucțiuni, LED-ul se va activa apoi se va stinge în 5uS. Acest lucru ar putea fi mult prea rapid pentru ca oamenii să observe, în plus, se va părea că LED-ul este complet aprins.

Ceea ce ar trebui să realizăm în schimb este să producem o inhibiție între pornirea LED-ului și oprirea LED-ului. Teoria inhibiției este că numărăm în jos de la o cantitate anterioară, deci, când ajunge la zero, renunțăm la numărare.

Valoarea zero înseamnă încheierea întârzierii și continuăm să ne desfășurăm procesul pe tot parcursul programului. Prin urmare, primul lucru pe care trebuie să-l facem este să determinăm o constantă pe care să o folosim ca contor.

Să numim acest CONTE constant. După aceea, trebuie să determinăm cât de semnificativ este un număr pentru a începe să se numere. Cu siguranță, cea mai mare cifră pe care am putea-o include este 255 sau FFh în hex., Așa cum am vorbit în tutorialul anterior, instrucțiunea equ atribuie o expresie unei situații de registru.

Acest lucru implică faptul că, indiferent de cantitatea pe care o alocăm COUNTUL nostru, acesta ar corespunde articolelor unui registru. În cazul în care încercăm să desemnăm valoarea FFh, vom obține o greșeală odată ce vom ajunge să compilăm programul.

Motivul pentru care se află locația FFh este, prin urmare, nu putem avea acces la ea. Prin urmare, cum trebuie să desemnăm un număr autentic? Cu siguranță, va necesita o cantitate mică de meditare laterală.

Dacă, probabil, desemnăm COUNT-ul nostru la adresa 08h, de exemplu, acest lucru ar indica o destinație de registru obiectiv de bază. În mod implicit, zonele neatinse sunt setate la FFh. În consecință, dacă COUNT duce la 08h, veți întâlni valoarea FFh în timp ce pornim prima dată. Cu toate acestea, eu, voi, cum putem stabili COUNT la un alt număr ?, tot ceea ce aplicăm este „mutați” o evaluare mai întâi la această destinație.

Ca o ilustrare, să presupunem că am dorit ca COUNT să aibă o valoare de 85h, nu putem menționa COUNT equ 85h, deoarece aceasta este poziția registrului tri-stat pentru portul A. Tocmai ceea ce realizăm este următorul: movlw 85h valoarea de 85h în registrul W movwf 08h

Acum mutați-l în registrul nostru de 08h. Ulterior, în cazul în care exprimăm COUNT ech 08h, COUNT ar corespunde valorii 85h. Delicat, nu-i așa! Prin urmare, inițial ne determinăm constanta: COUNT ech 08h După aceea trebuie să reducem acest COUNT cu unul până când devine zero.

Pur și simplu se întâmplă astfel încât există o instrucțiune concepută pentru a realiza acest lucru pentru noi, folosind un „goto” și o etichetă.

Instrucțiunea pe care urmează să o aplicăm este: DECFSZ COUNT, 1 Această instrucțiune indică „Decrementează registrul (aici este COUNT) după numărul care urmărește virgula. Dacă atingem zero, treceți cu două puncte înainte. ”Să-l găsim mai întâi în acțiune, înainte să îl plasăm în cursul nostru.

Ceea ce am realizat este inițial să stabilim COUNT-ul nostru constant la 255. Segmentul ulterior poziționează o etichetă, numită LABEL aproape de instrucțiunea noastră decfsz.

Decfsz COUNT, 1 reduce valoarea COUNT cu unul și păstrează rezultatul final direct în COUNT. În plus, verifică dacă COUNT are o valoare 0.

În caz contrar, în acest caz declanșează trecerea programului la linia ulterioară. Acum avem o declarație „go” care ne readuce la instrucțiunile noastre decfsz.

În cazul în care valoarea COUNT este egală, atunci instrucțiunea decfsz are ca rezultat ca programul nostru să treacă cu 2 locuri înainte și este trimis acolo unde am revendicat „Continuă aici”.

Prin urmare, din moment ce puteți observa, am adus programul să stea într-un singur loc pentru un timp predestinat înainte de a continua. Aceasta ar putea fi numită o buclă de întârziere.

Înțelegerea buclelor de întârziere

În cazul în care avem nevoie de o întârziere mai substanțială, am putea urmări o buclă până la următoarea. Buclele suplimentare, cu atât întârzierea se extinde. Permiteți-ne cel puțin două, presupunând că dorim să observăm blițul cu LED-uri. Vom plasa aceste bucle de întârziere în programul nostru și vom realiza acest lucru transformându-l într-un program autentic introducând comentarii:

Este posibil să compilați acest program după care programați PIC. Evident, asigurați-vă că încercați circuitul pentru a verifica dacă funcționează într-adevăr. Următorul este o schemă de circuit pe care ar trebui să o construiți imediat ce ați programat PIC.


Bravo, ai fi putut compune de fapt primul tău program PIC, precum și să fi construit un circuit care să aprindă și să stingă un LED. Până acum, în cazul în care ați urmat aceste cursuri, s-ar putea să fi învățat un total de șapte instrucțiuni din 35, dar fără îndoială până acum ați putea controla porturile I / O!

Ați încerca să schimbați buclele de întârziere pentru a face blițul LED mai rapid - care pare valoarea minimă a COUNT pentru a vedea în mod esențial blițul LED? Sau poate, veți dori să includeți un al 3-lea sau bucle de întârziere suplimentare după cel inițial pentru a stabiliza LED-ul în jos. o constantă unică pentru fiecare buclă de întârziere.

S-ar putea să vă lăsați de fapt cu buclele dvs. de întârziere pentru a reda blițul LED la o viteză specifică, de exemplu după o secundă. În următoarea instrucțiune, să vedem cum suntem capabili să folosim ceva cunoscut ca subrutină pentru a menține programul compact și de bază. Un subrutină este o parte integrantă a codului sau a programului, care poate fi menționat și când este posibil să aveți nevoie de el. Subrutinele sunt utilizate în cazurile în care îndepliniți frecvent aceeași funcție.

Ce sunt Subrutine

Avantajele utilizării unui subrutin sunt că va fi probabil mai simplu să modificați valoarea o dată în interiorul unui subrutin în loc de, să zicem, de zece ori pe tot parcursul programului dvs., precum și contribuie foarte mult la scăderea nivelului de memorie pe care programul dvs. îl consumă în interiorul PIC. Vom verifica un subrutină:

Inițial, trebuie să oferim subrutinei noastre o denumire și, în această situație, am selectat RUTINA. După acel tip, introducem codul pe care am vrea să îl conducem în mod normal. De aceea, am selectat întârzierea în programul nostru cu LED-uri intermitente. În cele din urmă, încheiem subrutina tastând instrucțiunea RETURN.

Pentru a începe subrutina de oriunde din programul nostru, tastăm rapid instrucțiunea CALL și apoi denumirea subrutinei.

Vom lua în considerare acest lucru puțin mai în profunzime. Odată ce ajungem la secțiunea programului nostru CALL xxx, în care xxx este numele subrutinei noastre, programul sare către oriunde este instalat subrutina xxx. Instrucțiunile din interiorul subrutinei sunt efectuate.

Ori de câte ori se îndeplinește instrucțiunea RETURN, programul revine la programul nostru principal la instrucțiunea ulterioară instrucțiunii noastre CALL xxx.

Este posibil să apelați subrutina similară de mai multe ori după cum doriți, ceea ce explică de ce utilizarea subrutinelor reduce durata generală a programului nostru.

Cu toate acestea, există câțiva factori pe care ar trebui să-i cunoașteți. Inițial, ca și în cazul programului nostru principal, orice constantă specifică trebuie confirmată înainte de a le putea utiliza.

Acestea pot fi recunoscute în cadrul programului propriu-zis sau direct la începutul programului principal. Vă propun să recunoașteți totul la începutul programului dvs. principal, de atunci recunoașteți că lucrurile sunt într-o poziție identică. Apoi, trebuie să vă asigurați că programul principal trece peste subrutină.

Ceea ce sugerez cu acest lucru este dacă ar trebui să plasați subrutina direct la încheierea programului dvs. principal, cu excepția cazului în care utilizați o declarație „Mergeți” pentru a ieși din locul unde se află subrutina, programul va continua și va implementa subrutina, indiferent dacă o solicită sau altfel.

PIC nu ar face distincție între un subrutină și programul principal. Vom verifica programul nostru intermitent, dar de data aceasta vom folosi un subrutină pentru bucla de întârziere. În mod ideal, veți descoperi cât de puțin mai complicat apare programul, precum și ați putea afla cum se aplică practic subrutina.

În cele din urmă, puteți observa că, utilizând un subrutină pentru bucla noastră de întârziere, am fi putut reduce dimensiunile programului.

De fiecare dată când dorim o întârziere, posibil când LED-ul este aprins sau oprit, numim practic subrutina de întârziere. La încheierea subrutinei, programul duce înapoi la linie urmând instrucțiunile noastre „Apel”. În ilustrația de mai sus, aprindem LED-ul.

După aceea, contactăm subrutina. Programul revine apoi pentru a putea opri LED-ul. Apelăm din nou subrutina, doar în cazul în care subrutina s-ar fi finalizat, programul revine și instrucțiunea ulterioară pe care o recunoaște este „go Start”. Pentru oricine ar putea fi intrigat, primul nostru program a avut 120 de octeți.

Prin utilizarea subrutinei, am putea reduce dimensiunea programului până la 103 octeți. Acest lucru nu poate părea a fi atât de fantastic, având în vedere faptul că avem doar 1024 de octeți în general în PIC, fiecare cantitate mică beneficiază.

În cadrul următoarei instrucțiuni, permiteți-ne să verificăm citirea din porturi.

Până în prezent, am compus în portul A pentru a putea activa și opri un LED. În acest moment, vom vedea cum vom citi pinii I / O de pe porturi.

Citirea porturilor de intrare / ieșire

Aceasta este exact pentru a ne asigura că suntem capabili să conectăm un circuit extern și să influențăm orice ieșiri specifice pe care le oferă.

Dacă doriți să memorați de la cursurile noastre anterioare, dacă doriți să stabiliți porturile I / O, trebuie să trecem de la Banca 0 la Banca 1. Vom realiza acest lucru inițial:

În acest moment, am fixat bitul 0 al portului A la intrare. acum trebuie să examinăm dacă știftul este ridicat sau scăzut. Pentru a realiza acest lucru, puteți utiliza doar una dintre cele două instrucțiuni:

BTFSC și BTFSS.

Instrucțiunea BTFSC înseamnă „Faceți un test de bit pe registru, precum și bitul pe care îl desemnăm.

În cazul în care este un 0, în acest caz omitem instrucțiunea ulterioară ”. BTFSS implică „Faceți un test de bit în registru și bitul pe care îl stabilim. În cazul în care este setat la 1, atunci ocolesc instrucțiunile ulterioare.

Pe care îl utilizăm este determinat de modul în care dorim să răspundă programul nostru în timp ce studiem datele de intrare. Ca o ilustrare, în cazul în care așteptăm doar intrarea să fie un 1, atunci am putea folosi instrucțiunea BTFSS în modul următor:

Cod aici:

BTFSS PortA, 0Goto start Continuați aici:
:

Programul ar trece doar pe „Continuă aici”, cu condiția ca bitul 0 din PortA să fie programat la 1.

În prezent, vom scrie un program care ar putea solicita un LED într-un ritm, cu toate acestea, dacă un comutator este limitat, acesta ar aprinde LED-ul de două ori mai lent.

Este posibil să vă exercitați acest program pe cont propriu, totuși am încorporat listarea cumva.

Puteți încerca și crea autorul întregului program, pentru a verifica dacă în cazul în care ați înțeles principiile. Vom folosi circuitul echivalent ca înainte, cu includerea unui comutator atașat RA0 al PIC și a șinei pozitive a sursei noastre.

Ceea ce am realizat aici este să aprindem LED-ul. Ulterior stabilesc dacă întrerupătorul este închis.

În cazul în care este limitat, apoi mă conectez la subrutina noastră de întârziere. Acest lucru ne oferă întârzierea echivalentă ca înainte, cu toate acestea, suntem în acest moment contactându-l de două ori.

Același lucru se aplică ori de câte ori LED-ul este oprit. În cazul în care comutatorul nu este închis, atunci avem perioadele noastre de pornire și oprire înregistrate anterior.

Ați urmat aceste lecții de la început, s-ar putea să căutați să înțelegeți că ați descoperit în prezent zece din cele 35 de instrucțiuni pentru PIC 16F84! Și fiecare dintre acestea se întâmplă să fie învățat doar prin aprinderea și stingerea unui LED.

Până în prezent, am compus PIC clipind un LED aprins și oprit.

Ulterior am fost capabili să folosim PIC-ul nostru prin includerea unui comutator, prin urmare, modificând viteza blițului.

Utilizarea eficientă a spațiului de memorie

Singura problemă este că programul este destul de lung și destul de ineficient de spațiu de memorie. Părea ok în timp ce includeam comenzile pentru prima dată, totuși ar trebui să existe o modalitate mai ușoară de a o executa. În mod pozitiv, vom analiza modul în care am pornit și oprit LED-ul.

movlw 02hmovwf PORTAmovlw 00hmovlw PORTA

La început ne-am umplut registrul w cu 02h, după care l-am transferat în registrul nostru PortA pentru a porni LED-ul. Pentru a-l opri, am ambalat w cu 00h, după care l-am mutat în registrul nostru PortA.

Între toate aceste rutine am fost obligați să luăm legătura cu un subrutină pentru a ne asigura că putem observa intermitentul LED.

Prin urmare, a trebuit să transferăm două seturi de informații de câteva ori (o dată în registrul w apoi în PORTA), precum și să apelăm un subrutină de două ori (o dată pentru pornit, apoi o dată pentru oprit). Astfel, cum am putea realiza acest lucru cu o eficiență suplimentară? Foarte simplu.

Folosim o instrucțiune diferită cunoscută sub numele de XORF. Instrucțiunea XORF funcționează o funcție SAU exclusivă în registrul pe care îl stipulăm cu informațiile pe care le oferim. Cred că trebuie să clarific ce este în lume un SAU exclusiv înainte de a continua. În cazul în care avem două intrări și o ieșire, intrarea poate fi 1 doar dacă și atât timp cât cele două intrări diferă. Deși sunt aceleași, atunci rezultatul va fi probabil 0. Următorul este un tabel de adevăr, pentru persoanele care aleg să le verifice:

A B F0 0 00 1 11 0 11 1 0

În acest moment vom verifica ce se întâmplă dacă redăm B la fel ca rezultatul nostru anterior și pur și simplu modificând valoarea lui A:

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

Dacă menținem valoarea lui A la fel ca 1 și l-am exclusiv SAU cu ieșirea, ieșirea ar comuta. În cazul în care nu puteți observa acest lucru din tabelul adevărului, mai jos, acesta poate fi asistat utilizând binare:

0 Ieșire curentă
EX-OR Cu 1 1 ieșire nouă
EX-OR Cu 1 0 ieșire nouă

Poate puteți constata că, prin exclusivitatea OR a ieșirii cu 1, vom comuta acum ieșirea de la 0 la 1 la 0.
Prin urmare, pentru a ne aprinde și opri LED-ul, avem nevoie doar de câteva propoziții:

MOVLW 02h
UȘĂ XORWF, 1

Ceea ce tocmai vom realiza este să adăugăm registrul nostru w cu 02h. Suntem, în acest caz, exclusiv SAU pentru acest număr, indiferent de ce se află pe PortA noastră. În cazul în care bitul 1 este 1, se va modifica la 0. În cazul în care bitul 1 este 0, se va modifica la 1. Să examinăm acest cod o dată sau de două ori, pentru a afișa cum rulează binar:

UŞĂ
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

De fapt, nu trebuie să încărcăm valoarea identică în registrul nostru de fiecare dată, de aceea este posibil să realizăm acest lucru o singură dată la început și să ne întoarcem la comanda de comutare. În plus, nu ar trebui să fixăm o valoare în registrul nostru PortA. Motivul? Cu siguranță, din moment ce la pornire este 1, îl putem comuta cu ușurință. Eu, alternativ, un 0 la pornire, chiar acum îl vom comuta.

Prin urmare, ați dori să vedeți codul nou format. Primul reprezintă codul nostru LED intermitent, în timp ce al doilea îl arată pe cel cu adăugarea comutatorului:

Vă dorim să puteți constata că, pur și simplu folosind o instrucțiune ușoară, am redus acum scara programului nostru. Adevărul este că, pentru a afișa cât de mult am putea reduce programele noastre, am demonstrat cele două programe, exact ceea ce au fost compuse și dimensiunile lor în tabelul de mai jos:

Dimensiuni de modificare a programului (octeți)
LED intermitent Original 120
Subrutină LED intermitentă adăugată 103
LED intermitent Funcția XOR utilizată 91
LED cu comutator original 132
LED cu funcția de comutare XOR folosit 124.

Prin urmare, nu doar că am descoperit câteva instrucțiuni noi, ci cu siguranță am redus și dimensiunea scripturilor noastre!

Mai jos, vom analiza modul în care puteți schimba biți individuali, efectua anumite aritmetici simple, precum și tabele de date.

Managerii logici

În cadrul ultimului tutorial am prezentat operația SA exclusivă. Funcția ExOR este înțeleasă ca un operator logic.

În cadrul acestui tutorial voi ilumina operatorii logici suplimentari pe care PIC îi promovează. Nu va exista niciun fel de caz în programele punctuale, cu toate acestea Vom învăța metode ușoare de utilizare a operatorilor prin aplicarea unor zone mici de cod.

Funcția ȘI ȘI analizează practic doi biți și oferă un 1 dacă sunt aceiași și un 0 în cazul în care sunt distinctivi. De exemplu, dacă am menționat 1 ȘI 1, rezultatul este 1, în timp ce în cazul în care am declarat 1 ȘI 0, consecința ar fi 0.

Inutil să spunem că suntem capabili să evaluăm și cuvintele, precum și toate funcțiile AND realizează revizuirea celor doi termeni bit cu bit. Instanța de mai jos demonstrează două cuvinte pe 8 biți care devin AND împreună cu produsul:

11001011
ȘI 10110011
Este egal cu 10000011

Sper că sunteți de acord, rezultatul va avea pur și simplu un 1 ori de câte ori 2 1s mână în mână unul cu altul într-o pereche de cuvinte. De exemplu, putem utiliza funcția ȘI pentru a verifica porturile.

În cazul în care verificăm câțiva pini I / O care sunt conectați la un circuit și ar trebui să fim atenți la o anumită situație în care doar câțiva pini sunt mari, în acest caz putem citi destul de mult port, după care ȘI rezultatul cu condiția pe care am examinat-o, identică cu instanța de mai sus.

PIC ne oferă două ingrediente pentru ȘI.
Sunt ANDLW și ANDWF. ANDLW ne permite să desfășurăm o funcție AND cu detaliile registrului W și o sumă pe care o stipulăm.

Sintaxa este: ANDLW în care este exact ceea ce mergem ȘI conținutul lui W cu.

Consecința funcției ȘI ar fi stocată direct în registrul W.
ANDWF ne permite să realizăm o funcție AND pe registrul W și un registru diferit, de exemplu un PORT. Sintaxa este: ANDWF, d în care este registrul de care suntem entuziasmați, de ex. PORTA și d arată PIC unde trebuie să poziționați rezultatul. Dacă d = 0, rezultatul este pus în registrul W, iar din d = 1 rezultatul final este salvat în registrul pe care l-am stipulat. Cele două părți ale codului de mai jos afișează un bun exemplu al fiecărei funcții ȘI.

Inițialul examinează starea PORTA, în care trebuie să verificăm dacă intrările sunt 1100. Putem plasa rezultatul înapoi în registrul W

1100
ANDWF 05h, 0 A doua ilustrare ar putea verifica acum conținutul registrului W:
ANDLW 1100

SAU

Am descoperit până acum o funcție SAU, mai exact XOR. Aceasta se dezvoltă într-un 1 dacă doi biți nu sunt la fel, dar sunt diferiți. Puteți găsi o altă funcție OR numită IOR, care este OR inclusiv. Această funcție va genera 1 în cazul în care fiecare bit este 1, dar în plus dacă fiecare bit este 1. Mai jos este un tabel de adevăr clar pentru a ilustra acest lucru:

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

Ce sunt operatorii aritmetici

ADĂUGA

Această funcție îndeplinește ceea ce pretinde de obicei. Contribuie cu două cifre! În cazul în care consecința adăugării celor două cifre depășește 8 biți, în acest caz probabil va fi setat un flag CARRY. Steagul CARRY este situat la adresa 03h bit 0.

Când acest bit este programat, atunci cele două cifre au depășit 8 biți. Când este un 0, în acest caz, consecința este localizată în 8 biți. La fel ca înainte, PIC ne oferă două stiluri de ADD, în special ADDLW și ADDWF. Așa cum ați fi presupus, acest lucru este similar cu funcția de mai sus. ADDLW oferă conținutul registrului W la care stipulăm. Sintaxa este: ADDLW ADDWF adăugăm conținutul registrului W și un alt registru pe care îl desemnăm.

Sintaxa este: ADDWF, d este unde

SUB

În acest moment, cred că nu poți presupune ce acționează această funcție! Într-adevăr, ați bănuit-o, această funcție
scade un bit din altul. Din nou, PIC ne oferă 2 gusturi: SUBLW și SUBWF. Sintaxa este exact similară cu funcția ADD, în afară de faptul că, evident, tastați SUB în locul ADD!

Increment În cazul în care am dorit să includem 1 la un număr în PIC, am putea folosi în mod absolut funcția ADD și ar putea folosi numărul unu. ~ Dificultatea cu aceasta este că trebuie mai întâi să plasăm figura în registrul W, apoi să folosim controlul ADDLW 1 pentru a o incrementa. În cazul în care am dorit să includem 1 într-un registru, poate fi și mai rău. Mai întâi trebuie să plasăm numărul 1 în registrul W, după aceea folosiți ADDWF, 1. Prin urmare, de exemplu, pentru a include 1 la locația 0C, să zicem, ar trebui să posedăm următoarea parte a scriptului:

movlw 01
addwf 0c, 1

Există o metodă mai ușoară de a efectua acest lucru. Putem exercita comanda INCF. Sintaxa este: INCF, d unde, este registrul sau locul în care suntem preocupați și d arată PIC unde ar trebui să poziționați rezultatul. În cazul d = 0, rezultatul se află în registrul W, iar în cazul d = 1, consecința este stabilită în registrul pe care l-am stipulat.

Prin utilizarea acestei instrucțiuni individuale suntem capabili să obținem de fapt cincizeci la sută din codificare. În cazul în care dorim ca rezultatul să fie restabilit în registrul W, în acest caz folosind instanța de mai sus, ar fi trebuit să includem o comandă suplimentară pentru a transfera elementele 0C înapoi în registrul W, după care puneți registrul 0C înapoi la nr. indiferent ce a fost.

Există o comandă de creștere. Este INCFSZ. Această comandă ar putea incrementa registrul pe care îl stipulăm, totuși dacă registrul este egal cu 0 după increment (care va apărea în timp ce includem 1 la 127), după aceea, PIC va trece probabil instrucțiunea ulterioară. Porțiunea de cod de mai jos reflectă acest lucru:

Bucla incfsz 0C
Go Go Loop
:
:
Restul programului.

În porțiunea de cod de mai sus, 0C va fi incrementat cu 1. Deținem apoi o instrucțiune care informează PIC să revină la eticheta noastră numită Buclă și să creștem din nou 0C cu 1. Acest lucru continuă până când 0C este egal cu 127. În această circumstanță, când mărim 0C cu 1, 0C se va potrivi acum cu 0. Instrucțiunea noastră INCFSZ ar putea foarte bine să informeze PIC să omită instrucțiunea ulterioară, care în acest caz este declarația goto, prin urmare, PIC va continua cu restul programului.

Decrement

Până acum am discutat despre funcția de descreștere la antrenamentele anterioare, prin urmare nu o voi mai revizui.

Completa

Instrucțiunea finală din această discuție ar inversa fiecare bit din registrul pe care îl stipulăm. Sintaxa este: COMF, d în care

Înțelegerea operațiunilor de biți

Acest lucru ar putea fi utilizat, de exemplu, pentru a schimba rapid pinii unui port de la ieșire la intrare și așa mai departe. Funcțiile bit ne permit să modelăm un singur bit într-o expresie. Acestea ne permit să procedăm, să setăm și să scăpăm de unii biți din registre sau numere pe care le stipulăm.

La încheierea acestui curs, vom dezvălui un program conceput pentru a crea un set de lumini de secvențiere care continuă înainte, apoi invers. Am observat acest lucru realizat mai devreme când am examinat funcția OR exclusivă, în care am OR exclusiv porturile cu o expresie. Am observat până acum câteva funcții când stabilim porturile pe PIC și

Permiteți-mi să reiterez utilizarea lor aici.

BCF

Această instrucțiune va șterge un pic pe care îl stipulăm într-un registru pe care îl desemnăm. Sintaxa
este:
BCF,

Am folosit acest lucru mai devreme pentru a modifica de la pagina 1 la pagina 0 eliminând un pic din registrul STATUS. De asemenea, îl putem folosi pentru a fixa un pic la 0 în orice alt registru / locație. De exemplu, în cazul în care am dori să setăm al treilea bit în 11001101 salvat în secțiunea 0C la 0, am putea
introduce:

BCF 0C, 03

BSF

Această instrucțiune ar rezolva orice bit pe care îl stipulăm la 1 în orice registru pe care îl indicăm. Am folosit acest lucru mai devreme pentru a trece de la pagina 0 la pagina 1. Sintaxa este: BSF ,, și este utilizată exact în aceeași metodă ca BCF de mai sus.

Până acum am putea seta sau șterge un pic într-un registru. Cu toate acestea, imaginați-vă dacă trebuie să verificăm practic dacă un bit este 1 sau 0 într-un registru?

Cu siguranță, este posibil să utilizați BTFSC. Afișează registrul de testare bit F și Salt dacă este clar. Această instrucțiune va analiza bitul pe care îl desemnăm în registru. În cazul în care bitul este 0, instrucțiunea ar informa PIC să treacă instrucțiunea ulterioară.

Am putea folosi această instrucțiune în cazul în care am dori să verificăm un steag, de exemplu steagul de transport. Acest lucru ne scutește de faptul că trebuie să citim registrul STATUS și să căutăm biții individuali pentru a afla care steaguri sunt fixate. 29 De exemplu, în cazul în care am dorit să verificăm dacă steagul Carry a fost setat la 1 după ce am adăugat 2 cifre, atunci am putea tasta următoarele:

BTFSC 03h, 0
continuați aici dacă este setat la 1
sau aici, dacă este setat la 0

În cazul în care starea bitului este 1, în acest caz instrucțiunea ulterioară BTFSC ar fi finalizată. În cazul în care este setat la 0, în acest caz instrucțiunea ulterioară este omisă. Următoarea parte a codului prezintă în care ar putea fi utilizat:

Buclă:
:
:
BTFSC 03,0
Go Go Loop

În codul de mai sus, PIC va ieși pur și simplu din buclă în cazul în care bitul 0 al registrului STATUS (sau steagul Carry) este definit la 0. Sau altfel, comanda goto ar fi efectuată.

BTFSS

Această instrucțiune indică registrul de testare bit F și Omite dacă este setat. Acest lucru poate fi comparabil cu instrucțiunea BTFSC, în afară de faptul că PIC ar omite instrucțiunea ulterioară dacă bitul pe care l-am evaluat este setat la 1, în loc de 0.

CLRF

Această instrucțiune ar rezolva toate detaliile unui registru la 0. Sintaxa este:

CLRF
Am folosit acest lucru mai devreme pentru a seta ieșirea porturilor la 0, aplicând CLRF 85h. În plus, l-am angajat pentru a repara porturile pentru a include toți pinii la ieșire utilizând CLRF
05h.

CLRW

Acest lucru seamănă cu instrucțiunea CLRF, cu excepția șterge registrul W. Sintaxa este destul de simplu:

CLRW

RLF și RRF

Aceste direcții ar transporta un pic într-un registru un singur slot spre stânga (RLF) sau spre dreapta (RRF) într-un registru. De exemplu, dacă aveam nevoie de 00000001 și am folosi RLF, în acest caz am putea avea 00000010. În acest moment, ce se întâmplă în cazul în care există 10000000 și am aplicat instrucțiunea RLF? Cu siguranță, 1 ar fi poziționat în steagul de transport. În cazul în care am aplica din nou instrucțiunea RLF, 1 va reapărea la început. La fel apare, totuși în sens opus, pentru instrucțiunea RRF. Cazul de la punctul de mai jos arată acest lucru pentru instrucțiunea RLF, în care avem putem vedea cei 8 biți ai unui registru, precum și steagul de transport:

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

Program de exemplu

Vom vedea acum un exemplu de cod pe care îl putem compila și conduce. Ar genera o lumină de secvențiere începând cu PortA bit 0, mergând la PortB bit 8 și
apoi întorcându-se.
Conectați LED-uri la fiecare dintre pinii portului. Vom avea o parte din bit
procedurile subliniate în acest tutorial.

TIME EQU 9FH Variabilă pentru bucla de întârziere.
PORTB EQU 06H Adresa Port B.
TRISB EQU 86H Port B Adresă Tristate.
Adresa PORTA EQU 05H Port A.
TRISA EQU 85H Port A Adresa Tristate.
STATUS EQU 03H Înregistrare selectare pagină.
COUNT1 EQU 0CH Registr de buclă.
COUNT2 EQU 0DH Registrul buclei.

STARE BSF, 5 Accesați pagina 1
MOVLW 00H și configurare
MOVWF TRISB ambele porturi A și B.
MOVLW 00H la ieșire,
MOVWF TRISA apoi reveniți la
STARE BCF, 5 pag. 0.
MOVLW 00H Clear Port A.
UȘĂ MOVWF

Începutul programului principal

RUNMOVLW
01H Setați primul bitMOVWF
PORTB pe portul B.CALL
Întârziere Așteptați puțin APEL
ÎNTÂRZIERE
Mutați bitul din Portul B la stânga, apoi întrerupeți.RLF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRLF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRLF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRLF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRLF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRLF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRLF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRLF
PORTB, 1 Aceasta mută bitul în steagul de transport
Acum treceți la Portul A și mutați bitul la stânga.RLF
PORTA, 1 Aceasta mută bitul din steagul zero în PortACALL
DELAYCALL DELAYRLF
UȘĂ, 1 APEL
APEL DE ÎNTÂRZIERE
DELAYRLF
UȘĂ, 1 APEL
APEL DE ÎNTÂRZIERE
DELAYRLF
UȘĂ, 1 APEL
APEL DE ÎNTÂRZIERE
ÎNTÂRZIERE
Mutați bitul înapoi pe portul ARRF
UȘĂ, 1 APEL
APEL DE ÎNTÂRZIERE
DELAYRRF
UȘĂ, 1 APEL
APEL DE ÎNTÂRZIERE
DELAYRRF
UȘĂ, 1 APEL
APEL DE ÎNTÂRZIERE
DELAYRRF
PORTA, 1 Aceasta mută bitul în steagul zero Acum mutați bitul
înapoi pe Port BRRF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRRF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRRF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRRF
PORTB, 1CALL
DELAYCALL DELAYRRF
PORTB, 1CALL
APEL DE ÎNAPOI
DELAYRRF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
DELAYRRF
PORTB, 1CALL
APEL DE ÎNTÂRZIERE
Întârziere Acum ne-am întors de unde am început, GOTO
RUN hai să mergem din nou.

Există o opțiune excelentă în setul de antrenament care vă permite să utilizați un tabel de date.

Un tabel de date este doar o listă de citate de date, în care totul este analizat pe baza unor considerații.
De exemplu, ați putea avea un circuit care utilizează un PIC care numără cantitatea de instanțe pe care un pin de intrare devine ridicat în 1 secundă. După aceea, puteți expune numărul pe un afișaj pe 7 segmente.

De îndată ce momentul a fost lansat, PIC începe să numere cantitatea de ocazii în care pinul crește. După 1 secundă, acesta vizitează tabelul și aruncă o privire în sus, trebuie să afișeze numărul de pe afișaj care simbolizează cantitatea de situații pe care pinul a crescut. Acest lucru poate fi benefic, deoarece nu stabilim care ar putea fi cifra până când PIC nu își va realiza estimarea.

Prin utilizarea unui tabel, suntem capabili să permitem PIC să determine ce cifră să fie prezentată. În acest moment, înainte de a vă arăta în continuare modul în care funcționează tabelul de date, ar trebui să vă spun că PIC menține calea unde se află în programul în care se află în timp ce programul funcționează.

Facilitează pentru cei care au efectuat anumite programe în BASIC. În caz contrar, nu vă faceți griji, poate doriți să aflați în continuare despre teorie. Prevedeți că există un program BASIC similar cu cel prezentat mai jos:

10 ANI K = 0
11 K = K + 1
12 IF K> 10 THEN GOTO 20 ELSE GOTO 11
20 PRINT K
21 SFÂRȘIT

Programul începe la linia 10. De îndată ce K este programat la 0, urmează să treacă la linia 11. După ce am inclus de la 1 la K, vom trece la linia 12.

În acest moment am putea fi curioși dacă K este mai mare de 10. În cazul în care este, apoi ne îndreptăm spre linia 20 sau altfel ne întoarcem la linia 11.

Linia 20 documentează K, iar linia 21 încheie programul. BASIC folosește statistici de linie pentru a-l ajuta pe programator să țină o evidență a problemelor, deoarece etichetele nu sunt autorizate. PIC folosește etichete pentru a scăpa între destinații - sau poate cu adevărat?

Folosim etichetele pentru a ne asigura că suntem conștienți de problemele aflate, precum și pentru a ne asigura că putem informa PIC într-un mod simplu unde să căutăm.

Tocmai ceea ce se întâmplă este că PIC profită de un contor de linie interioară numit Program Counter. Programul Contor (abreviat la PC) urmărește destinația de memorie a locului în care se află instrucțiunea actuală.

Ori de câte ori informăm PIC să viziteze o etichetă selectată, acesta înțelege locul de memorie și, prin urmare, mărește computerul până când vede destinația de memorie respectivă. Aceasta este exact aceeași metodă pe care am verificat-o programul BASIC de mai sus. Mai jos este un segment de cod, cu spațiile de memorie sau elementele computerului, lângă fiecare instrucțiune:

Instrucțiuni PC0000 movlw 03
0001 movwf 0C
0002 Buclă decfsc 0C
0003 Goto Loop
0004 sfârșit

În demonstrația de mai sus, am fixat PC-ul la 0000. Pe aceasta avem instrucțiunea movlw 03. Când PIC a implementat aceste date, crește PC-ul pentru ca instrucțiunea ulterioară să fie scanată. În acest moment, PIC vizualizează movwf 0C. PC-ul este incrementat din nou.

Acum PIC studiază decfsc 0C. În cazul în care detaliile 0C nu sunt 0, în acest caz PC-ul este incrementat cu 1, precum și următoarea instrucțiune, goto Loop, informează PC-ul să revină la poziția 0003, care este bucla menționată. În cazul în care detaliile 0C sunt 0, atunci se recomandă computerului să crească cu 2, pur și simplu omiteți instrucțiunile ulterioare.

Înțelegerea tabelelor de date

Aceasta plasează computerul în poziția 0004, în care programul se termină. Destinațiile sunt stabilite de asamblor și, în general, nu ar trebui să ne preocupăm ce realizează computerul. Până când, găsim necesitatea de a-l pune sub control la fel ca atunci când o facem atunci când folosim tabele de date. Cel mai convenabil mod de a descrie modul în care funcționează un tabel de date este să începeți cu o ilustrare.

PC equ 02
movlw 03
masa de apel
:
masa addwf PC
retlw 01
retlw 02
retlw 03
retlw 04
retlw 05
retlw 06
retlw 07
întoarcere

Instrucțiunea inițială alocă eticheta PC cu adresa contorului de programe (02h). Vom fi la scurt timp după introducerea valorii de 03h în registrul w. După aceea, comunicăm la masă. Cea mai importantă linie din tabelul subrutine mărește detaliile registrului W (03h) la contorul de programe.

Acest lucru declanșează contorul programului să crească cu 3 sau, în alt mod, stimulează contorul programului să coboare cu 3 linii. În timp ce contorul ajunge cu 3 linii în jos, PIC recunoaște instrucțiunile înapoi. Această comandă trimite valoarea care o urmează în registrul W, după care revine din subrutină. RETLW înseamnă practic Întoarcere, Literal la W.

Vezi Am plasat o virgulă după cuvântul Întoarcere. Deoarece suntem într-un subrutină, avem nevoie de o instrucțiune de returnare la suprafața acestuia. Prin urmare, RET în instrucțiune. După ce instrucțiunea RETLW este un număr, acesta este exact ceea ce este introdus în registrul W.

În acest caz, este figura 3. Am putea desemna orice cantitate în registrul W, atâta timp cât această cifră este combinată cu Contorul de programe din subrutina tabelului, vom descoperi o instrucțiune de retlw. În ilustrația de mai sus, acest lucru înseamnă că suntem capabili să posedăm orice număr de la 1 la 7. În cazul în care depășim subrutina, s-ar putea să putem finaliza efectuarea unei secțiuni suplimentare a programului. Din acest motiv, este de obicei o mișcare inteligentă de a plasa tabelul de date exact spre sfârșitul programului PIC, prin urmare, dacă depășim în acest caz, vom ajunge oricum la încheierea programului.

Subiectul întreruperilor poate fi cel mai lung și mai greu de parcurs.

Nu puteți găsi nicio metodă simplă de detaliere a întreruperilor, cu toate acestea, cu puțin noroc spre sfârșitul acestei părți, puteți aplica intreruperi în propriile programe.
Am separat secțiunea în 2 etape. Aceasta este pentru a permite separarea subiectului în secțiuni, de asemenea, pentru a vă oferi o plită la îndemână pentru înțelegere ușoară.

Ce este mai exact o întrerupere? Cu siguranță, așa cum indică termenul, o întrerupere este o tehnică sau un semnal care împiedică un microprocesor / microcontroler să efectueze orice lucru diferit.

Permiteți-mi să vă dau o ilustrație zilnică. Credeți că vă relaxați în propria casă, conversând cu o altă persoană. Dintr-o dată sună telefonul.

Nu mai vorbiți și luați telefonul pentru a vorbi cu apelantul. Odată ce ați avut interacțiunea telefonică, decideți să reveniți la conversația cu persoana respectivă înainte ca telefonul să sune. Este posibil să luați în considerare rutina principală în timp ce discutați cu cineva, sunetul telefonului vă va întrerupe conversația, iar pauza în rutină este metoda de a vorbi la telefon.

În timp ce discuția telefonică se încheie, atunci reveniți la rutina dvs. principală de chat. Această ilustrație este exact modul în care întrerupe un procesor să acționeze.

Programul principal funcționează, îndeplinind anumite funcții într-un circuit, totuși, atunci când are loc o întrerupere, programul primar se oprește în timp ce se efectuează o rutină diferită. rutina se termină, procesorul revine la rutina primară la fel ca înainte.

Înțelegerea întreruperilor

PIC are 4 surse de întrerupere. Acestea ar putea fi împărțite în câteva grupuri. Două sunt surse de întreruperi care pot fi utilizate în exterior către PIC, în timp ce celelalte două sunt procese interioare. Permiteți-mi să clarific cele două tipuri externe aici. Celelalte două vor fi descrise în diferite tutoriale odată ce ajungem la temporizatoare și stocăm date.

Dacă verificați pin-out-ul PIC, veți observa că pinul 6 este RB0 / INT. În acest moment, RB0 este clar portul B bit 0. INT reprezintă faptul că ar putea fi la fel de bine configurat ca un pin de întrerupere exterior. Mai mult decât atât, pinii portului B 4 la 7 (pinii 10 la 13) pot fi utilizați și pentru întreruperi. Înainte de a putea utiliza INT sau un alt port B, trebuie să îndeplinim două sarcini. În primul rând trebuie să informăm PIC că vom folosi întreruperi.

În continuare, trebuie să desemnăm care port B va fi folosit ca întrerupere, mai degrabă decât ca I / O pin. În interiorul PIC puteți găsi un registru cunoscut sub numele de INTCON și se află la adresa 0Bh. În acest registru veți descoperi 8 biți care pot fi activați sau dezactivați. Bitul 7 al INTCON este cunoscut sub numele de GIE. Aceasta este Activarea globală a interogării. Fixând acest lucru la 1 informează PIC că vom folosi o întrerupere.

Bitul 4 din INTCON este cunoscut sub numele de INTE, INTerrupt Enable. Punerea acestui bit la 1 transmite PIC că RB0 va fi un pin de întrerupere. Configurarea bitului 3, numit RBIE, informează PIc că vom folosi portul B biții 4 până la 7. În acest moment, PIC înțelege când acest pin poate fi ridicat sau scăzut, trebuie să oprească performanțele și să continue cu o întrerupere rutină. În acest moment, trebuie să informăm PIC dacă întreruperea va fi sau nu probabil pe marginea ascendentă (0V la + 5V) sau transformarea marginii descendente (+ 5V la 0V) a semnalului.

Pur și simplu, dorim ca PIC să întrerupă de fiecare dată când semnalul se deplasează de la cel mai mic la cel mai mare sau de la cel mai mare la cel mai mic. Prin delincvență, acest lucru poate fi stabilit pentru a fi plasat pe marginea ascendentă.

„Declanșarea” marginii este programată într-un registru suplimentar numit registru OPȚIUNE, la adresa 81h. Bitul care ne entuziasmează este bitul 6, denumit adesea INTEDG.

Setarea acestuia la 1 declanșează PIC să se întrerupă pe marginea de montare (stare implicită) și setarea la 0 stimulează PIC să se întrerupă pe marginea glisantă. Dacă doriți ca PIC să se activeze pe marginea ascendentă, atunci cu siguranță nu trebuie să faceți nimic pentru acest bit.

În acest moment, din păcate, registrul de opțiuni se află în banca 1, ceea ce înseamnă că ne bucurăm să modificăm de la banca 0 la banca 1, să setăm bitul în registrul de opțiuni, după revenirea la banca 0. Cheia de aici este să realizăm fiecare bit al Băncii 1 se înregistrează într-o singură grevă, de exemplu stabilirea pinilor portului, după aceea revenirea la Banca 0 dacă ați terminat.

Bine, în consecință, am notificat PIC care pin va fi probabil întreruperea și unde se va declanșa marginea, ce se întâmplă în program și PIC de fiecare dată când are loc întreruperea? Au loc câteva lucruri. În primul rând, este programat un „steag”.

Aceasta informează procesorul intern al PIC că a avut loc o întrerupere. Apoi, contorul de programe (despre care am vorbit în cadrul tutorialului anterior) sugerează o adresă specifică din PIC. Să verificăm rapid toate acestea individual. Semnalizator de întrerupere În registrul nostru INTCON, bitul 1 este semnalizatorul de întrerupere, numit INTF. În acest moment, ori de câte ori apare o întrerupere, acest semnal va fi probabil fixat la 1.

Când nu există o întrerupere, steagul este plasat la 0. Pe lângă faptul că este vorba despre toate realizările. În acest moment s-ar putea să vă gândiți la „ce rost are?” Sigur, chiar dacă acest semnal este programat la 1, PIC nu este capabil și nu va reacționa la o altă întrerupere. Prin urmare, să exprimăm faptul că provocăm o întrerupere. Semnalizatorul va fi probabil fixat la 1, iar PIC ar putea merge la rutina noastră pentru a lucra la întrerupere.

Când acest semnal nu a fost fixat la 1, iar PIC-ului i s-a permis să răspundă în continuare la întrerupere, atunci pulsarea continuă a pinului ar putea face ca PIC să revină la începutul rutinei noastre de întrerupere și să nu-l completeze în niciun caz. Revenind la ilustrația mea despre telefon, este similar cu ridicarea telefonului și imediat după ce discutați, începe să sune din nou, deoarece o altă persoană dorește să vorbească cu dvs.

Este recomandabil să finalizați un dialog, apoi să apucați din nou telefonul pentru a vorbi cu persoana care urmează. Puteți găsi o mică problemă cu acest steag. Chiar dacă PIC setează rapid acest steag la 1, nu îl setează din nou 0! Această activitate trebuie să fie exercitată de programator - adică de dvs. Acest lucru poate fi realizat fără efort, deoarece sunt sigur, și trebuie realizat după ce PIC a efectuat rutina de întrerupere.

Locația memoriei Ori de câte ori porniți inițial PIC-ul sau în cazul în care există o resetare, contorul de programe vă sfătuiește să adresați 0000h, care ar putea fi imediat de la începutul memoriei programului. Dar, în cazul în care există o întrerupere, Contorul programului ar indica adresa 0004h.

Prin urmare, în timp ce compunem programul nostru care va avea întreruperi, trebuie mai întâi să informăm PIC să treacă peste adresa 0004h și să mențină rutina de întrerupere care începe la adresa 0004h discretă din restul programului.

Acest lucru poate fi realizat fără probleme. Inițial, începem programul nostru cu o comandă cunoscută sub numele de ORG. Această comandă indică Origin, sau start. Ne ținem de ea cu o adresă. Deoarece PIC începe la adresa 0000h, tastăm ORG 0000h. După aceea, trebuie să trecem peste adresa 0004h. Realizăm acest lucru punând o instrucțiune GOTO, însoțită de o etichetă care indică programul nostru principal.

După aceea, aderăm la această comandă GOTO cu încă un ORG, în acest moment cu adresa 0004h. După această comandă vom introduce rutina noastră de întrerupere. În acest moment, am putea fi în măsură să tastați rutina noastră de întrerupere imediat după a doua comandă ORG sau putem poziționa o instrucțiune GOTO care indică rutina de întrerupere.

Este cu adevărat legat de opțiunea din partea ta. Pentru a informa PIC-ul pe care îl oferă a ajuns la încheierea rutinei de întrerupere, trebuie să poziționăm comanda RTFIE spre sfârșitul rutinei. Această comandă înseamnă revenirea din rutina de întrerupere. În timp ce PIC observă acest lucru, Contorul de program indică poziția finală în care se afla PIC înainte de apariția întreruperii. Am stabilit mai jos o scurtă secțiune de cod pentru a afișa cele de mai sus:

Există câteva lucruri pe care ar trebui să le informați atunci când utilizați întreruperile. Inițialul tinde să fie că, dacă s-ar putea să utilizați registrul identic în programul dvs. principal și rutina de întrerupere, având în vedere că detaliile registrului se vor modifica cel mai probabil atunci când are loc întreruperea.

De exemplu, să utilizăm registrul w pentru a redirecționa date către programul principal Port A, prin urmare puteți utiliza în plus registrul w în rutina de întrerupere pentru a muta datele de la o destinație la alta.

În cazul în care nu sunteți precaut, registrul w ar include ultima valoare pe care a primit-o în timp ce a fost în rutina de întrerupere, așa că atunci când reveniți de la întrerupere, aceste informații vor fi livrate în Portul A, mai degrabă decât valoarea pe care ați avut-o înainte a avut loc întreruperea.

Mijlocul în jurul acestui lucru este să salvați momentan detaliile registrului w înainte de a-l utiliza din nou în rutina de întrerupere. Al doilea este faptul că puteți găsi o întârziere între momentul în care are loc o întrerupere și momentul în care poate apărea următoarea. În timp ce înțelegeți, PIC are un ceas exterior, care ar putea fi un cristal sau ar putea fi un combo rezistor-condensator.

Indiferent de frecvența acestui ceas, PIC îl împarte la 4, după care folosește acest lucru pentru sincronizarea interioară. De exemplu, în cazul în care aveți un cristal de 4 MHz conectat la PIC, în acest caz, PIC va efectua instrucțiunile la 1 MHz. Această sincronizare interioară este cunoscută ca un ciclu de instrucțiuni. În acest moment, foaia tehnică susține (fără îndoială, în minuscule tipăriri) că trebuie să activați 3 până la 4 runde de instrucțiuni între întreruperi.

A mea ar fi să activez 4 runde. Motivul care stă la baza întârzierii este că PIC necesită timp pentru a trece la adresa de întrerupere, la steag, și a ajunge înapoi departe de rutina de întrerupere. Prin urmare, păstrați acest lucru în minte dacă lucrați cu un circuit alternativ pentru a activa o întrerupere pentru PIC.

În acest moment, un punct este faptul că, dacă utilizați biții 4 până la 7 din Portul B ca întrerupere. Nu puteți alege pini specifici din portul B pentru a funcționa ca o întrerupere.

Prin urmare, în cazul în care permiteți acești pini, este posibil ca acestea să poată fi obținute. Prin urmare, de exemplu, nu puteți avea pur și simplu biții 4 și 5 - biții 6 și 7 vor fi probabil împuterniciți în același timp. Care este exact scopul de a obține patru biți pentru a reprezenta o întrerupere? Cu siguranță, s-ar putea să aveți un circuit conectat la PIC, în cazul în care oricare dintre cele patru linii se ridică, în acest caz aceasta poate fi o problemă pe care trebuie să o influențați instantaneu.

O ilustrare a acestui lucru ar putea fi o alarmă de securitate la domiciliu, în care patru senzori sunt conectați la pinii de la portul B 4 la 7. Orice senzor specific poate solicita PIC să declanșeze o alarmă, iar rutina de semnalizare a alarmei este rutina de întrerupere. Acest lucru economisește verificarea porturilor în mod constant și permite PIC să continue cu diferite probleme. În următorul tutorial, vom compune un program pentru a gestiona o întrerupere.

Ne-am ocupat de o mulțime de elemente de bază în cadrul ultimului tutorial, prin urmare, simt că a sosit momentul ca noi să compunem primul nostru program.

Programul pe care îl vom scrie va calcula cantitatea de ocazii în care pornim un comutator și apoi vom afișa numărul.

Programul va conta de la 0 la 9, vizibil pe 4 LED-uri în formă binară, împreună cu intrarea sau întreruperea va fi probabil pe RB0.

Primul lucru pe care trebuie să îl facem este să informăm PIC să treacă peste adresa la care indică Contorul de program ori de câte ori are loc o întrerupere.

Veți observa că folosim o metodă unică de a expune numere hexazecimale. Înainte de întâmplare, aplică F9h în care h indica hexadecimal. Am putea scrie acest lucru ca 0xF9, care este structura pe care o vom folosi de acum înainte.

Acum trebuie să spunem PIC că vom folosi întreruperi și că folosim pinul RB0 6 ca pin de întrerupere:

bsf INTCON, 7GIE - Activare întrerupere globală (1 = activare)
bsf INTCON, 4INTE - Activare întrerupere RB0 (1 = activare)
Voi șterge steagul de întrerupere pentru orice eventualitate (nu am încredere niciodată în nimic!)
bcf INTCON, 1INTF - Ștergeți bitul de semnalizare pentru orice eventualitate

În prezent trebuie să ne stabilim cele 2 porturi. Rețineți că, deoarece utilizăm acum RB0 ca pin de întrerupere, acest lucru trebuie stabilit ca intrare:

Vom folosi o variabilă numită COUNT pentru a stoca numărul de comutatoare. Am putea pur și simplu să creștem valoarea portului A, dar veți vedea de ce folosesc o variabilă atunci când scriem rutina noastră de întrerupere.

Prin urmare, programul nostru principal este compus și, în acest moment, trebuie să informăm PIC cum să procedăm ori de câte ori are loc o întrerupere. În acest exemplu, întreruperea noastră va fi probabil comutatorul. Doar ceea ce ne-am dori să fie PIC este unul pentru COUNT-ul reglabil de fiecare dată când comutatorul este limitat.

Cu toate acestea, dorim doar să arătăm câte ocazii se oprește comutatorul de la 0 la 9. Mai sus, am afirmat că am putea fi în măsură să creștem pur și simplu valoarea portului A de fiecare dată când există o întrerupere. Cu toate acestea, Portul A are 5 biți, în cazul în care pur și simplu am incrementat portul, vom avea cel mai mare număr de 31. Există câteva explicații de ce am selectat să nu trec la 31.

Inițial, vom folosi un ecran cu 7 segmente, care cel mult ar putea merge doar de la 0 la 15 (0 la F în hex.). În continuare, doresc în plus să vă arăt câteva dintre comenzile aritmetice cu care v-ați împiedicat în ultimele lecții.

Prin urmare, vom continua cu rutina noastră de întrerupere. În prezent, primul lucru pe care trebuie să-l realizăm este să stocăm pe scurt detaliile registrului nostru w, deoarece am aplicat acest lucru pentru a muta conținutul COUNT la PORTA. În cazul în care nu îl salvăm, în acest caz am putea livra un număr total diferit din cauza aritmeticii noastre. Prin urmare, să realizăm mai întâi acest lucru:

În acest moment, înțelegem dacă valoarea COUNT este de 9 sau mai mult. Ceea ce trebuie să realizăm acum este dacă COUNT este mai mare de 9, puneți-l înapoi la 0 sau altfel reveniți la programul principal pentru a ne asigura că suntem capabili să îl livrăm în Portul A. Comanda BTFSS, deoarece înțelegeți că ar urma
instrucțiune în cazul în care pavilionul de transport este programat, adică COUNT = 10:

Singurul lucru care rămâne de făcut acum este să introducem colectiv, precum și să stabilim valorile constantelor noastre, pe care le putem realiza chiar la începutul programului nostru.

De fiecare dată când activați comutatorul, LED-urile vor fi numărate în binar de la 0000 la 1010 și apoi la 0000.

Următoarea figură arată schema de circuite compatibilă cu codul explicat mai sus. Interesant, veți găsi că condensatorul de sincronizare a fost inclus în proiectare. Aceasta este o manevră minunată prin care obțineți libertatea de a evita includerea condensatorului în cazul în care nu aveți niciunul cu dvs. în acel timp.

Aici capacitatea intră în joc prin intermediul capacității rătăcite de-a lungul pinului oscilatorului și al solului.
Desigur, s-ar putea să nu pară o modalitate foarte inteligentă de a evita practic un condensator, deoarece valoarea rătăcită poate varia în funcție de condițiile date.

O altă secțiune care poate fi asistată în circuit este rețeaua de denunțare de pe switch. Aceasta previne interferențele în timpul comutării mecanice și împiedică confuzia PIC dacă comutarea a fost o singură comutare sau mai multe comutatoare.




Precedent: Circuit temporizator motor bidirecțional programabil Următorul: Cum funcționează circuitele Buck-Boost