Creeaza.com - informatii profesionale despre


Cunostinta va deschide lumea intelepciunii - Referate profesionale unice
Acasa » tehnologie » electronica electricitate
Microcontrolerul PIC16F84

Microcontrolerul PIC16F84


Microcontrolerul PIC16F84

Introducere

CISC, RISC
Aplicatii
Clock-ul/instructiune
Pipelining
Semnificatia pinilor

1 Generator-oscilator de ceas
2 Reset
3 Unitatea de procesare centrala
4 Porturi
5 Organizarea memoriei
6 Intreruperi
7 Timer-ul liber TMRO
8 Memoria de date EEPROM

Introducere

PIC16F84 apartine unei clase de microcontrolere de 8 biti cu arhitectura RISC. Structura lui generala este aratata in schita urmatoare reprezentand blocurile de baza.

Memoria program (FLASH)-pentru memorarea unui program scris.
Pentru ca memoria ce este facuta in tehnologia FLASH poate fi programata si stearsa mai mult decat odata, aceasta face microcontrolerul potrivit pentru dezvoltarea de componenta.



EEPROM-memorie de date ce trebuie sa fie salvate cand nu mai este alimentare.
Este in mod uzual folosita pentru memorarea de date importante ce nu trebuie pierdute daca sursa de alimentare se intrerupe dintr-o data. De exemplu, o astfel de data este o temperatura prestabilita in regulatoarele de temperatura. Daca in timpul intreruperii alimentarii aceasta data se pierde, va trebui sa facem ajustarea inca o data la revenirea alimentarii. Astfel componenta noastra pierde in privinta auto-mentinerii.

RAM-memorie de date folosita de un program in timpul executarii sale.
In RAM sunt memorate toate rezultatele intermediare sau datele temporare ce nu sunt cruciale la intreruperea sursei de alimentare.

PORTUL A si PORTUL B sunt conexiuni fizice intre microcontroler si lumea de afara. Portul A are 5 pini, iar portul B are 8 pini.

TIMER-UL LIBER (FREE-RUN) este un registru de 8 biti in interiorul microcontrolerului ce lucreaza independent de program. La fiecare al patrulea impuls de ceas al oscilatorului isi incrementeaza valoarea lui pana ce atinge maximul (255), si apoi incepe sa numere tot din nou de la zero. Dupa cum stim timpul exact dintre fiecare doua incrementari ale continutului timer-ului, poate fi folosit pentru masurarea timpului ce este foarte util la unele componente.

UNITATEA DE PROCESARE CENTRALA are rolul unui element de conectivitate intre celelalte blocuri ale microcontrolerului. Coordoneaza lucrul altor blocuri si executa programul utilizatorului.

CISC, RISC

S-a spus deja ca PIC1684 are o arhitectura RISC. Acest termen este adeseori gasit in literatura despre calculatoare, si are nevoie sa fie explicat aici mai in detaliu. Arhitectura Harvard este un concept mai nou decat von-Neumann. S-a nascut din nevoia de marire a vitezei microcontrolerului. In arhitectura Harvard, bus-ul de date si bus-ul de adrese sunt separate. Astfel este posibil un mare debit de date prin unitatea de procesare centrala, si bineinteles, o viteza mai mare de lucru. Separarea programului de memoria de date face posibil ca mai departe instructiunile sa nu trebuiasca sa fie cuvinte de 8 biti. PIC16F84 foloseste 14 biti pentru instructiuni ceea ce permite ca toate instructiunile sa fie instructiuni dintr-un singur cuvant. Este de asemenea tipic pentru arhitectura Harvard sa aiba mai putine instructiuni decat von-Newmann si sa aiba instructiuni executate uzual intr-un ciclu.

Microcontrolerele cu arhitectura Harvard sunt de asemenea numite 'microcontrolere RISC'. RISC inseamna Reduced Instruction Set Computer. Microcontrolerele cu arhitectura von-Newmann sunt numite 'microcontrolere CISC'. Titlul CISC inseamna Complex Instruction Set Computer.

Pentru ca PIC16F84 este un microcontroler RISC, aceasta inseamna ca are un set redus de instructiuni, mai precis 35 de instructiuni (de ex. microcontrolerele INTEL si Motorola au peste 100 de instructiuni). Toate aceste instructiuni sunt executate intr-un ciclu cu exceptia instructiunilor jump si branch. Conform cu ceea ce spune constructorul, PIC16F84 ajunge la rezultate de 2:1 in compresia cod si 4:1 in viteza in comparatie cu alte microcontrolere de 8 biti din clasa sa.

Aplicatii

PIC16F84 se potriveste perfect in multe folosinte, de la industriile auto si aplicatiile de control casnice la instrumentele industriale, senzori la distanta, manere electrice de usi si dispozitivele de securitate. Este de asemenea ideal pentru cardurile smart ca si pentru aparatele alimentate de baterie din cauza consumului lui mic.

Memoria EEPROM face mai usoara aplicarea microcontrolerelor la aparate unde se cere memorarea permanenta a diferitor parametri (coduri pentru transmitatoare, viteza motorului, frecventele receptorului, etc.). Costul scazut, consumul scazut, manuirea usoara si flexibilitatea fac PIC16F84 aplicabil chiar si in domenii unde microcontrolerele nu au fost prevazute inainte (exemple: functii de timer, inlocuirea interfetei in sistemele mari, aplicatiile coprocesor, etc.).
Programabilitatea sistemului acestui cip (impreuna cu folosirea a doar doi pini in transferul de date) face posibila flexibilitatea produsului, dupa ce asamblarea si testarea au fost terminate. Aceasta capabilitate poate fi folosita pentru a crea productie pe linie de asamblare, de a inmagazina date de calibrare disponibile doar dupa testarea finala, sau poate fi folosit pentru a imbunatati programele la produsele finite.

Clock-ul /ciclul instructiune

Clock-ul sau ceasul este starter-ul principal al microcontrolerului, si este obtinut dintr-o componenta de memorie externa  numita 'oscilator'. Daca ar fi sa comparam un microcontroler cu un ceas de timp, 'clock-ul' nostru ar fi un ticait pe care l-am auzi de la ceasul de timp. In acest caz, oscilatorul ar putea fi comparat cu arcul ce este rasucit astfel ca ceasul de timp sa mearga. De asemenea, forta folosita pentru a intoarce ceasul poate fi comparata cu o sursa electrica.

Clock-ul de la oscilator intra intr-un microcontroler prin pinul OSC1 unde circuitul intern al microcontrolerului divide clock-ul in 4 clock-uri egale Q1, Q2, Q3 si Q4 ce nu se suprapun. Aceste 4 clock-uri constituie un ciclu de o singura instructiune (numit de asemenea ciclu masina) in timpul careia instructiunea este executata.

Executarea instructiunii incepe prin apelarea unei instructiuni care este urmatoarea in linie. Instructiunea este apelata din memoria program la fiecare Q1 si este scrisa in registrul de instructiuni la Q4. Decodarea si executarea instructiunii sunt facute intre urmatoarele cicluri Q1 si Q4. In urmatoarea diagrama putem vedea relatia dintre ciclul instructiunii si clock-ul oscilatorului (OSC1) ca si aceea a clock-urilor interne Q1-Q4. Contorul de program (PC) retine informatia despre adresa urmatoarei instructiuni.

Pipelining

Ciclul instructiune consta din ciclurile Q1, Q2, Q3 si Q4. Ciclurile de instructiuni de apelare si executare sunt conectate intr-un asa fel incat pentru a face o apelare, este necesar un ciclu cu o instructiune, si mai este nevoie de inca unul pentru decodare si executare. Totusi, datorita pipelining-ului (folosirea unei pipeline-conducta, si este aducerea unei instructiuni din memorie in timp ce se executa alta), fiecare instructiune este executata efectiv intr-un singur ciclu. Daca instructiunea cauzeaza o schimbare in contorul programului, si PC-ul nu directioneaza spre urmatoarea ci spre alte adrese (poate fi cazul cu subprogramele jumps sau calling), 2 cicluri sunt necesare pentru executarea unei instructiuni. Aceasta este pentru ca instructiunea trebuie procesata din nou, dar de data aceasta de la adresa corecta. Ciclul incepe cu clock-ul Q1, prin scrierea in registrul instruction register (IR). Decodarea si executarea incepe cu clock-urile Q2, Q3 si Q4.

TYC0 citeste instructiunea MOVLW 55h (nu are importanta pentru noi ce instructiune a fost executata, ce explica de ce nu este un dreptunghi  desenat in partea de jos).
TCYI executa instructiunea MOVLW 55h si citeste MOVWF PORTB.
TCY2 executa MOVWF PORTB si citeste CALL SUB_1.
TCY3 executa o apelare a subprogramului CALL SUB_1, si citeste instructiunea BSF PORTA, BIT3. Pentru ca instructiunea aceasta nu este aceea de care avem nevoie, sau nu este prima instructiune a subprogramului SUB_1 a carei executie este urmatoarea in ordine, instructiunea trebuie citita din nou.
Acesta este un bun exemplu a unei instructiuni avand nevoie de mai mult de un ciclu. TCY4 ciclul instructiunii este total folosit pentru citirea primei instructiuni din subprogram la adresa SUB_1.
TCY5 executa prima instructiune din subprogram SUB_1 si citeste urmatoarea.

Semnificatia pinilor

PIC16F84 are un numar total de 18 pini. Cel mai adesea se gaseste intr-o capsula de tip DIP18 dar se poate gasi de asemenea si intr-o capsula SMD care este mai mica ca cea DIP. DIP este prescurtarea de la Dual In Package. SMD este prescurtarea de la Surface Mount Devices sugerand ca gaurile pentru pini unde sa intre acestia, nu sunt necesare in lipirea acestui tip de componenta.

Pinii microcontrolerului PIC16F84 au urmatoarea semnificatie:

Pin nr.1 RA2 Al doilea pin la portul A. Nu are functie aditionala.
Pin nr.2 RA3 Al treilea pin la portul A. Nu are functie aditionala.
Pin nr.3 RA4 Al patrulea pin la portul A. TOCK1 care functioneaza ca timer se gaseste de asemenea la acest pin.
Pin nr.4 MCLR Reseteaza intrarea si tensiunea de programare Vpp a microcontrolerului.
Pin nr.5 VSS Alimentare, masa. Pin nr.6 RB0 Pin de zero la portul B. Intrarea Intrerupere este o functie aditionala. Pin nr.7 RB1 Primul pin la portul B. Nu are functie aditionala. Pin nr.8 RB2 Al doilea pin la portul B. Nu are functie aditionala. Pin nr.9 RB3 Al treilea pin la portul B. Nu are functie aditionala. Pin nr.10 RB4 Al patrulea pin la portul B. Nu are functie aditionala.
Pin nr.11 RB5 Al cincilea pin la portul B. Nu are functie aditionala.
Pin nr.12 RB6 Al saselea pin la portul B. Linia de 'Clock' in mod programare.
Pin nr.13 RB7 Al saptelea pin la portul B. Linia 'Data' in mod programare.
Pin nr.14 Vdd Polul pozitiv al sursei.
Pin nr.15 OSC2 Pin desemnat pentru conectarea la un oscilator.
Pin nr.16 OSC1 Pin desemnat pentru conectarea la un oscilator.
Pin nr.17 RA2 Al doilea pin la portul A. Nu are functie aditionala.
Pin nr.18 RA1 Primul pin la portul A. Nu are functie aditionala.


1 Generator de ceas - oscilator

Circuitul oscilator este folosit pentru a da microcontrolerului un ceas-clock. Ceasul este necesar pentru ca microcontrolerul sa execute programul sau instructiunile din program.

Tipuri de oscilatoare 

PIC16F84 poate lucra cu patru configuratii diferite de oscilator. Pentru ca configuratiile cu oscilator cu cristal si rezistor-condensator (RC) sunt cele utilizate cel mai frecvent, doar pe ele le vom mentiona aici. Tipul de microcontroler cu oscilator cu cristal este desemnat ca XT, iar microcontrolerul cu perechea rezistor-condensator are desemnarea RC. Aceasta este important pentru ca trebuie sa numiti tipul de oscilator cand cumparati un microcontroler.  

Oscilatorul XT

Oscilatorul cu cristal se afla intr-o carcasa metalica cu doi pini pe care este inscrisa frecventa la care cristalul oscileaza. Mai este necesar cate un condensator ceramic de 30pF cu celalalt capat la masa de a fi conectati la fiecare pin.

Oscilatorul si condensatorii pot fi incapsulati impreuna intr-o carcasa cu trei pini. Un asemenea element se numeste rezonator ceramic si este reprezentat in scheme ca cel de mai jos. Pinii centrali ai elementului sunt masa, iar pinii terminali sunt conectati la pinii OSC1 si OSC2 ai microcontrolerului. Cand se proiecteaza un aparat, regula este sa plasati oscilatorul cat mai aproape de microcontroler, pentru a elimina orice interferenta de pe liniile pe care microcontrolerul primeste tactul de ceas.



Oscilatorul RC

In aplicatiile unde nu este nevoie de o mare precizie de timp, oscilatorul RC permite economii aditionale la cumparare. Fecventa de rezonanta a oscilatorului RC depinde de valoarea tensiunii de alimentare, rezistorul R, condensatorul C si temperatura de lucru. Trebuie de mentionat ca frecventa de rezonanta este de asemenea influentata de variatiile normale ale parametrilor de proces, de toleranta externa a componentelor R si C, etc.

Diagrama de mai sus arata cum este conectat oscilatorul RC la PIC16F84. La valoarea rezistorului mai mica 2k, oscilatorul poate deveni instabil, sau oscilatia se poate chiar opri. La valori mari a lui R (ex.1M) oscilatorul devine foarte sensibil la zgomot si umezeala. Se recomanda ca valoarea rezistorului R sa fie intre 3 si 100k. Chiar daca oscilatorul va lucra fara un condensator extern (C=0pF), trebuie totusi folosit un condensator de peste 20pF pentru zgomot si stabilitate. Indiferent de ce oscilator este folosit, pentru a obtine un ceas la care sa functioneze microcontrolerul, ceasul trebuie divizat la 4. Un ceas al oscilatorului divizat cu 4 se poate obtine la pinul OSC2/CLKOUT, si poate fi folosit pentru testarea sau sincronizarea altor circuite logice.

Dupa alimentare, oscilatorul incepe sa oscileze. Oscilatia la inceput are o perioada si o amplitudine instabile, dar dupa un timp devin stabilizate.

Pentru a preveni ca un asemenea ceas inexact sa influenteze performantele microcontrolerului, trebuie sa tinem microcontrolerul in starea reset pe durata stabilizarii ceasului oscilatorului. Diagrama de mai sus arata o forma tipica de semnal pe care microcontrolerul o primeste de la oscilatorul cu cuart dupa alimentare.



2 Reset-ul

Resetul este folosit pentru a pune microcontrolerul intr-o conditie 'cunoscuta'. Aceasta inseamna practic ca microcontrolerul poate sa se comporte incorect in unele conditii nedorite. Pentru a continua sa functioneze corect trebuie resetat, insemnand ca toti registrii vor fi pusi intr-o stare de start. Resetul nu este folosit numai cand microcontrolerul nu se comporta cum vrem noi, dar poate de asemenea sa fie folosit cand se incearca un montaj ca o intrerupere intr-un program de executie sau cand se pregateste un microcontroler de a citi un program.

Pentru a preveni ajungerea unui zero logic la pinul MCLR accidental (linia de deasupra inseamna ca resetul este activat de un zero logic), MCLR trebuie sa fie conectat printr-un rezistor la polul pozitiv al sursei de alimentare. Rezistorul trebuie sa fie intre 5 si 10k. Acest rezistor a carui functie este de a mentine o anumita linie la starea logica unu ca o prevenire, se numeste o scoatere-pull up.




Microcontrolerul PIC16F84 are cateva surse de reset:

a) Reset la alimentare, POR (Power-On Reset)
b) Reset in timpul lucrului obisnuit prin aducerea unui zero logic la pinul  MCLR al microcontrolerului.
c) Reset in timpul regimului SLEEP
d) Reset la depasirea timer-ului watchdog (WDT)
e) Reset in timpul depasirii WDT in timpul regimului SLEEP.

Cele mai importante resurse de reset sunt a) si b). Prima are loc de fiecare data cand este alimentat microcontrolerul si serveste la aducerea toturor registrilor la starea initiala a pozitiei de start. A doua este pentru a aduce un zero logic la pinul MCLR in timpul operatiei normale a microcontrolerului. Este des folosita in dezvoltarea de programe. 

In timpul unui reset, locatiile de memorie RAM nu sunt resetate. Ele sunt necunoscute la alimentare si nu sunt schimbate la nici un reset. Spre deosebire de acestea, registrii SFR sunt resetati la o stare initiala a pozitiei de start. Unul din cele mai importante efecte ale resetului este setarea contorului de program (PC) la zero (0000h), ceea ce permite programului sa inceapa executarea de la prima instructiune scrisa.


Resetul la scaderea tensiunii de alimentare dincolo de limita permisibila  (Brown-out Reset)

Impulsul pentru resetare in timpul cresterii tensiunii este generat de microcontrolerul insusi cand detecteaza o crestere in tensiunea Vdd (in domeniul de la 1.2V la 1.8V). Acest impuls dureaza 72 ms ceea ce este un timp suficient pentru oscilator ca sa se stabilizeze. Aceste 72 ms sunt asigurate de un timer intern PWRT care are oscilatorul lui RC. Microcontrolerul este in modul reset cat timp PWRT este activ. Totusi, cand montajul functioneaza, probleme apar cand sursa nu scade la zero ci cand scade mai jos de limita ce garanteaza functionarea corecta a microcontrolerului.  Acesta este un caz real din practica, in special in mediile industriale unde perturbatiile si instabilitatile sursei de alimentare sunt ceva foarte curent. Pentru a rezolva aceasta problema trebuie sa ne asiguram ca microcontrolerul este intr-o stare de reset de fiecare data cand tensiunea sursei scade sub limita admisa.

Daca, conform cu specificatiile electrice, circuitul intern de resetare a microcontrolerului nu poate satisface aceste cerinte, se pot folosi componente electronice speciale ce sunt capabile sa genereze semnalul de reset dorit. In afara de aceasta functie, ele pot functiona pentru supravegherea tensiunii de alimentare. Daca tensiunea scade mai jos de nivelul specificat, un zero logic va apare la pinul MCLR ce tine microcontrolerul in starea de reset pana ce tensiunea nu este in limitele ce garanteaza functionarea corecta.



3 Unitatea de Procesare Centrala

Unitatea de procesare centrala (CPU) este creierul microcontrolerului. Aceasta parte este responsabila cu gasirea si aducerea (citirea din memorie)-fetching instructiunii corecte ce trebuie executata, cu decodarea acelei instructiuni, si in final cu executarea ei.

Unitatea de procesare centrala conecteaza toate partile microcontrolerului intr-un intreg. Desigur, functia sa cea mai importanta este sa decodeze instructiunile de program. Cand programatorul scrie un program, instructiunile au o forma clara ca MOVLW 0x20. Totusi, pentru ca microcontrolerul sa inteleaga aceasta, aceasta forma de 'scrisoare' a unei instructiuni trebuie tradusa intr-o serie de zero-uri si unu-uri ce se numeste 'opcode'. Aceasta tranzitie de la o scrisoare la o forma binara este facuta de translatori ca translatorul assembler (cunoscut ca si assembler sau asamblor). Instructiunea astfel adusa-fetched din memoria programului trebuie sa fie decodata de unitatea de procesare centrala. Putem apoi selecta din tabela tuturor instructiunilor un set de actiuni ce executa o sarcina desemnata definita de instructiune. Pentru ca instructiunile pot sa contina in ele asignari ce cer diferite transferuri de date dintr-o memorie in alta, din memorie la porturi, sau alte calcule, CPU trebuie sa fie conectata cu toate partile microcontrolerului. Aceasta este posibil printr-un bus de date si un bus de adrese.

Unitatea de Logica Aritmetica (ALU)

Unitatea de logica aritmetica este responsabila de executarea operatiilor ca adunarea, scaderea, mutarea (la stanga sau la dreapta intr-un registru) si de operatiile logice. Mutarea datelor intr-un registru se mai numeste 'shifting'- transferare. PIC16F84 contine o unitate logica aritmetica de 8 biti si registri de lucru de 8 biti.

In instructiunile cu doi operanzi, in mod obisnuit un operand este in registrul de lucru (registrul W), iar celalalt este unul din registri sau o constanta. Prin operand intelegem continutul asupra caruia se fac unele operatii, iar un registru este oricare din registrii GPR sau SFR. GPR este o prescurtare de la 'General Purposes Registers'-Registri cu Scopuri Generale, iar SFR de la  'Special Function Registers'-Registri cu Functie Speciala. In instructiunile cu un operand, un operand este fie registrul W fie unul din registri. Pe langa operatiile aritmetice si logice, ALU controleaza bitii de stare (biti gasiti in registrul STATUS). Executarea unor instructiuni afecteaza bitii de stare, de care depinde rezultatul insusi. Depinzand de ce instructiune este executata, ALU poate afecta valorile bitilor Carry (C), Digit Carry (DC), si Zero (Z) in registrul STATUS.


Registru STATUS

bit 0 C (Carry) Transfer
Bit care este afectat de operatiile de adunare, scadere si transfer.  
1= transferul produs din bitul cel mai inalt al rezultatului
0= transferul nu s-a produs
Bitul C este afectat de instructiunile ADDWF, ADDLW, SUBLW, SUBWF.

bit 1 DC (Digit Carry) DC Transfer
Bit afectat de operatiile de adunare, scadere si transfer. Spre deosebire de bitul C, acest bit reprezinta transferul din al patrulea loc rezultat. Este setat de adunare cand se intampla un transport de la bitul 3 la bitul 4, sau de scadere cand se intampla imprumut de la bitul 4 la bitul 3, sau de transfer in ambele directii.   
1= transfer produs la al patrulea bit conform cu ordinea, al rezultatului.
0= transferul nu s-a produs
Bitul DC este afectat de instructiunile ADDWF, ADDLW, SUBLW, SUBWF.

bit 2 Z (Zero bit) Indicarea unui rezultat zero.
Acest bit este setat cand rezultatul unei operatii aritmetice sau logice executate este zero. 
1= rezultatul egal cu zero
0= rezultatul nu este egal cu zero

bit 3 PD (Power-down bit)
Bit ce este setat cand microcontrolerul este alimentat atunci cand incepe sa functioneze, dupa fiecare reset obisnuit si dupa executarea instructiunii CLRWDT. Instructiunea SLEEP il reseteaza cand microcontrolerul intra in regimul consum/uzaj redus. Setarea lui repetata este posibila prin reset sau prin pornirea sau oprirea sursei. Starea poate fi triggerata de asemenea de un semnal la pinul RB0/INT, de o schimbare la portul RB, de terminarea scrierii in EEPROM-ul de date intern, si de watchdog de asemenea.
1= dupa ce sursa a fost pornita
0= executarea instructiunii SLEEP

bit 4 TO Time-out ; depasirea-overflow watchdog-ului.
Bitul este setat dupa pornirea sursei si executarea instructiunilor  CLRWDT si SLEEP. Bitul este resetat cand  watchdog-ul ajunge la sfarsit semnaland ca ceva nu este in ordine.
1= depasirea-oveflow nu s-a produs
0= depasirea-overflow s-a produs

bit6:5 RP1:RP0 (Register Bank Select bits-Biti de Selectare a Bancului de Registri)
Acesti doi biti sunt partea superioara a adresei la adresarea directa. Pentru ca instructiunile ce adreseaza memoria direct au doar sapte biti, ei au nevoie doar de inca un bit pentru a adresa cei 256 bytes adica cati are PIC16F84. Bitul  RP1 nu este folosit, dar este lasat pentru expansiuni viitoare ale acestui microcntroler. 
01= primul banc
00= bancul zero

bit 7 IRP (Register Bank Select bit-Bit de Selectare a Bancului de Registri) 
Bit al carui rol este de a fi al optulea bit la adresarea indirecta a RAM-ului intern.
1= bancul 2 si 3
0= bancul 0 si 1 (de la 00h la FFh)

Registrul STATUS contine starea aritmetica ALU (C, DC, Z),  starea RESET (TO, PD) si bitii pentru selectarea bancului de memorie (IRP, RP1, RP0).  Considerand ca selectia bancului de memorie este controlata prin acest registru, el trebuie sa fie prezent in fiecare banc. Bancul de memorie se va discuta mai in detaliu in capitolul Organizarea memoriei. Registrul STATUS poate fi o destinatie pentru orice instructiune, cu oricare alt registru. Daca registrul STATUS este o destinatie pentru instructiunile ce afecteaza bitii Z, DC or C, atunci scrierea in acesti trei biti nu este posibila. 

Registrul OPTION

bit 0:2 PS0, PS1, PS2 (Prescaler Rate Select bit-Bit Selectie Rata Prescaler)
Acesti trei biti definesc bitul de selectie a ratei prescalerului. Ce este un prescaler si cum pot afecta acesti biti functionarea unui microcontroler va fi explicat in sectiunea depre TMRO.

bit 3 PSA (Prescaler Assignment bit-Bit de Asignare Prescaler)
Bit ce asigneaza prescalerul intre TMRO si watchdog.
1= prescalerul este asignat watchdogului
0= prescalerul este asignat timer-ului liber (ree-run) TMRO

bit 4 T0SE (TMR0 Source Edge Select bit-Bit Selectie a Frontului Sursei TMR0)
Daca este permis de a se triggera TMRO prin impulsurile de la pinul RA4/T0CKI, acest bit determina daca aceasta va fi la frontul descrescator sau crescator al unui semnal. 
1= front crescator
0= front descrescator

bit 5 TOCS (TMR0 Clock Source Select bit-Bit Selectie Sursa Ceas TMR0)
Acest pin permite timerului liber (free-run) sa incrementeze starea lui fie de la oscilatorul intern la fiecare ¼ a ceasului oscilatorului, fie prin impulsuri externe la pinul  RA4/T0CKI.
1= impulsuri externe
0= ceas intern 1/4

bit 6 INTEDG (Interrupt Edge Select bit-Bit de Selectie a Frontului Intrerupere)
Daca intreruperea este activata este posibil ca acest bit sa determine frontul la care o intrerupere va fi activata la pinul RB0/INT.
1= front crescator
0= front descrescator

bit 7 RBPU (PORTB Pull-up Enable bit-Bit Enable-Activare Pull-up PORTB) 
Acest bit porneste si opreste rezistorii interni 'pull-up'-scoatere la portul B.
1= Rezistori oprire 'pull-up'
0= Rezistori pornire 'pull-up'



4 Porturi

Portul se refera la un grup de pini ai unui microcontroler ce pot fi accesati simultan, sau la care putem seta combinatia dorita de zero-uri si unu-uri, sau de la care putem citi o stare existenta. Fizic, portul este un registru in interiorul unui microcontroler ce este conectat cu fire la pinii microcontrolerului. Porturile reprezinta conexiunea fizica a Unitatii de Procesare Centrala cu lumea exterioara. Microcontrolerul le foloseste pentru a monitoriza sau controla alte componente sau aparate. Datorita functionalitatii, unii pini au rol dublu ca  RA4/TOCKI de exemplu, care este simultan al patrulea bit la portul A si o intrare externa pentru contorul liber (free-run). Selectia uneia din aceste doua functii ale pinului se face in unul din registrii configurationali.  O ilustratie a acesteia este al cincilea bit T0CS in registrul OPTION. Selectand una din functii cealalta este dezactivata.

Toti pinii portului pot fi definiti ca intrare sau iesire, conform cu nevoile unui montaj ce este in dezvoltare. Pentru a defini un pin ca pin de intrare sau ca pin de iesire, trebuie scrisa combinatia corecta de zero-uri si unu-uri in registrul TRIS. Daca in locul potrivit este scris '1' logic in registrul TRIS, acel pin este pin de intrare, iar daca este valabil contrariul, este un pin de iesire.  Fiecare port are registrul lui TRIS. Astfel, portul A are TRISA la adresa 85h, iar portul B are TRISB la adresa 86h.

PORTB

PORTB are 8 pini legati la el. Registrul adecvat pentru directia datelor este TRISB la adresa 86h. Setarea unui bit in registrul TRISB defineste pinul portului corespunzator ca pin de intrare, si resetarea unui bit in registrul TRISB, defineste pinul portului corespunzator ca pin de iesire. Fiecare pin la PORTB are un rezistor slab intern pull-up (scoatere) (rezistor care defineste o linie la unu logic) care poate fi activat prin resetarea celui de-al saptelea bit RBPU in registrul OPTION. Acesti rezistori 'pull-up' se inchid automat cand pinul portului este configurat ca o iesire. Cand porneste microcontrolerul, 'pull-up'-ii sunt dezactivati. 

Patru pini ai portului PORTB, RB7:RB4 pot cauza o intrerupere, care se intampla cand starea lor se schimba de la unu logic la zero logic si invers. Numai pinii configurati ca intrare pot cauza aceasta intrerupere sa se intample (daca fiecare pin RB7:RB4 este configurat ca o iesire, nu va fi generata o intrerupere la schimbarea starii). Aceasta optiune de intrerupere cu rezistorii 'pull-up' fac mai usoara rezolvarea problemelor din practica, ca de exemplu o tastatura matriceala. Daca randurile tastaturii sunt conectate la acesti pini, fiecare apasare a unei clape va cauza o intrerupere. Microcontrolerul va determina care clapa este apasata in timp ce se proceseaza o intrerupere. Nu se recomanda sa apelati la portul B in timp ce se proceseaza intreruperea.

Exemplul de mai sus arata cum pinii 0, 1, 2, si 3 sunt declarati ca intrare, si pinii 4, 5, 6 si 7 ca iesire.

PORTA

PORTA are 5 pini legati la el. Registrul corespunzator pentru directia datelor este TRISA  la adresa 85h. Ca si la portul B, setarea unui bit in registrul TRISA defineste de asemenea pinul portului corespunzator ca un pin de intrare, si resetarea unui bit in registrul TRISA defineste pinul portului corespunzator ca pin de iesire. 
Al cincilea pin al portului A are functie duala. La acel pin se afla de asemenea o intrare externa pentru timer-ul TMRO. Una din aceste doua optiuni este aleasa prin setarea sau resetarea bitului TOCS (TMR0 Clock Source Select bit-bit de Selectie a Sursei Ceasului TMRO). Acest pin permite timer-ului TMRO sa-si creasca starea fie de la oscilatorul intern fie prin impulsuri externe la pinul RA4/T0CKI.

Exemplul arata cum pinii 0, 1, 2, 3, si 4 sunt declarati ca intrare iar 5, 6 si 7 ca pini de iesire.


5 Organizarea memoriei

PIC16F84 are doua blocuri separate de memorie, unul pentru date si celalalt pentru programe. Memoria EEPROM si registrii GPR in memoria RAM constituie un bloc, si memoria FLASH constituie un bloc de  programe. 

Memoria program

Memoria program a fost realizata in tehnologia FLASH ceea ce face posibil de a programa un microcontroler de mai multe ori inainte de a fi instalat intr-un montaj, si chiar dupa instalarea sa daca se intampla unele schimbari in program sau parametri de proces. Marimea memoriei program este de 1024 locatii cu latime de 14 biti unde locatiile zero si patru sunt rezervate pentru reset si pentru vectorul intrerupere.

Memoria de date

Memoria de date consta din memoriile EEPROM si RAM. Memoria EEPROM consta din 64 de locatii de opt biti a caror continut nu este pierdut in timpul opririi sursei de alimentare. EEPROM-ul nu este direct adresabil, dar este accesat indirect prin registrii EEADR si EEDATA. Pentru ca memoria EEPROM este folosita curent la memorarea unor parametri importanti (de exemplu, o temperatura data in regulatoarele de temperatura), exista o procedura stricta de scriere in EEPROM ce trebuie urmata pentru a preveni scrierea accidentala. Memoria RAM pentru date ocupa un spatiu intr-o harta a memoriei de la locatia 0x0C la 0x4F ceea ce inseamna 68 de locatii. Locatiile memoriei RAM sunt de asemenea denumite registri GPR care este o abreviere General Purpose Registers-Registri cu Scop General. Registrii GPR pot fi accesati indiferent de ce banc este selectat la un moment.   

Registri SFR

Registri ce ocupa primele 12 locatii in bancurile 0 si 1 si sunt registri ai functiei specializate asignata cu unele blocuri ale microcontrolerului. Acestia sunt numiti Special Function Registers-Registri ai Functiei Speciale.

Bancuri de Memorie

In afara de aceasta diviziune in 'lungime' a registrilor SFR si GPR, harta memoriei este de asemenea impartita in 'latime' (vezi harta precedenta) in doua zone numite 'bancuri'. Selectarea unuia din bancuri se face de bitii RPO si RP1 in registrul STATUS-stare. 

Exemplu:
bcf STATUS, RP0

Instructiunea BCF sterge bitul RPO (RP0=0) in registrul STATUS si astfel seteaza bancul 0.

bsf STATUS, RP0

Instructiunea BSF seteaza bitul RPO (RP0=1) in registrul STATUS si astfel seteaza bancul 1.


Uzual, grupurile de instructiuni care sunt adesea in uz, sunt conectate intr-o singura unitate ce poate fi usor apelata intr-un program, si a carei nume are o semnificatie clara, asa-numitul Macros-macrocomanda. Cu ajutorul lor, selectia dintre doua bancuri devine mai clara si programul mult mai elegibil.

BANK0 macro
  Bcf STATUS, RP0   ;Select memory bank 0
  Endm

BANK1 macro
  Bsf STATUS, RP0   ;Select memory bank 1
  Endm

Locatiile 0Ch - 4Fh sunt registri cu scop general (GPR) ce sunt folositi ca memorie RAM. Cand sunt accesate locatiile 8Ch - CFh in Bancul 1, accesam de fapt exact aceleasi locatii in Bancul 0. Cu alte cuvinte, cand doriti sa accesati unul din registrii GPR, nu trebuie sa va ingrijorati ca nu stiti in ce banc sunteti!

Contorul de Program

Contorul de program (PC) este un registru de 13 biti ce contine adresa instructiunii ce se executa. Prin incrementarea sau schimbarea sa (ex. in caz de salturi) microcontrolerul executa instructiunile de program pas-cu-pas.

Stiva

PIC16F84 are o stiva de 13 biti cu 8 nivele, sau cu alte cuvinte, un grup de 8 locatii de memorie de 13 biti latime cu functii speciale. Rolul sau de baza este de a pastra valoarea contorului de program dupa un salt din programul principal la o adresa a unui subprogram. Pentru ca un program sa stie cum sa se intoarca la punctul de unde a pornit, trebuie sa inapoieze valoarea contorului programului din stiva. Cand se muta dintr-un program intr-un subprogram, contorul programului este impins in stiva (un exemplu de acesta este instructiunea CALL). Cand se executa instructiuni ca RETURN, RETLW sau RETFIE ce au fost executate la sfarsitul unui subprogram, contorul programului a fost luat dintr-o stiva, asa ca programul sa poata continua de unde a fost oprit inainte de a fi intrerupt. Aceste operatii de plasare intr-o si luare dintr-o stiva de contor de program sunt numite PUSH si POP, si sunt numite conform cu instructiunile similare ale unor microcontrolere mai mari.


Programarea In Sistem

Pentru a programa o memorie de program, microcontrolerul trebuie sa fie setat pentru un mod de lucru special prin aducerea pinului MCLR la 13.5V, iar sursa de tensiune Vdd trebuie sa fie stabilizata intre 4.5V si 5.5V. Memoria program poate fi programata serial folosind doi pini 'data/clock' ce trebuie sa fie mai intai separati de liniile montajului, asa ca sa nu apara erori in timpul programarii.

Moduri de adresare

Locatiile de memorie RAM pot fi accesate direct sau indirect.


Adresarea Directa

Adresarea Directa se face printr-o adresa de 9 biti. Aceasta adresa este obtinuta prin conectarea celui de-al saptelea bit al adresei directe a unei instructiuni cu doi biti (RP1, RP0) din registrul STATUS dupa cum se arata in figura urmatoarea. Orice acces la registrii SFR poate fi un exemplu de adresare directa.

Bsf STATUS, RP0 ;Bankl
movlw 0xFF  ;w=0xFF
movwf TRISA ;address of TRISA register is taken from
;instruction movwf

Adresarea Directa

Adresarea Indirecta

Adresarea indirecta spre deosebire de cea directa nu ia o adresa dintr-o instructiune ci o creeaza cu ajutorul bitului IRP a registrilor STATUS si FSR. Locatia adresata este accesata prin registrul INDF care de fapt tine o adresa indicata de un FSR. Cu alte cuvinte, orice instructiune care foloseste INDF ca registrul al ei, in realitate acceseaza datele indicate de un registru FSR. Sa spunem, de exemplu, ca un registru cu scop general (GPR) la adresa 0Fh contine o valoarea 20. Prin scrierea unei valori 0Fh in registrul FSR vom obtine un registru indicator la adresa 0Fh, iar prin citirea din registrul INDF, vom obtine valoarea 20, ceea ce inseamna ca am citit din primul registru valoarea lui fara accesarea lui directa (dar prin FSR si INDF). Se pare ca acest tip de adresare nu are nici un avantaj fata de adresarea directa, dar exista unele nevoi in timpul programarii ce se pot rezolva mai simplu doar prin adresarea indirecta.

Un asemenea exemplu poate trimite un set de date prin comunicatia seriala, lucrand cu bufere si indicatoare (ce vor fi discutate in continuare intr-un capitol cu exemple), sau sa stearga o parte a memoriei RAM (16 locatii) ca in urmatorul exemplu.

Citind datele din registrul INDF cand continutul registrului FSR este egal cu zero, intoarce valoarea zero, si scrie in el rezultatul in operatia NOP (no operation- nu opereaza).



6 Intreruperi

Intreruperile sunt un mecanism a unui microcontroler ce ii permit sa raspunda la unele evenimente la momentul cand se intampla, indiferent de ce face atunci microcontrolerul. Aceasta este o parte foarte importanta, pentru ca permite conexiunea microcontrolerului cu lumea de afara. In general, fiecare intrerupere schimba debitul programului, il intrerupe si dupa executarea unui subprogram (rutine de intrerupere), continua din acelasi punct.

Registrul de control al unei intreruperi se numeste INTCON si se gaseste la adresa 0Bh. Rolul lui este de a permite sau interzice cererile de intreruperi, si in caz ca nu sunt permise, inregistreaza cererile de intrerupere singulare prin bitii lui.

Registru INTCON

bit 0 RBIF (RB Port Change Interrupt Flag bit-bit Stegulet de Intrerupere a Schimbarii Portului RB) Bit ce informeaza despre schimbarile de la pinii 4, 5, 6 si 7 ai portului B.
1=cel putin un pin si-a schimbat starea
0=nu s-a intamplat nici o schimbare la vreun pin

bit 1 INTF (INT External Interrupt Flag bit-bit Stegulet de Intrerupere Externa INT) A avut loc o intrerupere externa.
1=a avut loc o intrerupere
0=nu a avut loc o intrerupere
Daca s-a detectat un front crescator sau descrescator la pinul RB0/INT, (ce este definit cu bitul INTEDG in registrul OPTION), bitul INTF este setat. Bitul trebuie sa fie sters in subprogramul intrerupere pentru a detecta urmatoarea intrerupere.

bit 2 T0IF (TMR0 Overflow Interrupt Flag bit-bit Stegulet Depasire Intrerupere TMRO) Depasirea contorului TMRO.
1=contorul si-a schimbat starea de la FFh la 00h.
0=depasirea nu a avut loc
Bitul trebuie sa fie sters in program pentru ca o intrerupere sa fie detectata.

bit 3 RBIE (RB port change Interrupt Enable bit-bit Permite Intreruperea schimbarii portului RB) Permite sa aiba loc intreruperi la schimbarea starii pinilor 4, 5, 6, si 7 ai portului B. 
1=permite intreruperi la schimbarea starii 
0=intreruperi interzise la schimbarea starii
Daca RBIE si RBIF au fost simultan setate, va avea loc o intrerupere.

bit 4 INTE (INT External Interrupt Enable bit-bit Permite Intrerupere externa INT) Bit ce permite intreruperea externa de la pinul RB0/INT.
1=intrerupere externa permisa
0=intrerupere externa interzisa
Daca INTE si INTF au fost setate simultan, va avea loc o intrerupere.

bit 5 T0IE (TMR0 Overflow Interrupt Enable bit-bit Permite Depasire Intrerupere TMRO) Bit ce permite intreruperile in timpul depasirii contorului TMRO.
1=intrerupere permisa
0=intrerupere interzisa
Daca T0IE si T0IF au fost simultan setate, va avea loc intreruperea.

Bit 6 EEIE (EEPROM Write Complete Interrupt Enable bit-bit Permite Intrerupere Completa a Scrierii EEPROM) Bit ce permite o intrerupere la sfarsitul unei rutine de scriere in EEPROM
1= intrerupere permisa
0= intrerupere interzisa
Daca EEIE si EEIF (ce este in registrul EECON1) au fost simultan setate, va avea loc o intrerupere.

Bit 7 GIE (Global Interrupt Enable bit-bit Permite Intrerupere Globala) Bit ce permite sau interzice toate intreruperile.
1=toate intreruperile sunt permise
0=toate intreruperile sunt interzise


PIC16F84 are patru surse de intrerupere:

1. Terminarea scrierii datelor in EEPROM
 Intrerupere TMR0 cauzata de depasirea timer-ului
3. Intrerupere in timpul schimbarii la pinii RB4, RB5, RB6 si RB7 ai portului B.
4. Intrerupere Externa de la pinul RB0/INT al microcontrolerului

In general, fiecare sursa de intrerupere are doi biti legati la ea. Unul permite intreruperea, iar celalalt detecteaza cand au loc intreruperi. Exista un bit comun numit GIE ce poate fi folosit pentru a interzice sau permite toate intreruperile simultan. Acest bit este foarte folositor cand se scrie un program pentru ca permite ca toate intreruperile sa fie interzise pentru o perioada de timp, asa ca executia unei parti importante a programului sa nu fie intrerupta. Cand instructiunea ce reseteaza bitul GIE a fost executata (GIE=0, toate intreruperile interzise), fiecare intrerupere ce ramane nerezolvata trebuie ignorata.

Intreruperile ce raman nerezolvate si ce au fost ignorate, sunt procesate cand bitul GIE (GIE=1, toate intreruperile sunt permise) va fi sters. Cand i s-a raspuns intreruperii, bitul GIE a fost sters, asa ca orice intreruperi aditionale vor fi interzise, adresa de intoarcere a fost trimisa in stiva, iar adresa 0004h a fost scrisa in contorul programului - numai dupa aceasta incepe raspunsul la o intrerupere! Dupa ce este procesata intreruperea, bitul a carui setare a cauzat o intrerupere trebuie sters, sau rutina de intrerupere va fi procesata automat tot mereu in timpul intoarcerii la programul principal.

Pastrarea continutului registrilor importanti

Doar valoarea de intoarcere a contorului programului este inmagazinata intr-o stiva in timpul unei intreruperi (prin valoare de intoarcere a contorului programului intelegem adresa instructiunii ce trebuie executata, dar nu a fost executata pentru ca a avut loc intreruperea). Pastrand doar valoarea contorului programului adesea nu este suficient. Unii registri ce sunt in uz in programul principal pot fi de asemenea in uz in rutina de intrerupere. Daca ei nu sunt retinuti, programul principal va obtine valori complet diferite in acei registri in timpul intoarcerii dintr-o rutina de intrerupere, ceea ce va cauza erori in program. Un exemplu de asemenea caz este continutul registrului de lucru W. Daca presupunem ca programul principal a folosit registrul de lucru W pentru unele din operatiile sale, si ca a pastrat in el o valoare ce este importanta pentru urmatoarea instructiune, atunci o intrerupere ce se va intampla inainte de acea instructiune va schimba valoarea registrului de lucru W, ce va influenta direct programul principal.

Procedura de inregistrare de registri importanti inainte de a merge la o rutina de intrerupere se numeste PUSH, in timp ce procedura ce aduce valorile inregistrate inapoi, se numeste POP. PUSH si POP sunt instructiuni ale altor microcontrolere (Intel), dar sunt atat de larg acceptate ca o intreaga operatie este numita dupa ele. PIC16F84 nu are instructiuni ca PUSH si POP, si ele trebuie sa fie programate.

Datorita simplitatii si folosirii frecvente, aceste parti ale programului pot fi facute ca macro-uri. Conceptul unui Macro este explicat in 'Limbaj de asamblare program'. In urmatorul exemplu, continuturile registrilor W si STATUS sunt memorate in variabilele W_TEMP si STATUS_TEMP inainte de rutina de intrerupere. La inceputul rutinei PUSH trebuie sa verificam bancul selectat in prezent pentru ca W_TEMP and STATUS_TEMP nu se gasesc in bancul 0. Pentru schimbul de date intre acesti registri, instructiunea SWAPF se foloseste in loc de MOVF pentru ca nu afecteaza starea bitilor registrului STATUS.

Exemplul este un program asamblor pentru urmatorii pasi :
1. Testarea bancului curent 
 Stocarea registrului W indiferent de bancul curent
3. Stocarea registrul STATUS in bancul 0
4. Executarea rutinei de intrerupere pentru procesul de intrerupere (ISR)
5. Restaureaza registrul STATUS
6. Restaureaza registrul W

Daca mai sunt si alte variabile sau registri ce trebuie stocati, atunci ei trebuie sa fie pastrati dupa stocarea registrului STATUS (pasul 3), si adusi inapoi inainte ca registrul STATUS sa fie restaurat (pasul 5).

Acelasi exemplu se poate realiza utilizand macro-uri, facand astfel programul mai eligibil. Macro-urile ce sunt deja definite, pot fi folosite pentru scrierea de noi macro-uri. Macro-urile BANK1 si BANK0 ce sunt explicate in capitolul 'Organizarea memoriei' sunt folosite cu macro-urile 'push' si 'pop'.

Intrerupere externa la pinul RB0/INT al microcontrolerului

Intreruperea externa la pinul RB0/INT este triggerata de frontul crescator (daca bitul INTEDG=1 in registrul OPTION<6>), sau de frontul descrescator (daca INTEDG=0). Cand apare semnalul corect la pinul INT, bitul INTF este setat la registrul INTCON. Bitul INTF (INTCON<1>) trebuie resetat in rutina de intrerupere, asa ca intreruperea sa nu aiba loc din nou in timpul intoarcerii la programul principal. Acesta este un pas important al programului pe care programatorul nu trebuie sa-l uite, sau programul va merge constant in rutina de intrerupere. Intreruperea poate fi inchisa prin resetarea bitului de control INTE (INTCON<4>).

Intreruperea in timpul depasirii contorului TMRO

Depasirea contorului TMRO (de la FFh la 00h) va seta bitul T0IF (INTCON<2>). Aceasta este o intrerupere foarte importanta pentru ca multe probleme reale se por rezolva folosind aceasta intrerupere. Unul din exemple este masurarea timpului. Daca stim cat timp are nevoie contorul pentru a completa un ciclu de la 00h to FFh, atunci numarul de intreruperi inmultit cu acea durata de timp va da timpul total scurs. In rutina de intrerupere unele variabile vor fi incrementate in memoria RAM, valoarea acelei variabile inmultite cu timpul de care are nevoie contorul pentru a contoriza intr-un ciclu intreg, va da timpul total scurs. Intreruperea poate fi pornita/oprita prin setarea/resetarea bitului T0IE (INTCON<5>). 

Intrerupere pe timpul unei schimbari la pinii  4, 5, 6 si 7 ai portului B

Schimbarea semnalului de intrare la PORTB <7:4> seteaza bitul RBIF (INTCON<0>). Patru pini RB7, RB6, RB5 si RB4 ai portului B, pot triggera o intrerupere ce are loc cand starea la ei se schimba de la unu la zero logic, sau viceversa. Pentru ca pinii sa fie sensibili la aceasta schimbare, trebuie definiti ca intrare. Daca oricare din ei este definit ca iesire, intreruperea nu va fi generata la schimbarea starii. Daca ei sunt definiti ca intrare, starea lor curenta este comparata cu vechea valoare ce a fost stocata la ultima citire de la portul B. Intreruperea poate fi pornita/oprita prin setarea/resetarea bitului RBIE in registrul INTCON.

Intreruperea la terminarea subrutinei write in EEPROM

Aceasta intrerupere este doar de natura practica. Pentru ca scrierea intr-o locatie EEPROM dureaza cam 10ms (care este o durata lunga in termenii microcontrolerului), nu este rentabil de a astepta pana la capat scrierea. Este adaugat astfel mecanismul de intrerupere ceea ce permite microcontrolerului sa continue executarea programului principal, in timp ce scrierea in EEPROM este facuta in plan secundar. Cand scrierea este terminata, intreruperea informeaza microcontrolerul ca scrierea s-a terminat. Bitul EEIF, prin care se face aceasta informare, se gaseste in registrul EECON1. Producerea unei intreruperi poate fi interzisa prin resetarea bitului EEIE in registrul INTCON. 

Initializarea intreruperii

Pentru a folosi un mecanism de intrerupere a unui microcontroler, trebuie facute unele sarcini pregatitoare. Aceste proceduri sunt pe scurt numite 'initializare'. Prin initializare definim la ce va raspunde microcontrolerul, si ce va ignora. Daca nu setam bitul ce permite o anumita intrerupere, programul nu va executa un subprogram intrerupere. Prin aceasta putem obtine controlul asupra producerii intreruperii, ceea ce este foarte folositor.

Exemplul de mai sus arata initializarea unei intreruperi externe la pinul RB0 al microcontrolerului. Unde se vede unu setat, inseamna ca intreruperea este permisa. Producerea altor intreruperi nu este permisa, si toate intreruperile impreuna sunt interzise pana ce bitul GIE este tinut in unu.

Urmatorul exemplu arata o cale tipica de a dirija intreruperile. PIC16F84 are doar o locatie unde adresa unui subprogram intrerupere este memorata. Aceasta inseamna ca mai intai trebuie sa detectam ce intrerupere este la indemana (daca mai mult de o sursa de intreruperi este disponibila), si apoi putem executa acea parte a programului ce se refera la acea intrerupere.

Reintoarcerea dintr-o rutina de intrerupere poate fi facuta cu instructiunile RETURN, RETLW si RETFIE. Se   remanda ca sa fie utilizata instructiunea RETFIE pentru ca acea instructiune este singura ce seteaza automat bitul GIE, ceea ce permite sa se produca o noua intrerupere.





7 Timer-ul liber TMR0

Timer-ele (temporizatoarele) sunt de obicei cele mai complicate parti ale unui microcontroler, asa ca este necesar  sa rezervam mai mult timp pentru a le explica. Odata cu aplicarea lor este posibil sa se creeze relatii intre o dimensiune reala ca 'timp' si o variabila ce reprezinta starea timer-ului intr-un microcontroler. Fizic, timer-ul este un registru a carui valoare creste continuu pana la 255, si apoi porneste de la capat: 0, 1, 2, 3, 4255.0,1, 2, 3etc.

Aceasta incrementare se face in fundalul a tot ceea ce face un microcontroler. Depinde de programator 'sa gaseasca o cale' de cum sa profite de aceasta caracteristica pentru nevoile lui. Una din cai este sa creasca o variabila la fiecare depasire a timer-ului. Daca stim cat timp are nevoie timer-ul sa faca o runda completa, atunci inmultind valoarea variabilei cu acel timp obtinem timpul total scurs. 

PIC16F84 are un timer de 8 biti. Numarul de biti determina pana la ce valoare contorizeaza timer-ul inainte de a incepe sa contorizeze de la zero din nou. In cazul unui timer de 8 biti, acel numar este 256. O schema simplificata a relatiei dintre un timer si un prescaler-divizor este reprezentata in diagrama anterioara. Prescalerul este numele acelei parti din microcontroler ce divide ceasul oscilatorului inainte de a ajunge la logica ce creste starea timer-ului. Numarul ce divide un ceas este definit prin trei biti in registrul OPTION. Cel mai mare divizor este 256. Aceasta inseamna de fapt ca doar la al fiecare 256-lea ceas, valoarea timer-ului va creste cu unu. Aceasta ne da posibilitatea de a masura perioade de timp mai lungi.

Dupa fiecare numaratoare pana la 255, timer-ul isi reseteaza valoarea la zero si incepe cu un nou ciclu de contorizare pana la 255. In timpul fiecarei tranzitii de la 255 la zero, bitul TOIF in registrul INTCON este setat. Daca se permit intreruperi, de aceasta se poate profita in generarea si in procesarea rutinei de intrerupere. Depinde de programator sa reseteze bitul TOIF in rutina de intrerupere, asa ca noua intrerupere, sau noua depasire sa fie detectate. In afara de ceasul oscilator intern, starea timer-ului poate de asemenea sa creasca prin ceasul extern la pinul RA4/TOCKI. Alegerea uneia din aceste doua optiuni se face in registrul OPTION prin bitul TOCS. Daca a fost aleasa aceasta optiune de ceas extern, va fi posibil sa se defineasca frontul unui semnal (crescator sau descrescator), la care timer-ul sa-si creasca valoarea.

In practica, unul din exemplele tipice ce este rezolvat prin ceas extern si unde timer-ul contorizeaza rotatiile complete ale unui ax al unei masini de productie, ca bobinatorul de transformator de exemplu. Sa rotim patru suruburi de metal pe axul unui bobinator. Aceste patru suruburi vor reprezenta convexitatea metalica. Sa plasam acum un senzor inductiv la o distanta de 5 mm de capatul unui surub. Senzorul inductiv va genera semnalul descrescator de fiecare data cand capul surubului este paralel cu capul senzorului. Fiecare semnal va reprezenta o patrime dintr-o rotatie, si suma tuturor rotatiilor se va gasi in timer-ul TMRO. Programul poate usor citi aceste date din timer printr-un bus de date. 

Urmatorul exemplu ilustreaza cum sa se initializeze timer-ul la fronturile descrescatoare ale semnalului din sursa externa cu un prescaler 1:4. Timer-ul lucreaza in mod 'polig-impingere'.

Acelasi exemplu poate fi realizat printr-o intrerupere in modul urmator:

Prescalerul poate fi asignat fie de timer-ul TMRO fie de watchdog. Watchdogul este un mecanism pe care microcontrolerul il foloseste sa se apere impotriva blocarii programelor. Ca orice alt circuit electric, la fel si cu microcontrolerul se pot intampla defectari, sau unele stricaciuni. Din nefericire microcontrolerul are de asemenea un program unde se pot intampla probleme. Cand se intampla aceasta, microcontrolerul se va opri din functionare si va ramane in acea stare pana ce cineva il reseteaza. Din cauza aceasta, a fost introdus mecanismul watchdog. Dupa o anumita perioada de timp, watchdogul reseteaza microcontrolerul (de fapt microcontrolerul se reseteaza singur). Watchdogul luceaza pe baza unui principiu simplu: daca se intampla depasirea timer-ului, microcontrolerul este resetat, si incepe executarea programului mereu din nou. Astfel, se va intampla un reset atat in cazul unei functionari corecte cat si incorecte. Urmatorul pas este prevenirea resetului in cazul unei functionari corecte, ce se face prin scrierea unui zero in registrul WDT (instructiunea CLRWDT) de fiecare data cand se apropie de depasire. Astfel programul va preveni un reset cat timp este executat corect. De indata ce s-a blocat, nu se va scrie zero, va avea loc depasirea timer-ului WDT si un reset ce va duce microcontrolerul inapoi la functionarea corecta din nou. 

Prescalerul este acordat cu timer-ul TMRO, sau cu timer-ul watchdogului prin bitul PSA in registrul OPTION. Stergand bitul PSA, prescalerul va fi acordat cu timer-ul TMRO. Cand prescalerul este acordat cu timer-ul TMRO, toate instructiunile de scriere in registrul TMRO (CLRF TMR0, MOVWF TMR0, BSF TMR0,) vor sterge prescalerul. Cand prescalerul este asignat timerului watchdog, numai instructiunea CLRWDT va sterge prescalerul si timer-ul watchdog in acelasi timp. Schimbarea prescalerului este completa sub controlul programatorului, si poate fi schimbat in timp ce se ruleaza programul.

Exista doar un prescaler si un timer. Functie de nevoi, ele sunt asignate fie timer-ului TMRO fie watchdog-ului.

Registrul control OPTION

Bit 0:2 PS0, PS1, PS2 (Prescaler Rate Select bit-bit Selectare Rata Prescaler) 
Subiectul prescaler, si cum afecteaza acesti biti lucrul unui microcontroler va fi abordat in sectiunea despre TMRO.

bit 3 PSA (Prescaler Assignment bit-bit Asignare Prescaler)
Bit ce asigneaza prescalerul intre TMRO si timer-ul watchdog).
1=prescalerul este asignat la timer-ul watchdog 
0=prescalerul este asignat la timer-ul free-liber

bit 4 T0SE (TMR0 Source Edge Select bit-bit Selectare Front Sursa TMRO)

Daca triggerul TMRO a fost activat cu impulsuri de la pinul RA4/T0CKI, acest bit va determina daca va fi la frontul crescator sau descrescator al semnalului.   
1=front descrescator 
0=front crescator

bit 5 T0CS (TMR0 Clock Source Select bit-bit Selectare Sursa Ceas TMRO)
Acest bit permite unui timer free-run sa-si incrementeze valoarea fie de la oscilatorul intern, de exemplu ¼ din ceasul oscilatorului, sau prin impulsuri externe la pinul RA4/T0CKI.
1=impulsuri externe
0=1/4 ceas intern

bit 6 INTEDG (Interrupt Edge Select bit-bit Selectare Front Intreruperi)
Daca a fost permisa producerea de intreruperi, acest bit va determina la ce front va avea loc intreruperea la pinul RB0/INT.
1=front crescator 
0=front descrescator

bit 7 RBPU (PORTB Pull-up Enable bit-bit Permite Pull-up-tragerea PORTB) 
Acest bit deschide sau inchide rezistorii interni la portul B. 
1=rezistorii 'pull-up' deschisi
0=rezistorii 'pull-up' inchisi



8 Memoria de date EEPROM

PIC16F84 are 64 de bytes de locatii de memorie EEPROM la adresele de la 00h la 63h unde se poate scrie sau de unde se poate citi. Cea mai importanta caracteristica a acestei memorii este ca nu pierde continutul in timpul inchideri sursei de alimentare. Aceasta inseamna practic ca ceea ce a fost scris in ea va ramane chiar si cand microcontrolerul este inchis. Datele pot fi retinute in EEPROM fara sursa de alimentare pana la 40 de ani. (dupa cum declara producatorul lui PICD16F84), si se pot executa 10000 de cicluri de scriere. 

In practica, memoria EEPROM este folosita pentru stocarea unor date importante sau a unor parametri de proces.
Un asemenea parametru este o temperatura data, asignata cand se seteaza un regulator de temperatura la un proces. Daca nu s-a retinut, va fi nevoie sa se ajusteze temperatura data dupa fiecare intrerupere a alimentarii. Pentru ca aceasta este foarte  nepractic (chiar periculos), producatorii de microntrolere au inceput sa instaleze un tip mai mic de memorie EEPROM.

Memoria EEPROM este plasata intr-un loc special al memoriei si poate fi accesata prin registri speciali. Acesti registri sunt:

. EEDATA la adresa 08h, care retine datele de citit sau cele de scris.  
. EEADR la adresa 09h, ce contine o adresa a locatiei EEPROM ce este accesata.  
. EECON1 la adresa 88h, ce contine biti de control.
. EECON2 la adresa 89h. Acest registru nu exista fizic si serveste la protejarea EEPROM-ului de scrieri accidentale.

Registrul EECON1 la adresa 88h este un registru de control cu 5 biti implementati.  
Bitii 5, 6 si 7 nu sunt folositi, si prin citire sunt totdeauna zero. Interpretarea bitilor registrului EECON1 urmeaza.

Registrul EECON1

bit 0 RD (Read Control bit-bit Control Citire) 
Setarea acestui bit initializeaza transferul de date definit in EEADR la registrul EEDATA. Pentru ca timpul nu este esential in citirea datelor ca la scriere, datele din EEDATA pot fi deja folosite in urmatoarea instructiune.
1=initializeaza citirea
0=nu initializeaza citirea

bit 1 WR (Write Control bit-bit Control Scriere) 
Setarea acestui bit initializeaza scrierea datelor din registrul EEDATA la adresa specifcata prin registrul EEADR. 
1=initializeaza scrierea  
0=nu initializeaza scrierea

bit 2 WREN (EEPROM Write Enable bit-bit Permite Scrierea EEPROM) Permite scrierea in EEPROM
Daca acest bit nu a fost setat, microcontrolerul nu va permite scrierea in EEPROM.
1=scriere permisa
0=scriere interzisa

bit 3 WRERR (Write EEPROM Error Flag-Stegulet Eroare Scriere EEPROM ) Eroare in timpul scrierii in EEPROM
Acest bit a fost setat doar in caz ca scrierea in EEPROM a fost intrerupta de un semnal sau prin terminarea timpului din timer-ul watchdog (daca este activat).
1=a avut loc eroare
0=nu a avut loc eroare

bit 4 EEIF (EEPROM Write Operation Interrupt Flag bit-bit Stegulet Intrerupere Operatie Scriere EEPROM) Bit folosit pentru a informa ca scrierea datelor s-a terminat.
Cand s-a terminat scrierea, acest bit va fi setat automat. Programtorul trebuie sa stearga bitul EEIF in programul sau pentru a detecta noua terminare a scrierii. 
1=scrierea terminata
0=scrierea inca neterminata, sau inca nu a inceput

Citirea din memoria EEPROM

Setarea bitului RD initializeaza transferul de date de la adresa gasita in EEADR la registrul EEDATA. Ca si la citirea datelor nu avem nevoie de atat de mult timp ca la scriere, datele luate din registrul EEDATA pot deja fi folosite mai departe in urmatoarea instructiune. 

O mostra a partii programului ce citeste datele in EEPROM, ar putea arata ca mai jos:

Dupa ultima instructiune de program, continutul de la o adresa EEPROM zero poate fi gasit in registrul w.

Scrierea in memoria EEPROM

Pentru a scrie datele in locatia EEPROM, programatorul trebuie mai intai sa scrie adresa in registrul EEADR si datele in registrul EEDATA. Numai atunci este folositor de a seta bitul WR ce pune totul in miscare. Bitul WR va fi resetat, si bitul EEIF setat urmand o scriere ce poate fi folosita in procesarea intreruperilor. Valorile 55h si AAh sunt prima si a doua cheie care interzic ca scrierea accidentala in EEPROM sa se intample. Aceste doua valori sunt scrise in EECON2 care serveste doar pentru acel scop, de a primi aceste doua valori si de a preveni orice scriere accidentala in memoria EEPROM. Liniile de program marcate ca 1, 2, 3 si 4 trebuie sa fie executate in acea ordine in intervale egale de timp. De aceea este foarte important, sa inchideti intreruperile ce ar putea schimba timpul necesar pentru executare instructiunilor. Dupa scriere, intreruperile, pot fi permise din nou.


Exemplu unei parti a programului ce scrie datele 0xEE in prima locatie in memoria EEPROM ar putea arata ca mai jos:

Este recomandat ca WREN sa fie inchis tot timpul cu exceptia scrierii datelor in EEPROM, asa ca posibilitatea unei scrieri accidentale va fi minima. Scrierea in EEPROM va fi automat stearsa




Politica de confidentialitate


creeaza.com logo mic.com Copyright © 2024 - Toate drepturile rezervate.
Toate documentele au caracter informativ cu scop educational.