Sunteți pe pagina 1din 477

SISTEME CU MICROPROCESOARE.

MICROCONTROLERUL PIC18F4455

1. ARHITECTURA GENERALĂ

Introducere
Obiective
1.1 ARHITECTURA VON NEUMANN
Cuprins
1.1.1 Unitatea centrală de prelucrare
1.1.2 Magistralele
1.1.3 Memoria
1.1.4 Echipamentele de intrare-ieşire
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
1.4.1 Execuţia instrucţiunilor
1.4.2 Unitatea de control
1.4.3 Unitatea aritmetică şi logică
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

9
ARHITECTURA GENERALĂ

Microcontrolerele sunt în esenţă sisteme de calcul având arhitectura


modelată pe baza celei a calculatoarelor numerice. Pornind de la această
idee, capitolul curent urmăreşte câteva principii privind arhitectura şi
Introducere
modul de funcţionare al acestor tipuri de sisteme.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă deosebirile existente între arhitecturile sistemelor de
calcul de tip von Neumann şi Harvard;
Obiective - să înţeleagă relaţia dintre microcontrolere şi microprocesoare
- să cunoască rolul şi structura elementelor componente ale
sistemelor de calcul;
- să cunoască modul în care se execută instrucţiunile şi conceptul de
pipeline;
- să cunoască rolul registrului de lucru (WREG) şi al registrului
STATUS.

1.1 ARHITECTURA VON NEUMANN

Din punct de vedere istoric sistemele de calcul moderne îşi au originea în cele
dezvoltate în timpul celui de-al doilea război mondial. Aceste sisteme iniţiale îndeplineau o
funcţionalitate dedicată, fiind proiectate pentru a realiza o singură sarcină pe baza unui set de
date, iar pentru a-şi schimba comportamentul era necesară refacerea conexiunilor fizice dintre
elementele componente. Evoluţia esenţială a acestor sisteme de calcul rudimentare s-a produs
în momentul în care s-a înţeles că programul putea fi stocat în memorie alături de date. Unul
dintre avantajele acestei arhitecturi, denumită von Neumann, după numele celui care a
coordonat proiectul, îl reprezintă flexibilitatea. Astfel, modificarea programului presupune
doar încărcarea secvenţei de biţi corespunzătoare în zona de memorie potrivită.
Simplitatea arhitecturii von Neumann a făcut ca majoritatea sistemelor de calcul
moderne să fie bazate pe această structură. Elementele caracteristice ale acestor sisteme de
calcul sunt: unitatea centrală de prelucrare (UCP), memoriile, echipamentele de intrare ieşire
şi magistralele. Unitatea centrală de prelucrare conţine o unitate de control, care realizează
interpretarea, secvenţierea instrucţiunilor şi comandă celelalte componente ale sistemului, şi o
unitate aritmetică şi logică (UAL), care execută instrucţiuni. Unitatea de memorie stochează
instrucţiuni şi date, iar echipamentele periferice asigură interacţiunea dintre sistemul de calcul

10
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

şi mediul înconjurător prin introducerea instrucţiunilor şi a datelor, respectiv prin


reprezentarea rezultatelor. Magistralele furnizează căile de comunicaţie între componentele
sistemului de calcul.
În Fig. 1.1 se prezintă structura generală a sistemelor de calcul bazate pe arhitectura
von Neumann.

Fig. 1.1. Structura generală a sistemelor de calcul bazate pe arhitectura von Neumann

1.1.1 Unitatea centrală de prelucrare (UCP)

Funcţia principală a unităţii centrale de prelucrare (UCP) este de a executa o secvenţă


de instrucţiuni stocată în memorie. Acest lucru se va realiza în mod continuu şi repetat atâta
timp cât sitemul este activ. Un ciclu de instrucţiune presupune extragerea instrucţiunilor din
memorie într-un registru intern al UCP, decodificarea acestora şi apoi execuţia propriuzisă.
Extragerea succesivă a instrucţiunilor din memorie se realizează sub controlul unui circuit
denumit numărător de program (en. PC – Program Counter), care va conţine adresa
următoarei instrucţiuni din memorie care urmează a fi extrasă. Datele rezultate din execuţia
programului sau datele utilizate de program pot fi accesate din memorie. De asemenea,
unitatea centrală de prelucrare supervizează şi comandă celelalte componente ale sistemului
prin liniile de control.[8]
Structura internă a unităţii centrale de prelucrare conţine în general următoarele
componente majore:
1. O unitate de control care realizează interpretarea şi secvenţierea
instrucţiunilor, precum şi comanda celorlalte componente ale sistemului.
2. O unitate aritmetică şi logică care execută instrucţiunile din memorie. Ea este
responsabilă de manipularea datelor şi executarea operaţiilor aritmetice şi logice.
3. Regiştri interni (memorii de mare viteză), cu rol în stocarea de informaţii
necesare execuţiei instrucţiunilor (ex. Registrul de instrucţiuni, acumulatorul etc.).
În general, aceşti regiştri interni stochează doar câţiva octeţi de date, care pot fi
operanzi, rezultate, adrese de memorie etc.

11
ARHITECTURA GENERALĂ

1.1.2 Magistralele

Magistralele reprezintă căile de comunicaţie ale sistemului de calcul. Informaţia


transferată între componentele sistemului este transmisă sub formă binară, paralel pe liniile
magistralelor. Se pot identifica trei tipuri de magistrale:

1. Magistrala de date este utilizată la transferul datelor necesare procesării efectuate de


UCP. De exemplu, un sistem de calcul de 8 biţi este un sistem de calcul care dispune
de o magistrală de date cu lăţimea de 8 biţi, fiind capabil să transfere date (numere)
reprezentate pe 8 biţi. Astfel, un asemenea sistem va putea efecuta operaţii între
operanzi reprezentaţi pe 8 biţi, furnizând rezultate reprezentate pe 8 biţi.
Existenţa unei magistrale de 8 biţi nu limitează procesorul doar la utilizarea datelor cu
dimensiunea de 8 biţi, ci indică faptul că procesorul poate accesa un singur octet de
date per ciclu de memorie. De aceea, în raport cu o magistrală cu lăţimea de 16 biţi, o
magistrală de 8 biţi poate transmite doar jumătate din informaţie în unitatea de timp.
Astfel, procesoarele de 16 biţi sunt mai rapide decât cele de 8 biţi ş.a.m.d. Chiar dacă
procesoarele de 16, 32 sau 64 de biţi pot accesa date cu dimensiunea maximă egală cu
laţimea magistralelor lor, ele pot accesa la fel de bine şi locaţii de memorie cu
dimensiunea mai mică (ex. câte un octet).
Totuşi, există şi cazuri în care dimensiunea magistralei externe de date este diferită de
cea a magistralei interne a procesorului. În aceste cazuri se vor realiza mai multe
transferuri din memorie pentru a extrage un operand.

2. Magistrala de adrese este utilizată pentru specificarea adreselor locaţiilor de


memorie accesate. De exemplu, în cazul unei magistrale de adrese de 8 biţi, sistemul
poate accesa 28=256 locaţii de memorie distincte. Cu 16 linii de adresă se pot adresa
65536 locaţii de memorie.

3. Magistrala de control are rolul de a conduce semnalele de control ale UCP care
comandă componentele sistemului. De exemplu, semnalele transmise prin intermediul
magistralei de control pot specifica modul de acces la memorie în vederea realizării
unor operaţii de scriere sau de citire. Practic liniile de scriere şi citire ale magistralei
controlează direcţia datelor de pe magistrala de date. Alte semnale ale magistralei de
control pot include: tactul sistem, liniile de întrerupere, linii de stare etc.

12
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1.1.3 Memoria

Memoriile sunt caracterizate prin conţinutul pe care acestea îl stochează într-un set de
regiştri şi locaţia sau adresa individuală a fiecărui registru. În cazul arhitecturii von Neumann,
atât instrucţiunile cât şi datele se găsesc în acelaşi spaţiu de memorie. Indiferent că este
internă sau externă, memoria reprezintă un spaţiu de stocare şi poate fi accesată cu ajutorul
magistralelor dacă se specifică adresa locaţiei dorite şi tipul operaţiei (scriere sau citire).

1.1.4 Echipamentele de intrare-ieşire

Pentru a putea fi util un sistem de calcul trebuie să fie capabil să interacţioneze cu


mediul înconjurător. Acest lucru se realizează prin intermediul echipmantelor de intrare ieşire.
Comunicarea dintre UCP şi echipamentele periferice se va efectua tot prin intermediul
magistralelor printr-un set de regiştri cu adrese proprii denumite porturi. Porturile pot fi
accesate în mod similar cu memoria, în multe situaţii chiar sunt mapate în spaţiul de adrese al
memoriei. Prin intermediul porturilor pot fi configurate perifericele, pot fi trimise date direct
spre exterior sau pot fi citite date binare din exterior.

1.2 ARHITECTURA HARVARD

Principalul avantaj al arhitecturii von Neumann îl reprezintă simplitatea, totuşi,


existenţa unor magistrale comune pentru toate cele trei componente ale arhitecturii determină
faptul că sistemul de calcul în cauză nu poate realiza la un anumit moment decât un singur
lucru. Astfel, de exemplu, accesul la datele din memorie nu se poate produce în acelaşi timp
cu extragerea unei instrucţiuni din memorie.
În aceste condiţii, în prima decadă după cel de-al doilea război mondial s-a dezvoltat
la universitatea Harvard o nouă arhitectură pentru sistemele de calcul. Această arhitectură,
denumită arhitectura Harvard reprezenta o variaţie a arhitecturii von Neumann fiind
caracterizată de faptul că datele şi instrucţiunile sunt stocate separat în spaţii de memorie
distincte şi sunt accesate prin magistrale diferite. Avantajul acestei arhitecturi este dat de
posibilitatea de a accesa datele şi instrucţiunile în acelaşi timp, având drept consecinţă
creşterea complexităţii arhitecturii interne. Acesta este şi motivul pentru care arhitectura
Harvard a început să fie prezentă mai mult abia odată cu evoluţia circuitelor integrate.

13
ARHITECTURA GENERALĂ

În Fig. 1.2 sunt alăturate, cu scop comparativ, cele două tipuri de arhitecturi de sisteme
de calcul: von Neumann (Fig. 1.2-a) şi Harvard (Fig. 1.2-b). În cea din urmă se evidenţiază
cele două spaţii de memorie distincte împreună cu magistralele asociate. Fiecare memorie
dispune de propria sa magistrală de adrese, respectiv de date, astfel încât nu există nici o
legătură între adresele sau datele celor două spaţii de memorie.[10,19]

Fig. 1.2. Comparaţie între arhitecturile von Neumann şi Harvard

1.3 MICROPROCESOR SAU MICROCONTROLER?

Până acum, în paragrafele anterioare s-a făcut referire doar la câteva sisteme de calcul
care ne trimit cu gândul mai mult spre calculatoarele numerice.
Dar, ce sunt de fapt microprocesoarele, respectiv microcontrolerele?
Pe scurt, microprocesorul implementează funcţiile unităţii centrale de prelucrare.
Pentru a putea fi folosit într-un sistem de calcul, unui microprocesor trebuie să i se adauge
alte componente, cum ar fi memorie, sau componente pentru primirea şi trimiterea datelor.
Pe de altă parte microcontrolerul a fost proiectat să conţină toate cele trei
componente principale (UCP, memorie, echipamente de intrare-ieşire) într-un singur circuit
integrat. Astfel, nu mai sunt necesare alte componente externe deoarece toate perifericele
sunt deja incluse în el. Funcţiile principale ale componentelor însă rămân neschimbate fiind
aceleaşi indiferent de aplicaţia dezvoltată, dar din motive de preţ şi dimensiune
microcontrolerele dispun de un set redus de instrucţiuni şi o capacitate de adresare mai mică.
Astfel, făcând trimitere la cele două tipuri de arhitecturi prezentate anterior în Fig. 1.1
şi Fig. 1.2, microprocesorul reprezintă unitatea centrală de prelucrare, pe când
microcontrolerul reprezintă întreg sistemul de calcul.[4,6]

14
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Pentru a pune în evidenţă structura internă a microcontrolerelor se consideră următorul


exemplu.
Se analizează cazul unui sistem de control al unei sere, bazat pe
microcontroler. Acesta monitorizează parametri precum: umiditatea
solului, temperatura ambiantă sau gradul de iluminare şi comandă diferite
Exemplu
echipamente pentru a stabili condiţiile optime în seră (Fig. 1.3).

Fig. 1.3. Controlul unei sere cu ajutorul unui microsistem

Astfel, umiditatea din sol se măsoară cu ajutorul unui traductor de


umiditate care furnizează un semnal analogic. Dacă acest semnal este sub
o anumită valoare se comandă pornirea sistemului de irigaţie care
presupune deschiderea unei valve pentru apă timp de 5 secunde, apoi
închiderea acesteia timp de 5 secunde şi repetarea acestui ciclu până la
refacerea umidităţii dorite a solului
De asemenea, se monitorizează temperatura din seră cu ajutorul unui
senzor de temperatură şi se comandă deschiderea / închiderea ferestrelor,
precum şi sistemul de încalzire al serei.
În contextul acestei aplicaţii, sistemul de control trebuie să interfaţeze
diverse semnale. Astfel, pentru interfaţarea semnalelor care provin de la
traductorul de umiditate, senzorul de lumină, respectiv cel de temperatură,
vor fi necesare trei intrări analogice, respectiv un convertor analog-digital.
Convertorul analog-digital va discretiza pe rând cele trei semnale
furnizând intern valorile digitale echivalente care vor putea fi comparate
cu referinţele impuse. Pornirea iluminatului, comanda ferestrelor serei, a
sistemului de incălzire sau a sistemului de irigaţie se poate realiza prin
semnale de control discrete, de tip închis/deschis furnizate de la un port de
ieşire digital în baza logicii de control realizate prin programul memorat.
Dacă presupunem că acest sistem necesită şi o interfaţă cu utilizatorul care
să permită fixarea parametrilor de funcţionare ai serei, precum şi afişarea

15
ARHITECTURA GENERALĂ

unor informaţii utile putem completa necesarul de porturi de intrare/ieşire


digitale.

În continuare se pot rezuma resursele necesare pentru implementarea


proiectului:
- o intrare pentru un oscilator extern conectat la un counter/timer
care să furnizeze baza de timp pentru obţinerea celor 5 secunde
cerute. În general, tactul sistem este de cele mai multe ori folosit
de către un timer intern pentru obţinerea temporizărilor;
- trei intrări analogice şi un convertor analog-digital necesare pentru
măsurarea semnalelor care provin de la traductorul de umiditate,
senzorul de temperatură şi cel de lumină;
- o ieşire digitală pentru comanda valvei sistemului de irigat;
- o ieşire digitală pentru comanda motoarelor de acţionare ale
ferestrelor serei;
- o ieşire digitală pentru comanda sistemului de încălzire;
- o ieşire digitală pentru comanda sistemului de iluminat;
- intrări şi ieşiri digitale suplimentare pentru interfaţarea unui panou
de comandă care poate cuprinde butoane şi elemente de afişare
(ex. LED-uri, afişaj LCD);
- UCP pentru realizarea calculelor şi pentru efectuarea operaţiilor de
intrare-ieşire;
- Memorie program (de obicei memorie de tip ROM) pentru
stocarea logicii de control;
- Memorie de date pentru stocarea variabilelor temporare (de obicei
memorie de tip RAM).
Presupunând că programul de control nu ocupă complet toate resursele
microcontrolerului, sistemul ar mai putea transmite date la distanţă prin
intermediul unui sistem de comunicaţie.

În concluzie, pornind de la exemplul anterior se pot identifica o parte din


componentele unui microcontroler. Astfel, structura generală a microcontrolerelor include
unitatea centrală de prelucrare, memorii pentru stocarea datelor şi a programului, ceas intern,
timere, interfeţe de comunicaţie, convertoare analog-digitale, circuite de veghe şi bineînţeles
porturi pentru intrări şi ieşiri digitale şi analogice.[8]

16
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.4. Structura generală a microcontrolerelor

1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR DIN FAMILIA PIC18F

PIC este o familie de microcontrolere produse de compania Microchip Technology.


Denumirea PIC este o prescurtare de la “Programmable Intelligent Computer” (Calculator
Inteligent Programabil). Succesul de care se bucură aceste microcontrolere se datorează în
mare măsură suportului oferit de producător şi al mediului de dezvoltare MPLAB IDE
disponibil gratuit pe site-ul producătorului1. Numărul mare de aplicaţii, posibilitatea de a
dezvolta aplicaţiile în limbaj de asamblare sau în C, dar şi o mulţime de biblioteci bine
documentate permit dezvoltarea rapidă a aplicaţiilor şi fac din aceste microcontrolere un bun
candidat pentru studiul din acest curs.
PIC 18 reprezintă o familie de microcontrolere cu instrucţiuni pe 16 biţi, şi magistrală
internă de date de 8 biţi, memorie program de tip flash, spaţiu de memorie date adresabil
liniar. Familia a fost extinsă cu un număr mare de protocoale de comunicaţii, CAN, Ethernet,
USB, SPI, I2C, Irda, existând în prezent peste 100 de membri ai familiei fiecare cu alte
combinaţii de facilităţi. În continuare se prezintă câteva caracteristici ale acestor
microcontrolere.
Microcontrolerele PIC analizate în acest curs sunt bazate pe arhitectura Harvard.
Pentru a reduce din complexitatea unităţii centrale de prelucrare, aceste microcontrolere
implementează un set redus de instrucţiuni (en. RISC = Reduced Instruction Set Computer).
Spre deosebire de procesoarele RISC, procesoarele cu set complex de instrucţiuni (en. CISC =
Complex Instruction Set Computer) au fost proiectate să implementeze un set de instrucţiuni
cât mai apropiat de cel al limbajelor de nivel înalt, motiv pentru care şi numărul de
instrucţiuni este mai mare. În schimb, procesoarele RISC dispun de un set compact de
instrucţiuni şi moduri mai puţine de adresare, obţinându-se în felul acesta timpi de execuţie ai
instucţiunilor mai mici la aceeaşi frecvenţă de tact.[8]

1
http://www.microchip.com [22]

17
ARHITECTURA GENERALĂ

Unul dintre avantajele importante ale arhitecturii Harvard este dat de faptul că
magistralele celor două tipuri de memorii pot avea dimensiuni diferite. Astfel, magistrala de
date (instrucţiuni) a memoriei program împreună cu memoria program pot fi organizate pe
cuvinte (în cazul analizat este vorba de cuvinte de 16 biţi), iar magistrala şi memoria de date
sunt organizate pe octet. Acest lucru, combinat cu setul redus de instrucţiuni permit
implementarea unor instrucţiuni cu lungime fixă ce pot fi extrase într-un singur pas.

1.4.1 Execuţia instrucţiunilor

Înţelegerea ciclului instrucţiune este esenţială pentru înţelegerea modului de


funcţionare al microcontrolerelor. Un ciclu instrucţiune presupune două faze principale:
- Faza de extragere a instrucţiunilor din memoria program într-un registru intern al
UCP
- Faza de execuţie care include decodificarea instrucţiunii, extragerea operanzilor,
efectuarea operaţiei specificate în codul instrucţiunii şi depunerea rezultatului în
memorie
Durata unui ciclu instrucţiune depinde de frecvenţa de lucru a sistemului, fiind egală
cu 2x4 tacţi sistem. Astfel, tactul sistem este divizat intern la patru fiind generate patru
semnale de tact în cuadratură (Q1, Q2, Q3 şi Q4). Numărătorul program este incrementat în
Q1, iar instrucţiunea este extrasă din memorie în registrul de instrucţiuni în Q4. În
următoarele Q1 până la Q4 instrucţiunea este decodificată (Q1), se citesc datele/operanzii din
memorie (Q2), se procesează datele în funcţie tipul instrucţiunii decodificate (Q3), se scriu
datele/rezultatele în memorie (Q4). Dacă oricare din aceşti paşi lipseşte, datorită tipului de
instrucţiune care se execută, se va insera un pas fără operaţie în locul lui, astfel încât timpul de
execuţie rămâne constant.[8,15]
Analizând cele două faze ale ciclului instrucţiune se constată că în faza de extragere
UCP accesează memoria program, iar în faza de execuţie UCP accesează memoria de date.
Ţinând cont de faptul că microcontrolerul implementează o arhitectura Harvard, iar cele două
memorii pot fi accesate prin magistrale independente, pentru a creşte performanţa sistemului
s-a implementat un pipeline pe două nivele pentru instrucţiuni. Acesta permite suprapunerea
celor două faze ale instrucţiunii. Astfel, în timp ce instucţiunea curentă este extrasă cea
precedentă se execută. În acest fel se reduce la jumătate timpul de execuţie al unei
instrucţiuni, datorită faptului că la fiecare 4 tacţi sistem se terimină de executat o instrucţiune.
Excepţie prezintă instrucţiunile care modifică valoarea numărătorului de program.

18
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.5. Fazele de execuţie ale instrucţiunilor [8,15]

Fig. 1.6. Exemplu de execuţie al unui set de instrucţiuni

Pornind de la modul în care se execută instrucţiunile, UCP poate fi împărţită în două


componente: Unitatea de control şi regiştrii asociaţi, respectiv Unitatea Aritmetică şi Logică.

1.4.2 Unitatea de control

În Fig. 1.7 se prezintă structura simplificată a unităţii de control împreună cu circuitele


componente.

Fig. 1.7. Unitatea de control

Instrucţiunile care constituie programul microcontrolerului sunt stocate în memoria


program sub forma unor cuvinte binare la adrese succesive. Un numărător binar, denumit
numărător de program (en. PC = Program Counter) este utilizat pentru a adresa pe rând

19
ARHITECTURA GENERALĂ

fiecare instrucţiune. Sub controlul acestui numărător, instrucţiunile vor fi extrase pe rând din
memoria program, iar apoi vor fi executate.
Doi regiştri de instrucţiuni, care împreună formează Pipeline-ul, vor stoca codul
instrucţiunilor extrase din memoria program. Cel de sus, Registrul de Instrucţiuni 1 (RI1) va
stoca instrucţiunea n şi o va păstra pe durata următorului ciclu instrucţiune. Această structură
permite ca instrucţiunea n-1, aflată în registrul de la baza pipeline-ului (Registrul de
Instrucţiuni 2 - RI2) să fie executată în timp ce instrucţiunea n este extrasă din memorie şi
stocată în Registrul de instrucţiuni 1 al pipeline-ului. După execuţia instrucţiunii n-1 se
transferă conţinutul din registrul de instrucţiuni 1 al pipeline-ului în registrul de instrucţiuni 2,
urmând ca în timp ce instrucţiunea n+1 este extrasă din memorie şi stocată în vârful pipeline-
ului, instrucţiunea de la bază (instrucţiunea n) să fie executată.
Una din componentele de bază ale UCP, decodificatorul, are rolul de a descifra codul
instrucţiunii stocate în registrul de la baza pipeline-ului şi contribuie la generarea semnalelor
de control interne necesare pentru execuţia instrucţiunii.

1.4.3 Unitatea aritmetică şi logică

Microcontrolerul conţine o unitate aritmetică si logică (Fig. 1.8) pe 8 biţi şi un registru


de lucru de 8 biţi (en. WREG = Work Register) denumit şi acumulator. Unitatea aritmetică este
capabilă să efectueze operaţii precum: adunare, scădere, operaţii logice (ŞI, SAU, XOR etc),
deplasări şi rotiri, înmulţire. În cazul instrucţiunilor cu doi operanzi (ex. adunare) unul din
operanzi se va găsi întotdeauna în registrul de lucru. Celălalt operand poate fi o constantă sau
un registru din memorie. În funcţie de starea unui bit din codul instrucţiunii, denumit bit de
destinaţie d, rezultatul operaţiilor poate fi stocat fie în registrul de lucru (d=0) fie în registrul
din memoria de date din care provenea operandul (d=1). Rezultatul operaţiei de înmulţiere se
va stoca întotdeauna într-o pereche de regiştri speciali PRODH:PRODL.
Introducerea registrului de lucru (WREG) în structura microcontrolerului contribuie la
simplificarea substanţială a modului de reprezentare al instrucţiunilor, lucru care conduce la
creşterea vitezei de execuţie a instrucţiunilor, precum şi la reducerea cantităţii de memorie
necesară pentru stocarea instrucţiunilor. Pentru a exemplifica această idee se poate considera
cazul unei operaţii de adunare în care intervin trei termeni: doi operanzi, respectiv un rezultat.
În lipsa registrului de lucru şi a bitului de destinaţie al rezultatului, codul instrucţiunii de
adunare ar fi trebuit să cuprindă specificarea tuturor celor trei termeni, în loc de unul singur,
lucru care ar fi condus la creşterea numărului de biţi necesari pentru reprezentarea
instrucţiunii.

20
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.8. Structura unităţii aritmetice şi logice

Operaţiile aritmetice şi logice pot genera o serie de indicatori ce vor fi stocaţi în


registrul de stare STATUS. Aceşti indicatori sunt: bitul de transport (C - Carry), bitul de
depăşire (OV - Overflow), bitul de semn (N - Negative), rezultat zero (Z - Zero), bitul de
transport auxiliar (DC – Digit Carry). Registrul de stare poate fi şi registru de destinaţie, dar
dacă operaţia executată va conduce la setarea acestor indicatori, se va suprascrie rezultatul. De
exemplu instrucţiunea CLRF STATUS, va şterge toţi biţii registrului STATUS, dar bitul Z va
fi setat la sfârsitul instrucţiunii. În concluzie, registrul de stare va conţine întotdeauna valorile
corecte ale indicatorilor.[8]
Structura registrului de stare STATUS este prezentată mai jos:

bit 7 bit 0
- - - N OV Z DC C
Fig. 1.9. Registrul STATUS

Pornind de la ideea introductivă conform căreia microcontrolerele


reprezintă încapsularea unor sisteme de calcul, în acest curs s-au prezentat

Concluzii principalele tipuri de arhitecturi existente, s-a evidenţiat structura acestora,


rolul elementelor componente, dar şi principalele avantaje şi dezavantaje
care le caracterizează. Studiul unei aplicaţii practice a condus la
identificarea necesarului de elemente componente în structua generală a
microcontrolerelor, iar familia de microcontrolere PIC18F a furnizat
suportul pentru aprofundarea conceptelor referitoare la modul de execuţie
al instrucţiunilor, respectiv la structura internă a UCP.

21
ARHITECTURA GENERALĂ

1. Arhitectura microcontrolerului permite extragerea unei instrucţiuni din


memorie simultan cu execuţia altei instrucţiuni. Discutaţi elementele
care permit realizarea acestor lucruri în paralel.
Întrebări de
2. Care este diferenţa între arhitectura von Neumann şi arhitectura
autoevaluare
Harvard a sistemelor de calcul?
3. Care este diferenţa între un microcontroler şi un microcprocesor?
4. Explicaţi rolul registrului de lucru (WREG) în arhitectura
microcontrolerului.
5. Explicaţi rolul registrului status (STATUS) în arhitectura
microcontrolerului.
6. Prezentaţi un avantaj şi un dezavantaj pentru fiecare din cele două
tipuri de arhitecturi prezentate.
7. Care sunt elementele componente ale unui sistem de calcul?
8. Care sunt fazele unei instrucţiuni?
9. Care este rolul numărătorului de program?
10. Cum este implementat pipeline-ul la nivelul unităţii de control?

Adresă
Colecţie de biţi utilizaţi pentru a identifica locaţiile de memorie
Termeni Ciclu instrucţiune
esenţiali Procesul prin care se extrage o instrucţiune din memoria program şi se
execută
CISC
Complex Instruction Set Computer
Dată
Conţinutul unei locaţii de memorie
Instrucţiuni
Comenzi pe care le execută UCP
Magistrală
Colecţie de fire prin care informaţia se transmite paralel între componentele
unui sistem de calcul
Memorie
Spaţiu de stocare
Memorie de date
Spaţiu de stocare temporar (RAM) pentru datele cu care lucrează programul

22
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Memorie program
Spaţiu de stocare pentru program
Microcontroler
Sistem de calcul încapsulat într-un singur circuit integrat
Microprocesor
Parte componentă a unui sistem de calcul, UCP
Numărător de program
Numărător binar utilizat pentru adresarea instrucţiunilor. Conţine adresa
instrucţiunii care urmează a fi executată
PIC
Programmable Intelligent Computer
Pipeline
Tehnică utilizată pentru a creşte numărul de instrucţiuni care pot fi
executate în unitatea de timp. Pipeline-ul nu reduce timpul necesar
execuţiei unei instrucţiuni, ci creşte numărul de instrucţiuni care pot fi
procesate simultan
Port
Calea de legătură a sistemului de calcul cu lumea exterioară prin care acesta
poate să trimită şi să primească date
Registru
Spaţiu de stocare
Registru de instrucţiuni
Spaţiu de stocare temporar pentru o instrucţiune extrasă din memorie
RISC
Reduced Instruction Set Computer
STATUS
Registru care indică starea operaţiilor aritmetice şi logice executate de
unitatea aritmetică şi logică
UAL
Unitate aritmetică şi logică
UCP
Unitate centrală de prelucrare
WREG
Registru de lucru / acumulator. În general conţine unul din operanzii
instrucţiunilor

23
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1. ARHITECTURA GENERALĂ

Introducere
Obiective
1.1 ARHITECTURA VON NEUMANN
Cuprins
1.1.1 Unitatea centrală de prelucrare
1.1.2 Magistralele
1.1.3 Memoria
1.1.4 Echipamentele de intrare-ieşire
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
1.4.1 Execuţia instrucţiunilor
1.4.2 Unitatea de control
1.4.3 Unitatea aritmetică şi logică
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

9
ARHITECTURA GENERALĂ

Microcontrolerele sunt în esenţă sisteme de calcul având arhitectura


modelată pe baza celei a calculatoarelor numerice. Pornind de la această
idee, capitolul curent urmăreşte câteva principii privind arhitectura şi
Introducere
modul de funcţionare al acestor tipuri de sisteme.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă deosebirile existente între arhitecturile sistemelor de
calcul de tip von Neumann şi Harvard;
Obiective - să înţeleagă relaţia dintre microcontrolere şi microprocesoare
- să cunoască rolul şi structura elementelor componente ale
sistemelor de calcul;
- să cunoască modul în care se execută instrucţiunile şi conceptul de
pipeline;
- să cunoască rolul registrului de lucru (WREG) şi al registrului
STATUS.

1.1 ARHITECTURA VON NEUMANN

Din punct de vedere istoric sistemele de calcul moderne îşi au originea în cele
dezvoltate în timpul celui de-al doilea război mondial. Aceste sisteme iniţiale îndeplineau o
funcţionalitate dedicată, fiind proiectate pentru a realiza o singură sarcină pe baza unui set de
date, iar pentru a-şi schimba comportamentul era necesară refacerea conexiunilor fizice dintre
elementele componente. Evoluţia esenţială a acestor sisteme de calcul rudimentare s-a produs
în momentul în care s-a înţeles că programul putea fi stocat în memorie alături de date. Unul
dintre avantajele acestei arhitecturi, denumită von Neumann, după numele celui care a
coordonat proiectul, îl reprezintă flexibilitatea. Astfel, modificarea programului presupune
doar încărcarea secvenţei de biţi corespunzătoare în zona de memorie potrivită.
Simplitatea arhitecturii von Neumann a făcut ca majoritatea sistemelor de calcul
moderne să fie bazate pe această structură. Elementele caracteristice ale acestor sisteme de
calcul sunt: unitatea centrală de prelucrare (UCP), memoriile, echipamentele de intrare ieşire
şi magistralele. Unitatea centrală de prelucrare conţine o unitate de control, care realizează
interpretarea, secvenţierea instrucţiunilor şi comandă celelalte componente ale sistemului, şi o
unitate aritmetică şi logică (UAL), care execută instrucţiuni. Unitatea de memorie stochează
instrucţiuni şi date, iar echipamentele periferice asigură interacţiunea dintre sistemul de calcul

10
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

şi mediul înconjurător prin introducerea instrucţiunilor şi a datelor, respectiv prin


reprezentarea rezultatelor. Magistralele furnizează căile de comunicaţie între componentele
sistemului de calcul.
În Fig. 1.1 se prezintă structura generală a sistemelor de calcul bazate pe arhitectura
von Neumann.

Fig. 1.1. Structura generală a sistemelor de calcul bazate pe arhitectura von Neumann

1.1.1 Unitatea centrală de prelucrare (UCP)

Funcţia principală a unităţii centrale de prelucrare (UCP) este de a executa o secvenţă


de instrucţiuni stocată în memorie. Acest lucru se va realiza în mod continuu şi repetat atâta
timp cât sitemul este activ. Un ciclu de instrucţiune presupune extragerea instrucţiunilor din
memorie într-un registru intern al UCP, decodificarea acestora şi apoi execuţia propriuzisă.
Extragerea succesivă a instrucţiunilor din memorie se realizează sub controlul unui circuit
denumit numărător de program (en. PC – Program Counter), care va conţine adresa
următoarei instrucţiuni din memorie care urmează a fi extrasă. Datele rezultate din execuţia
programului sau datele utilizate de program pot fi accesate din memorie. De asemenea,
unitatea centrală de prelucrare supervizează şi comandă celelalte componente ale sistemului
prin liniile de control.[8]
Structura internă a unităţii centrale de prelucrare conţine în general următoarele
componente majore:
1. O unitate de control care realizează interpretarea şi secvenţierea
instrucţiunilor, precum şi comanda celorlalte componente ale sistemului.
2. O unitate aritmetică şi logică care execută instrucţiunile din memorie. Ea este
responsabilă de manipularea datelor şi executarea operaţiilor aritmetice şi logice.
3. Regiştri interni (memorii de mare viteză), cu rol în stocarea de informaţii
necesare execuţiei instrucţiunilor (ex. Registrul de instrucţiuni, acumulatorul etc.).
În general, aceşti regiştri interni stochează doar câţiva octeţi de date, care pot fi
operanzi, rezultate, adrese de memorie etc.

11
ARHITECTURA GENERALĂ

1.1.2 Magistralele

Magistralele reprezintă căile de comunicaţie ale sistemului de calcul. Informaţia


transferată între componentele sistemului este transmisă sub formă binară, paralel pe liniile
magistralelor. Se pot identifica trei tipuri de magistrale:

1. Magistrala de date este utilizată la transferul datelor necesare procesării efectuate de


UCP. De exemplu, un sistem de calcul de 8 biţi este un sistem de calcul care dispune
de o magistrală de date cu lăţimea de 8 biţi, fiind capabil să transfere date (numere)
reprezentate pe 8 biţi. Astfel, un asemenea sistem va putea efecuta operaţii între
operanzi reprezentaţi pe 8 biţi, furnizând rezultate reprezentate pe 8 biţi.
Existenţa unei magistrale de 8 biţi nu limitează procesorul doar la utilizarea datelor cu
dimensiunea de 8 biţi, ci indică faptul că procesorul poate accesa un singur octet de
date per ciclu de memorie. De aceea, în raport cu o magistrală cu lăţimea de 16 biţi, o
magistrală de 8 biţi poate transmite doar jumătate din informaţie în unitatea de timp.
Astfel, procesoarele de 16 biţi sunt mai rapide decât cele de 8 biţi ş.a.m.d. Chiar dacă
procesoarele de 16, 32 sau 64 de biţi pot accesa date cu dimensiunea maximă egală cu
laţimea magistralelor lor, ele pot accesa la fel de bine şi locaţii de memorie cu
dimensiunea mai mică (ex. câte un octet).
Totuşi, există şi cazuri în care dimensiunea magistralei externe de date este diferită de
cea a magistralei interne a procesorului. În aceste cazuri se vor realiza mai multe
transferuri din memorie pentru a extrage un operand.

2. Magistrala de adrese este utilizată pentru specificarea adreselor locaţiilor de


memorie accesate. De exemplu, în cazul unei magistrale de adrese de 8 biţi, sistemul
poate accesa 28=256 locaţii de memorie distincte. Cu 16 linii de adresă se pot adresa
65536 locaţii de memorie.

3. Magistrala de control are rolul de a conduce semnalele de control ale UCP care
comandă componentele sistemului. De exemplu, semnalele transmise prin intermediul
magistralei de control pot specifica modul de acces la memorie în vederea realizării
unor operaţii de scriere sau de citire. Practic liniile de scriere şi citire ale magistralei
controlează direcţia datelor de pe magistrala de date. Alte semnale ale magistralei de
control pot include: tactul sistem, liniile de întrerupere, linii de stare etc.

12
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1.1.3 Memoria

Memoriile sunt caracterizate prin conţinutul pe care acestea îl stochează într-un set de
regiştri şi locaţia sau adresa individuală a fiecărui registru. În cazul arhitecturii von Neumann,
atât instrucţiunile cât şi datele se găsesc în acelaşi spaţiu de memorie. Indiferent că este
internă sau externă, memoria reprezintă un spaţiu de stocare şi poate fi accesată cu ajutorul
magistralelor dacă se specifică adresa locaţiei dorite şi tipul operaţiei (scriere sau citire).

1.1.4 Echipamentele de intrare-ieşire

Pentru a putea fi util un sistem de calcul trebuie să fie capabil să interacţioneze cu


mediul înconjurător. Acest lucru se realizează prin intermediul echipmantelor de intrare ieşire.
Comunicarea dintre UCP şi echipamentele periferice se va efectua tot prin intermediul
magistralelor printr-un set de regiştri cu adrese proprii denumite porturi. Porturile pot fi
accesate în mod similar cu memoria, în multe situaţii chiar sunt mapate în spaţiul de adrese al
memoriei. Prin intermediul porturilor pot fi configurate perifericele, pot fi trimise date direct
spre exterior sau pot fi citite date binare din exterior.

1.2 ARHITECTURA HARVARD

Principalul avantaj al arhitecturii von Neumann îl reprezintă simplitatea, totuşi,


existenţa unor magistrale comune pentru toate cele trei componente ale arhitecturii determină
faptul că sistemul de calcul în cauză nu poate realiza la un anumit moment decât un singur
lucru. Astfel, de exemplu, accesul la datele din memorie nu se poate produce în acelaşi timp
cu extragerea unei instrucţiuni din memorie.
În aceste condiţii, în prima decadă după cel de-al doilea război mondial s-a dezvoltat
la universitatea Harvard o nouă arhitectură pentru sistemele de calcul. Această arhitectură,
denumită arhitectura Harvard reprezenta o variaţie a arhitecturii von Neumann fiind
caracterizată de faptul că datele şi instrucţiunile sunt stocate separat în spaţii de memorie
distincte şi sunt accesate prin magistrale diferite. Avantajul acestei arhitecturi este dat de
posibilitatea de a accesa datele şi instrucţiunile în acelaşi timp, având drept consecinţă
creşterea complexităţii arhitecturii interne. Acesta este şi motivul pentru care arhitectura
Harvard a început să fie prezentă mai mult abia odată cu evoluţia circuitelor integrate.

13
ARHITECTURA GENERALĂ

În Fig. 1.2 sunt alăturate, cu scop comparativ, cele două tipuri de arhitecturi de sisteme
de calcul: von Neumann (Fig. 1.2-a) şi Harvard (Fig. 1.2-b). În cea din urmă se evidenţiază
cele două spaţii de memorie distincte împreună cu magistralele asociate. Fiecare memorie
dispune de propria sa magistrală de adrese, respectiv de date, astfel încât nu există nici o
legătură între adresele sau datele celor două spaţii de memorie.[10,19]

Fig. 1.2. Comparaţie între arhitecturile von Neumann şi Harvard

1.3 MICROPROCESOR SAU MICROCONTROLER?

Până acum, în paragrafele anterioare s-a făcut referire doar la câteva sisteme de calcul
care ne trimit cu gândul mai mult spre calculatoarele numerice.
Dar, ce sunt de fapt microprocesoarele, respectiv microcontrolerele?
Pe scurt, microprocesorul implementează funcţiile unităţii centrale de prelucrare.
Pentru a putea fi folosit într-un sistem de calcul, unui microprocesor trebuie să i se adauge
alte componente, cum ar fi memorie, sau componente pentru primirea şi trimiterea datelor.
Pe de altă parte microcontrolerul a fost proiectat să conţină toate cele trei
componente principale (UCP, memorie, echipamente de intrare-ieşire) într-un singur circuit
integrat. Astfel, nu mai sunt necesare alte componente externe deoarece toate perifericele
sunt deja incluse în el. Funcţiile principale ale componentelor însă rămân neschimbate fiind
aceleaşi indiferent de aplicaţia dezvoltată, dar din motive de preţ şi dimensiune
microcontrolerele dispun de un set redus de instrucţiuni şi o capacitate de adresare mai mică.
Astfel, făcând trimitere la cele două tipuri de arhitecturi prezentate anterior în Fig. 1.1
şi Fig. 1.2, microprocesorul reprezintă unitatea centrală de prelucrare, pe când
microcontrolerul reprezintă întreg sistemul de calcul.[4,6]

14
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Pentru a pune în evidenţă structura internă a microcontrolerelor se consideră următorul


exemplu.
Se analizează cazul unui sistem de control al unei sere, bazat pe
microcontroler. Acesta monitorizează parametri precum: umiditatea
solului, temperatura ambiantă sau gradul de iluminare şi comandă diferite
Exemplu
echipamente pentru a stabili condiţiile optime în seră (Fig. 1.3).

Fig. 1.3. Controlul unei sere cu ajutorul unui microsistem

Astfel, umiditatea din sol se măsoară cu ajutorul unui traductor de


umiditate care furnizează un semnal analogic. Dacă acest semnal este sub
o anumită valoare se comandă pornirea sistemului de irigaţie care
presupune deschiderea unei valve pentru apă timp de 5 secunde, apoi
închiderea acesteia timp de 5 secunde şi repetarea acestui ciclu până la
refacerea umidităţii dorite a solului
De asemenea, se monitorizează temperatura din seră cu ajutorul unui
senzor de temperatură şi se comandă deschiderea / închiderea ferestrelor,
precum şi sistemul de încalzire al serei.
În contextul acestei aplicaţii, sistemul de control trebuie să interfaţeze
diverse semnale. Astfel, pentru interfaţarea semnalelor care provin de la
traductorul de umiditate, senzorul de lumină, respectiv cel de temperatură,
vor fi necesare trei intrări analogice, respectiv un convertor analog-digital.
Convertorul analog-digital va discretiza pe rând cele trei semnale
furnizând intern valorile digitale echivalente care vor putea fi comparate
cu referinţele impuse. Pornirea iluminatului, comanda ferestrelor serei, a
sistemului de incălzire sau a sistemului de irigaţie se poate realiza prin
semnale de control discrete, de tip închis/deschis furnizate de la un port de
ieşire digital în baza logicii de control realizate prin programul memorat.
Dacă presupunem că acest sistem necesită şi o interfaţă cu utilizatorul care
să permită fixarea parametrilor de funcţionare ai serei, precum şi afişarea

15
ARHITECTURA GENERALĂ

unor informaţii utile putem completa necesarul de porturi de intrare/ieşire


digitale.

În continuare se pot rezuma resursele necesare pentru implementarea


proiectului:
- o intrare pentru un oscilator extern conectat la un counter/timer
care să furnizeze baza de timp pentru obţinerea celor 5 secunde
cerute. În general, tactul sistem este de cele mai multe ori folosit
de către un timer intern pentru obţinerea temporizărilor;
- trei intrări analogice şi un convertor analog-digital necesare pentru
măsurarea semnalelor care provin de la traductorul de umiditate,
senzorul de temperatură şi cel de lumină;
- o ieşire digitală pentru comanda valvei sistemului de irigat;
- o ieşire digitală pentru comanda motoarelor de acţionare ale
ferestrelor serei;
- o ieşire digitală pentru comanda sistemului de încălzire;
- o ieşire digitală pentru comanda sistemului de iluminat;
- intrări şi ieşiri digitale suplimentare pentru interfaţarea unui panou
de comandă care poate cuprinde butoane şi elemente de afişare
(ex. LED-uri, afişaj LCD);
- UCP pentru realizarea calculelor şi pentru efectuarea operaţiilor de
intrare-ieşire;
- Memorie program (de obicei memorie de tip ROM) pentru
stocarea logicii de control;
- Memorie de date pentru stocarea variabilelor temporare (de obicei
memorie de tip RAM).
Presupunând că programul de control nu ocupă complet toate resursele
microcontrolerului, sistemul ar mai putea transmite date la distanţă prin
intermediul unui sistem de comunicaţie.

În concluzie, pornind de la exemplul anterior se pot identifica o parte din


componentele unui microcontroler. Astfel, structura generală a microcontrolerelor include
unitatea centrală de prelucrare, memorii pentru stocarea datelor şi a programului, ceas intern,
timere, interfeţe de comunicaţie, convertoare analog-digitale, circuite de veghe şi bineînţeles
porturi pentru intrări şi ieşiri digitale şi analogice.[8]

16
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.4. Structura generală a microcontrolerelor

1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR DIN FAMILIA PIC18F

PIC este o familie de microcontrolere produse de compania Microchip Technology.


Denumirea PIC este o prescurtare de la “Programmable Intelligent Computer” (Calculator
Inteligent Programabil). Succesul de care se bucură aceste microcontrolere se datorează în
mare măsură suportului oferit de producător şi al mediului de dezvoltare MPLAB IDE
disponibil gratuit pe site-ul producătorului1. Numărul mare de aplicaţii, posibilitatea de a
dezvolta aplicaţiile în limbaj de asamblare sau în C, dar şi o mulţime de biblioteci bine
documentate permit dezvoltarea rapidă a aplicaţiilor şi fac din aceste microcontrolere un bun
candidat pentru studiul din acest curs.
PIC 18 reprezintă o familie de microcontrolere cu instrucţiuni pe 16 biţi, şi magistrală
internă de date de 8 biţi, memorie program de tip flash, spaţiu de memorie date adresabil
liniar. Familia a fost extinsă cu un număr mare de protocoale de comunicaţii, CAN, Ethernet,
USB, SPI, I2C, Irda, existând în prezent peste 100 de membri ai familiei fiecare cu alte
combinaţii de facilităţi. În continuare se prezintă câteva caracteristici ale acestor
microcontrolere.
Microcontrolerele PIC analizate în acest curs sunt bazate pe arhitectura Harvard.
Pentru a reduce din complexitatea unităţii centrale de prelucrare, aceste microcontrolere
implementează un set redus de instrucţiuni (en. RISC = Reduced Instruction Set Computer).
Spre deosebire de procesoarele RISC, procesoarele cu set complex de instrucţiuni (en. CISC =
Complex Instruction Set Computer) au fost proiectate să implementeze un set de instrucţiuni
cât mai apropiat de cel al limbajelor de nivel înalt, motiv pentru care şi numărul de
instrucţiuni este mai mare. În schimb, procesoarele RISC dispun de un set compact de
instrucţiuni şi moduri mai puţine de adresare, obţinându-se în felul acesta timpi de execuţie ai
instucţiunilor mai mici la aceeaşi frecvenţă de tact.[8]

1
http://www.microchip.com [22]

17
ARHITECTURA GENERALĂ

Unul dintre avantajele importante ale arhitecturii Harvard este dat de faptul că
magistralele celor două tipuri de memorii pot avea dimensiuni diferite. Astfel, magistrala de
date (instrucţiuni) a memoriei program împreună cu memoria program pot fi organizate pe
cuvinte (în cazul analizat este vorba de cuvinte de 16 biţi), iar magistrala şi memoria de date
sunt organizate pe octet. Acest lucru, combinat cu setul redus de instrucţiuni permit
implementarea unor instrucţiuni cu lungime fixă ce pot fi extrase într-un singur pas.

1.4.1 Execuţia instrucţiunilor

Înţelegerea ciclului instrucţiune este esenţială pentru înţelegerea modului de


funcţionare al microcontrolerelor. Un ciclu instrucţiune presupune două faze principale:
- Faza de extragere a instrucţiunilor din memoria program într-un registru intern al
UCP
- Faza de execuţie care include decodificarea instrucţiunii, extragerea operanzilor,
efectuarea operaţiei specificate în codul instrucţiunii şi depunerea rezultatului în
memorie
Durata unui ciclu instrucţiune depinde de frecvenţa de lucru a sistemului, fiind egală
cu 2x4 tacţi sistem. Astfel, tactul sistem este divizat intern la patru fiind generate patru
semnale de tact în cuadratură (Q1, Q2, Q3 şi Q4). Numărătorul program este incrementat în
Q1, iar instrucţiunea este extrasă din memorie în registrul de instrucţiuni în Q4. În
următoarele Q1 până la Q4 instrucţiunea este decodificată (Q1), se citesc datele/operanzii din
memorie (Q2), se procesează datele în funcţie tipul instrucţiunii decodificate (Q3), se scriu
datele/rezultatele în memorie (Q4). Dacă oricare din aceşti paşi lipseşte, datorită tipului de
instrucţiune care se execută, se va insera un pas fără operaţie în locul lui, astfel încât timpul de
execuţie rămâne constant.[8,15]
Analizând cele două faze ale ciclului instrucţiune se constată că în faza de extragere
UCP accesează memoria program, iar în faza de execuţie UCP accesează memoria de date.
Ţinând cont de faptul că microcontrolerul implementează o arhitectura Harvard, iar cele două
memorii pot fi accesate prin magistrale independente, pentru a creşte performanţa sistemului
s-a implementat un pipeline pe două nivele pentru instrucţiuni. Acesta permite suprapunerea
celor două faze ale instrucţiunii. Astfel, în timp ce instucţiunea curentă este extrasă cea
precedentă se execută. În acest fel se reduce la jumătate timpul de execuţie al unei
instrucţiuni, datorită faptului că la fiecare 4 tacţi sistem se terimină de executat o instrucţiune.
Excepţie prezintă instrucţiunile care modifică valoarea numărătorului de program.

18
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.5. Fazele de execuţie ale instrucţiunilor [8,15]

Fig. 1.6. Exemplu de execuţie al unui set de instrucţiuni

Pornind de la modul în care se execută instrucţiunile, UCP poate fi împărţită în două


componente: Unitatea de control şi regiştrii asociaţi, respectiv Unitatea Aritmetică şi Logică.

1.4.2 Unitatea de control

În Fig. 1.7 se prezintă structura simplificată a unităţii de control împreună cu circuitele


componente.

Fig. 1.7. Unitatea de control

Instrucţiunile care constituie programul microcontrolerului sunt stocate în memoria


program sub forma unor cuvinte binare la adrese succesive. Un numărător binar, denumit
numărător de program (en. PC = Program Counter) este utilizat pentru a adresa pe rând

19
ARHITECTURA GENERALĂ

fiecare instrucţiune. Sub controlul acestui numărător, instrucţiunile vor fi extrase pe rând din
memoria program, iar apoi vor fi executate.
Doi regiştri de instrucţiuni, care împreună formează Pipeline-ul, vor stoca codul
instrucţiunilor extrase din memoria program. Cel de sus, Registrul de Instrucţiuni 1 (RI1) va
stoca instrucţiunea n şi o va păstra pe durata următorului ciclu instrucţiune. Această structură
permite ca instrucţiunea n-1, aflată în registrul de la baza pipeline-ului (Registrul de
Instrucţiuni 2 - RI2) să fie executată în timp ce instrucţiunea n este extrasă din memorie şi
stocată în Registrul de instrucţiuni 1 al pipeline-ului. După execuţia instrucţiunii n-1 se
transferă conţinutul din registrul de instrucţiuni 1 al pipeline-ului în registrul de instrucţiuni 2,
urmând ca în timp ce instrucţiunea n+1 este extrasă din memorie şi stocată în vârful pipeline-
ului, instrucţiunea de la bază (instrucţiunea n) să fie executată.
Una din componentele de bază ale UCP, decodificatorul, are rolul de a descifra codul
instrucţiunii stocate în registrul de la baza pipeline-ului şi contribuie la generarea semnalelor
de control interne necesare pentru execuţia instrucţiunii.

1.4.3 Unitatea aritmetică şi logică

Microcontrolerul conţine o unitate aritmetică si logică (Fig. 1.8) pe 8 biţi şi un registru


de lucru de 8 biţi (en. WREG = Work Register) denumit şi acumulator. Unitatea aritmetică este
capabilă să efectueze operaţii precum: adunare, scădere, operaţii logice (ŞI, SAU, XOR etc),
deplasări şi rotiri, înmulţire. În cazul instrucţiunilor cu doi operanzi (ex. adunare) unul din
operanzi se va găsi întotdeauna în registrul de lucru. Celălalt operand poate fi o constantă sau
un registru din memorie. În funcţie de starea unui bit din codul instrucţiunii, denumit bit de
destinaţie d, rezultatul operaţiilor poate fi stocat fie în registrul de lucru (d=0) fie în registrul
din memoria de date din care provenea operandul (d=1). Rezultatul operaţiei de înmulţiere se
va stoca întotdeauna într-o pereche de regiştri speciali PRODH:PRODL.
Introducerea registrului de lucru (WREG) în structura microcontrolerului contribuie la
simplificarea substanţială a modului de reprezentare al instrucţiunilor, lucru care conduce la
creşterea vitezei de execuţie a instrucţiunilor, precum şi la reducerea cantităţii de memorie
necesară pentru stocarea instrucţiunilor. Pentru a exemplifica această idee se poate considera
cazul unei operaţii de adunare în care intervin trei termeni: doi operanzi, respectiv un rezultat.
În lipsa registrului de lucru şi a bitului de destinaţie al rezultatului, codul instrucţiunii de
adunare ar fi trebuit să cuprindă specificarea tuturor celor trei termeni, în loc de unul singur,
lucru care ar fi condus la creşterea numărului de biţi necesari pentru reprezentarea
instrucţiunii.

20
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.8. Structura unităţii aritmetice şi logice

Operaţiile aritmetice şi logice pot genera o serie de indicatori ce vor fi stocaţi în


registrul de stare STATUS. Aceşti indicatori sunt: bitul de transport (C - Carry), bitul de
depăşire (OV - Overflow), bitul de semn (N - Negative), rezultat zero (Z - Zero), bitul de
transport auxiliar (DC – Digit Carry). Registrul de stare poate fi şi registru de destinaţie, dar
dacă operaţia executată va conduce la setarea acestor indicatori, se va suprascrie rezultatul. De
exemplu instrucţiunea CLRF STATUS, va şterge toţi biţii registrului STATUS, dar bitul Z va
fi setat la sfârsitul instrucţiunii. În concluzie, registrul de stare va conţine întotdeauna valorile
corecte ale indicatorilor.[8]
Structura registrului de stare STATUS este prezentată mai jos:

bit 7 bit 0
- - - N OV Z DC C
Fig. 1.9. Registrul STATUS

Pornind de la ideea introductivă conform căreia microcontrolerele


reprezintă încapsularea unor sisteme de calcul, în acest curs s-au prezentat

Concluzii principalele tipuri de arhitecturi existente, s-a evidenţiat structura acestora,


rolul elementelor componente, dar şi principalele avantaje şi dezavantaje
care le caracterizează. Studiul unei aplicaţii practice a condus la
identificarea necesarului de elemente componente în structua generală a
microcontrolerelor, iar familia de microcontrolere PIC18F a furnizat
suportul pentru aprofundarea conceptelor referitoare la modul de execuţie
al instrucţiunilor, respectiv la structura internă a UCP.

21
ARHITECTURA GENERALĂ

1. Arhitectura microcontrolerului permite extragerea unei instrucţiuni din


memorie simultan cu execuţia altei instrucţiuni. Discutaţi elementele
care permit realizarea acestor lucruri în paralel.
Întrebări de
2. Care este diferenţa între arhitectura von Neumann şi arhitectura
autoevaluare
Harvard a sistemelor de calcul?
3. Care este diferenţa între un microcontroler şi un microcprocesor?
4. Explicaţi rolul registrului de lucru (WREG) în arhitectura
microcontrolerului.
5. Explicaţi rolul registrului status (STATUS) în arhitectura
microcontrolerului.
6. Prezentaţi un avantaj şi un dezavantaj pentru fiecare din cele două
tipuri de arhitecturi prezentate.
7. Care sunt elementele componente ale unui sistem de calcul?
8. Care sunt fazele unei instrucţiuni?
9. Care este rolul numărătorului de program?
10. Cum este implementat pipeline-ul la nivelul unităţii de control?

Adresă
Colecţie de biţi utilizaţi pentru a identifica locaţiile de memorie
Termeni Ciclu instrucţiune
esenţiali Procesul prin care se extrage o instrucţiune din memoria program şi se
execută
CISC
Complex Instruction Set Computer
Dată
Conţinutul unei locaţii de memorie
Instrucţiuni
Comenzi pe care le execută UCP
Magistrală
Colecţie de fire prin care informaţia se transmite paralel între componentele
unui sistem de calcul
Memorie
Spaţiu de stocare
Memorie de date
Spaţiu de stocare temporar (RAM) pentru datele cu care lucrează programul

22
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Memorie program
Spaţiu de stocare pentru program
Microcontroler
Sistem de calcul încapsulat într-un singur circuit integrat
Microprocesor
Parte componentă a unui sistem de calcul, UCP
Numărător de program
Numărător binar utilizat pentru adresarea instrucţiunilor. Conţine adresa
instrucţiunii care urmează a fi executată
PIC
Programmable Intelligent Computer
Pipeline
Tehnică utilizată pentru a creşte numărul de instrucţiuni care pot fi
executate în unitatea de timp. Pipeline-ul nu reduce timpul necesar
execuţiei unei instrucţiuni, ci creşte numărul de instrucţiuni care pot fi
procesate simultan
Port
Calea de legătură a sistemului de calcul cu lumea exterioară prin care acesta
poate să trimită şi să primească date
Registru
Spaţiu de stocare
Registru de instrucţiuni
Spaţiu de stocare temporar pentru o instrucţiune extrasă din memorie
RISC
Reduced Instruction Set Computer
STATUS
Registru care indică starea operaţiilor aritmetice şi logice executate de
unitatea aritmetică şi logică
UAL
Unitate aritmetică şi logică
UCP
Unitate centrală de prelucrare
WREG
Registru de lucru / acumulator. În general conţine unul din operanzii
instrucţiunilor

23
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1. ARHITECTURA GENERALĂ

Introducere
Obiective
1.1 ARHITECTURA VON NEUMANN
Cuprins
1.1.1 Unitatea centrală de prelucrare
1.1.2 Magistralele
1.1.3 Memoria
1.1.4 Echipamentele de intrare-ieşire
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
1.4.1 Execuţia instrucţiunilor
1.4.2 Unitatea de control
1.4.3 Unitatea aritmetică şi logică
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

9
ARHITECTURA GENERALĂ

Microcontrolerele sunt în esenţă sisteme de calcul având arhitectura


modelată pe baza celei a calculatoarelor numerice. Pornind de la această
idee, capitolul curent urmăreşte câteva principii privind arhitectura şi
Introducere
modul de funcţionare al acestor tipuri de sisteme.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă deosebirile existente între arhitecturile sistemelor de
calcul de tip von Neumann şi Harvard;
Obiective - să înţeleagă relaţia dintre microcontrolere şi microprocesoare
- să cunoască rolul şi structura elementelor componente ale
sistemelor de calcul;
- să cunoască modul în care se execută instrucţiunile şi conceptul de
pipeline;
- să cunoască rolul registrului de lucru (WREG) şi al registrului
STATUS.

1.1 ARHITECTURA VON NEUMANN

Din punct de vedere istoric sistemele de calcul moderne îşi au originea în cele
dezvoltate în timpul celui de-al doilea război mondial. Aceste sisteme iniţiale îndeplineau o
funcţionalitate dedicată, fiind proiectate pentru a realiza o singură sarcină pe baza unui set de
date, iar pentru a-şi schimba comportamentul era necesară refacerea conexiunilor fizice dintre
elementele componente. Evoluţia esenţială a acestor sisteme de calcul rudimentare s-a produs
în momentul în care s-a înţeles că programul putea fi stocat în memorie alături de date. Unul
dintre avantajele acestei arhitecturi, denumită von Neumann, după numele celui care a
coordonat proiectul, îl reprezintă flexibilitatea. Astfel, modificarea programului presupune
doar încărcarea secvenţei de biţi corespunzătoare în zona de memorie potrivită.
Simplitatea arhitecturii von Neumann a făcut ca majoritatea sistemelor de calcul
moderne să fie bazate pe această structură. Elementele caracteristice ale acestor sisteme de
calcul sunt: unitatea centrală de prelucrare (UCP), memoriile, echipamentele de intrare ieşire
şi magistralele. Unitatea centrală de prelucrare conţine o unitate de control, care realizează
interpretarea, secvenţierea instrucţiunilor şi comandă celelalte componente ale sistemului, şi o
unitate aritmetică şi logică (UAL), care execută instrucţiuni. Unitatea de memorie stochează
instrucţiuni şi date, iar echipamentele periferice asigură interacţiunea dintre sistemul de calcul

10
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

şi mediul înconjurător prin introducerea instrucţiunilor şi a datelor, respectiv prin


reprezentarea rezultatelor. Magistralele furnizează căile de comunicaţie între componentele
sistemului de calcul.
În Fig. 1.1 se prezintă structura generală a sistemelor de calcul bazate pe arhitectura
von Neumann.

Fig. 1.1. Structura generală a sistemelor de calcul bazate pe arhitectura von Neumann

1.1.1 Unitatea centrală de prelucrare (UCP)

Funcţia principală a unităţii centrale de prelucrare (UCP) este de a executa o secvenţă


de instrucţiuni stocată în memorie. Acest lucru se va realiza în mod continuu şi repetat atâta
timp cât sitemul este activ. Un ciclu de instrucţiune presupune extragerea instrucţiunilor din
memorie într-un registru intern al UCP, decodificarea acestora şi apoi execuţia propriuzisă.
Extragerea succesivă a instrucţiunilor din memorie se realizează sub controlul unui circuit
denumit numărător de program (en. PC – Program Counter), care va conţine adresa
următoarei instrucţiuni din memorie care urmează a fi extrasă. Datele rezultate din execuţia
programului sau datele utilizate de program pot fi accesate din memorie. De asemenea,
unitatea centrală de prelucrare supervizează şi comandă celelalte componente ale sistemului
prin liniile de control.[8]
Structura internă a unităţii centrale de prelucrare conţine în general următoarele
componente majore:
1. O unitate de control care realizează interpretarea şi secvenţierea
instrucţiunilor, precum şi comanda celorlalte componente ale sistemului.
2. O unitate aritmetică şi logică care execută instrucţiunile din memorie. Ea este
responsabilă de manipularea datelor şi executarea operaţiilor aritmetice şi logice.
3. Regiştri interni (memorii de mare viteză), cu rol în stocarea de informaţii
necesare execuţiei instrucţiunilor (ex. Registrul de instrucţiuni, acumulatorul etc.).
În general, aceşti regiştri interni stochează doar câţiva octeţi de date, care pot fi
operanzi, rezultate, adrese de memorie etc.

11
ARHITECTURA GENERALĂ

1.1.2 Magistralele

Magistralele reprezintă căile de comunicaţie ale sistemului de calcul. Informaţia


transferată între componentele sistemului este transmisă sub formă binară, paralel pe liniile
magistralelor. Se pot identifica trei tipuri de magistrale:

1. Magistrala de date este utilizată la transferul datelor necesare procesării efectuate de


UCP. De exemplu, un sistem de calcul de 8 biţi este un sistem de calcul care dispune
de o magistrală de date cu lăţimea de 8 biţi, fiind capabil să transfere date (numere)
reprezentate pe 8 biţi. Astfel, un asemenea sistem va putea efecuta operaţii între
operanzi reprezentaţi pe 8 biţi, furnizând rezultate reprezentate pe 8 biţi.
Existenţa unei magistrale de 8 biţi nu limitează procesorul doar la utilizarea datelor cu
dimensiunea de 8 biţi, ci indică faptul că procesorul poate accesa un singur octet de
date per ciclu de memorie. De aceea, în raport cu o magistrală cu lăţimea de 16 biţi, o
magistrală de 8 biţi poate transmite doar jumătate din informaţie în unitatea de timp.
Astfel, procesoarele de 16 biţi sunt mai rapide decât cele de 8 biţi ş.a.m.d. Chiar dacă
procesoarele de 16, 32 sau 64 de biţi pot accesa date cu dimensiunea maximă egală cu
laţimea magistralelor lor, ele pot accesa la fel de bine şi locaţii de memorie cu
dimensiunea mai mică (ex. câte un octet).
Totuşi, există şi cazuri în care dimensiunea magistralei externe de date este diferită de
cea a magistralei interne a procesorului. În aceste cazuri se vor realiza mai multe
transferuri din memorie pentru a extrage un operand.

2. Magistrala de adrese este utilizată pentru specificarea adreselor locaţiilor de


memorie accesate. De exemplu, în cazul unei magistrale de adrese de 8 biţi, sistemul
poate accesa 28=256 locaţii de memorie distincte. Cu 16 linii de adresă se pot adresa
65536 locaţii de memorie.

3. Magistrala de control are rolul de a conduce semnalele de control ale UCP care
comandă componentele sistemului. De exemplu, semnalele transmise prin intermediul
magistralei de control pot specifica modul de acces la memorie în vederea realizării
unor operaţii de scriere sau de citire. Practic liniile de scriere şi citire ale magistralei
controlează direcţia datelor de pe magistrala de date. Alte semnale ale magistralei de
control pot include: tactul sistem, liniile de întrerupere, linii de stare etc.

12
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1.1.3 Memoria

Memoriile sunt caracterizate prin conţinutul pe care acestea îl stochează într-un set de
regiştri şi locaţia sau adresa individuală a fiecărui registru. În cazul arhitecturii von Neumann,
atât instrucţiunile cât şi datele se găsesc în acelaşi spaţiu de memorie. Indiferent că este
internă sau externă, memoria reprezintă un spaţiu de stocare şi poate fi accesată cu ajutorul
magistralelor dacă se specifică adresa locaţiei dorite şi tipul operaţiei (scriere sau citire).

1.1.4 Echipamentele de intrare-ieşire

Pentru a putea fi util un sistem de calcul trebuie să fie capabil să interacţioneze cu


mediul înconjurător. Acest lucru se realizează prin intermediul echipmantelor de intrare ieşire.
Comunicarea dintre UCP şi echipamentele periferice se va efectua tot prin intermediul
magistralelor printr-un set de regiştri cu adrese proprii denumite porturi. Porturile pot fi
accesate în mod similar cu memoria, în multe situaţii chiar sunt mapate în spaţiul de adrese al
memoriei. Prin intermediul porturilor pot fi configurate perifericele, pot fi trimise date direct
spre exterior sau pot fi citite date binare din exterior.

1.2 ARHITECTURA HARVARD

Principalul avantaj al arhitecturii von Neumann îl reprezintă simplitatea, totuşi,


existenţa unor magistrale comune pentru toate cele trei componente ale arhitecturii determină
faptul că sistemul de calcul în cauză nu poate realiza la un anumit moment decât un singur
lucru. Astfel, de exemplu, accesul la datele din memorie nu se poate produce în acelaşi timp
cu extragerea unei instrucţiuni din memorie.
În aceste condiţii, în prima decadă după cel de-al doilea război mondial s-a dezvoltat
la universitatea Harvard o nouă arhitectură pentru sistemele de calcul. Această arhitectură,
denumită arhitectura Harvard reprezenta o variaţie a arhitecturii von Neumann fiind
caracterizată de faptul că datele şi instrucţiunile sunt stocate separat în spaţii de memorie
distincte şi sunt accesate prin magistrale diferite. Avantajul acestei arhitecturi este dat de
posibilitatea de a accesa datele şi instrucţiunile în acelaşi timp, având drept consecinţă
creşterea complexităţii arhitecturii interne. Acesta este şi motivul pentru care arhitectura
Harvard a început să fie prezentă mai mult abia odată cu evoluţia circuitelor integrate.

13
ARHITECTURA GENERALĂ

În Fig. 1.2 sunt alăturate, cu scop comparativ, cele două tipuri de arhitecturi de sisteme
de calcul: von Neumann (Fig. 1.2-a) şi Harvard (Fig. 1.2-b). În cea din urmă se evidenţiază
cele două spaţii de memorie distincte împreună cu magistralele asociate. Fiecare memorie
dispune de propria sa magistrală de adrese, respectiv de date, astfel încât nu există nici o
legătură între adresele sau datele celor două spaţii de memorie.[10,19]

Fig. 1.2. Comparaţie între arhitecturile von Neumann şi Harvard

1.3 MICROPROCESOR SAU MICROCONTROLER?

Până acum, în paragrafele anterioare s-a făcut referire doar la câteva sisteme de calcul
care ne trimit cu gândul mai mult spre calculatoarele numerice.
Dar, ce sunt de fapt microprocesoarele, respectiv microcontrolerele?
Pe scurt, microprocesorul implementează funcţiile unităţii centrale de prelucrare.
Pentru a putea fi folosit într-un sistem de calcul, unui microprocesor trebuie să i se adauge
alte componente, cum ar fi memorie, sau componente pentru primirea şi trimiterea datelor.
Pe de altă parte microcontrolerul a fost proiectat să conţină toate cele trei
componente principale (UCP, memorie, echipamente de intrare-ieşire) într-un singur circuit
integrat. Astfel, nu mai sunt necesare alte componente externe deoarece toate perifericele
sunt deja incluse în el. Funcţiile principale ale componentelor însă rămân neschimbate fiind
aceleaşi indiferent de aplicaţia dezvoltată, dar din motive de preţ şi dimensiune
microcontrolerele dispun de un set redus de instrucţiuni şi o capacitate de adresare mai mică.
Astfel, făcând trimitere la cele două tipuri de arhitecturi prezentate anterior în Fig. 1.1
şi Fig. 1.2, microprocesorul reprezintă unitatea centrală de prelucrare, pe când
microcontrolerul reprezintă întreg sistemul de calcul.[4,6]

14
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Pentru a pune în evidenţă structura internă a microcontrolerelor se consideră următorul


exemplu.
Se analizează cazul unui sistem de control al unei sere, bazat pe
microcontroler. Acesta monitorizează parametri precum: umiditatea
solului, temperatura ambiantă sau gradul de iluminare şi comandă diferite
Exemplu
echipamente pentru a stabili condiţiile optime în seră (Fig. 1.3).

Fig. 1.3. Controlul unei sere cu ajutorul unui microsistem

Astfel, umiditatea din sol se măsoară cu ajutorul unui traductor de


umiditate care furnizează un semnal analogic. Dacă acest semnal este sub
o anumită valoare se comandă pornirea sistemului de irigaţie care
presupune deschiderea unei valve pentru apă timp de 5 secunde, apoi
închiderea acesteia timp de 5 secunde şi repetarea acestui ciclu până la
refacerea umidităţii dorite a solului
De asemenea, se monitorizează temperatura din seră cu ajutorul unui
senzor de temperatură şi se comandă deschiderea / închiderea ferestrelor,
precum şi sistemul de încalzire al serei.
În contextul acestei aplicaţii, sistemul de control trebuie să interfaţeze
diverse semnale. Astfel, pentru interfaţarea semnalelor care provin de la
traductorul de umiditate, senzorul de lumină, respectiv cel de temperatură,
vor fi necesare trei intrări analogice, respectiv un convertor analog-digital.
Convertorul analog-digital va discretiza pe rând cele trei semnale
furnizând intern valorile digitale echivalente care vor putea fi comparate
cu referinţele impuse. Pornirea iluminatului, comanda ferestrelor serei, a
sistemului de incălzire sau a sistemului de irigaţie se poate realiza prin
semnale de control discrete, de tip închis/deschis furnizate de la un port de
ieşire digital în baza logicii de control realizate prin programul memorat.
Dacă presupunem că acest sistem necesită şi o interfaţă cu utilizatorul care
să permită fixarea parametrilor de funcţionare ai serei, precum şi afişarea

15
ARHITECTURA GENERALĂ

unor informaţii utile putem completa necesarul de porturi de intrare/ieşire


digitale.

În continuare se pot rezuma resursele necesare pentru implementarea


proiectului:
- o intrare pentru un oscilator extern conectat la un counter/timer
care să furnizeze baza de timp pentru obţinerea celor 5 secunde
cerute. În general, tactul sistem este de cele mai multe ori folosit
de către un timer intern pentru obţinerea temporizărilor;
- trei intrări analogice şi un convertor analog-digital necesare pentru
măsurarea semnalelor care provin de la traductorul de umiditate,
senzorul de temperatură şi cel de lumină;
- o ieşire digitală pentru comanda valvei sistemului de irigat;
- o ieşire digitală pentru comanda motoarelor de acţionare ale
ferestrelor serei;
- o ieşire digitală pentru comanda sistemului de încălzire;
- o ieşire digitală pentru comanda sistemului de iluminat;
- intrări şi ieşiri digitale suplimentare pentru interfaţarea unui panou
de comandă care poate cuprinde butoane şi elemente de afişare
(ex. LED-uri, afişaj LCD);
- UCP pentru realizarea calculelor şi pentru efectuarea operaţiilor de
intrare-ieşire;
- Memorie program (de obicei memorie de tip ROM) pentru
stocarea logicii de control;
- Memorie de date pentru stocarea variabilelor temporare (de obicei
memorie de tip RAM).
Presupunând că programul de control nu ocupă complet toate resursele
microcontrolerului, sistemul ar mai putea transmite date la distanţă prin
intermediul unui sistem de comunicaţie.

În concluzie, pornind de la exemplul anterior se pot identifica o parte din


componentele unui microcontroler. Astfel, structura generală a microcontrolerelor include
unitatea centrală de prelucrare, memorii pentru stocarea datelor şi a programului, ceas intern,
timere, interfeţe de comunicaţie, convertoare analog-digitale, circuite de veghe şi bineînţeles
porturi pentru intrări şi ieşiri digitale şi analogice.[8]

16
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.4. Structura generală a microcontrolerelor

1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR DIN FAMILIA PIC18F

PIC este o familie de microcontrolere produse de compania Microchip Technology.


Denumirea PIC este o prescurtare de la “Programmable Intelligent Computer” (Calculator
Inteligent Programabil). Succesul de care se bucură aceste microcontrolere se datorează în
mare măsură suportului oferit de producător şi al mediului de dezvoltare MPLAB IDE
disponibil gratuit pe site-ul producătorului1. Numărul mare de aplicaţii, posibilitatea de a
dezvolta aplicaţiile în limbaj de asamblare sau în C, dar şi o mulţime de biblioteci bine
documentate permit dezvoltarea rapidă a aplicaţiilor şi fac din aceste microcontrolere un bun
candidat pentru studiul din acest curs.
PIC 18 reprezintă o familie de microcontrolere cu instrucţiuni pe 16 biţi, şi magistrală
internă de date de 8 biţi, memorie program de tip flash, spaţiu de memorie date adresabil
liniar. Familia a fost extinsă cu un număr mare de protocoale de comunicaţii, CAN, Ethernet,
USB, SPI, I2C, Irda, existând în prezent peste 100 de membri ai familiei fiecare cu alte
combinaţii de facilităţi. În continuare se prezintă câteva caracteristici ale acestor
microcontrolere.
Microcontrolerele PIC analizate în acest curs sunt bazate pe arhitectura Harvard.
Pentru a reduce din complexitatea unităţii centrale de prelucrare, aceste microcontrolere
implementează un set redus de instrucţiuni (en. RISC = Reduced Instruction Set Computer).
Spre deosebire de procesoarele RISC, procesoarele cu set complex de instrucţiuni (en. CISC =
Complex Instruction Set Computer) au fost proiectate să implementeze un set de instrucţiuni
cât mai apropiat de cel al limbajelor de nivel înalt, motiv pentru care şi numărul de
instrucţiuni este mai mare. În schimb, procesoarele RISC dispun de un set compact de
instrucţiuni şi moduri mai puţine de adresare, obţinându-se în felul acesta timpi de execuţie ai
instucţiunilor mai mici la aceeaşi frecvenţă de tact.[8]

1
http://www.microchip.com [22]

17
ARHITECTURA GENERALĂ

Unul dintre avantajele importante ale arhitecturii Harvard este dat de faptul că
magistralele celor două tipuri de memorii pot avea dimensiuni diferite. Astfel, magistrala de
date (instrucţiuni) a memoriei program împreună cu memoria program pot fi organizate pe
cuvinte (în cazul analizat este vorba de cuvinte de 16 biţi), iar magistrala şi memoria de date
sunt organizate pe octet. Acest lucru, combinat cu setul redus de instrucţiuni permit
implementarea unor instrucţiuni cu lungime fixă ce pot fi extrase într-un singur pas.

1.4.1 Execuţia instrucţiunilor

Înţelegerea ciclului instrucţiune este esenţială pentru înţelegerea modului de


funcţionare al microcontrolerelor. Un ciclu instrucţiune presupune două faze principale:
- Faza de extragere a instrucţiunilor din memoria program într-un registru intern al
UCP
- Faza de execuţie care include decodificarea instrucţiunii, extragerea operanzilor,
efectuarea operaţiei specificate în codul instrucţiunii şi depunerea rezultatului în
memorie
Durata unui ciclu instrucţiune depinde de frecvenţa de lucru a sistemului, fiind egală
cu 2x4 tacţi sistem. Astfel, tactul sistem este divizat intern la patru fiind generate patru
semnale de tact în cuadratură (Q1, Q2, Q3 şi Q4). Numărătorul program este incrementat în
Q1, iar instrucţiunea este extrasă din memorie în registrul de instrucţiuni în Q4. În
următoarele Q1 până la Q4 instrucţiunea este decodificată (Q1), se citesc datele/operanzii din
memorie (Q2), se procesează datele în funcţie tipul instrucţiunii decodificate (Q3), se scriu
datele/rezultatele în memorie (Q4). Dacă oricare din aceşti paşi lipseşte, datorită tipului de
instrucţiune care se execută, se va insera un pas fără operaţie în locul lui, astfel încât timpul de
execuţie rămâne constant.[8,15]
Analizând cele două faze ale ciclului instrucţiune se constată că în faza de extragere
UCP accesează memoria program, iar în faza de execuţie UCP accesează memoria de date.
Ţinând cont de faptul că microcontrolerul implementează o arhitectura Harvard, iar cele două
memorii pot fi accesate prin magistrale independente, pentru a creşte performanţa sistemului
s-a implementat un pipeline pe două nivele pentru instrucţiuni. Acesta permite suprapunerea
celor două faze ale instrucţiunii. Astfel, în timp ce instucţiunea curentă este extrasă cea
precedentă se execută. În acest fel se reduce la jumătate timpul de execuţie al unei
instrucţiuni, datorită faptului că la fiecare 4 tacţi sistem se terimină de executat o instrucţiune.
Excepţie prezintă instrucţiunile care modifică valoarea numărătorului de program.

18
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.5. Fazele de execuţie ale instrucţiunilor [8,15]

Fig. 1.6. Exemplu de execuţie al unui set de instrucţiuni

Pornind de la modul în care se execută instrucţiunile, UCP poate fi împărţită în două


componente: Unitatea de control şi regiştrii asociaţi, respectiv Unitatea Aritmetică şi Logică.

1.4.2 Unitatea de control

În Fig. 1.7 se prezintă structura simplificată a unităţii de control împreună cu circuitele


componente.

Fig. 1.7. Unitatea de control

Instrucţiunile care constituie programul microcontrolerului sunt stocate în memoria


program sub forma unor cuvinte binare la adrese succesive. Un numărător binar, denumit
numărător de program (en. PC = Program Counter) este utilizat pentru a adresa pe rând

19
ARHITECTURA GENERALĂ

fiecare instrucţiune. Sub controlul acestui numărător, instrucţiunile vor fi extrase pe rând din
memoria program, iar apoi vor fi executate.
Doi regiştri de instrucţiuni, care împreună formează Pipeline-ul, vor stoca codul
instrucţiunilor extrase din memoria program. Cel de sus, Registrul de Instrucţiuni 1 (RI1) va
stoca instrucţiunea n şi o va păstra pe durata următorului ciclu instrucţiune. Această structură
permite ca instrucţiunea n-1, aflată în registrul de la baza pipeline-ului (Registrul de
Instrucţiuni 2 - RI2) să fie executată în timp ce instrucţiunea n este extrasă din memorie şi
stocată în Registrul de instrucţiuni 1 al pipeline-ului. După execuţia instrucţiunii n-1 se
transferă conţinutul din registrul de instrucţiuni 1 al pipeline-ului în registrul de instrucţiuni 2,
urmând ca în timp ce instrucţiunea n+1 este extrasă din memorie şi stocată în vârful pipeline-
ului, instrucţiunea de la bază (instrucţiunea n) să fie executată.
Una din componentele de bază ale UCP, decodificatorul, are rolul de a descifra codul
instrucţiunii stocate în registrul de la baza pipeline-ului şi contribuie la generarea semnalelor
de control interne necesare pentru execuţia instrucţiunii.

1.4.3 Unitatea aritmetică şi logică

Microcontrolerul conţine o unitate aritmetică si logică (Fig. 1.8) pe 8 biţi şi un registru


de lucru de 8 biţi (en. WREG = Work Register) denumit şi acumulator. Unitatea aritmetică este
capabilă să efectueze operaţii precum: adunare, scădere, operaţii logice (ŞI, SAU, XOR etc),
deplasări şi rotiri, înmulţire. În cazul instrucţiunilor cu doi operanzi (ex. adunare) unul din
operanzi se va găsi întotdeauna în registrul de lucru. Celălalt operand poate fi o constantă sau
un registru din memorie. În funcţie de starea unui bit din codul instrucţiunii, denumit bit de
destinaţie d, rezultatul operaţiilor poate fi stocat fie în registrul de lucru (d=0) fie în registrul
din memoria de date din care provenea operandul (d=1). Rezultatul operaţiei de înmulţiere se
va stoca întotdeauna într-o pereche de regiştri speciali PRODH:PRODL.
Introducerea registrului de lucru (WREG) în structura microcontrolerului contribuie la
simplificarea substanţială a modului de reprezentare al instrucţiunilor, lucru care conduce la
creşterea vitezei de execuţie a instrucţiunilor, precum şi la reducerea cantităţii de memorie
necesară pentru stocarea instrucţiunilor. Pentru a exemplifica această idee se poate considera
cazul unei operaţii de adunare în care intervin trei termeni: doi operanzi, respectiv un rezultat.
În lipsa registrului de lucru şi a bitului de destinaţie al rezultatului, codul instrucţiunii de
adunare ar fi trebuit să cuprindă specificarea tuturor celor trei termeni, în loc de unul singur,
lucru care ar fi condus la creşterea numărului de biţi necesari pentru reprezentarea
instrucţiunii.

20
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.8. Structura unităţii aritmetice şi logice

Operaţiile aritmetice şi logice pot genera o serie de indicatori ce vor fi stocaţi în


registrul de stare STATUS. Aceşti indicatori sunt: bitul de transport (C - Carry), bitul de
depăşire (OV - Overflow), bitul de semn (N - Negative), rezultat zero (Z - Zero), bitul de
transport auxiliar (DC – Digit Carry). Registrul de stare poate fi şi registru de destinaţie, dar
dacă operaţia executată va conduce la setarea acestor indicatori, se va suprascrie rezultatul. De
exemplu instrucţiunea CLRF STATUS, va şterge toţi biţii registrului STATUS, dar bitul Z va
fi setat la sfârsitul instrucţiunii. În concluzie, registrul de stare va conţine întotdeauna valorile
corecte ale indicatorilor.[8]
Structura registrului de stare STATUS este prezentată mai jos:

bit 7 bit 0
- - - N OV Z DC C
Fig. 1.9. Registrul STATUS

Pornind de la ideea introductivă conform căreia microcontrolerele


reprezintă încapsularea unor sisteme de calcul, în acest curs s-au prezentat

Concluzii principalele tipuri de arhitecturi existente, s-a evidenţiat structura acestora,


rolul elementelor componente, dar şi principalele avantaje şi dezavantaje
care le caracterizează. Studiul unei aplicaţii practice a condus la
identificarea necesarului de elemente componente în structua generală a
microcontrolerelor, iar familia de microcontrolere PIC18F a furnizat
suportul pentru aprofundarea conceptelor referitoare la modul de execuţie
al instrucţiunilor, respectiv la structura internă a UCP.

21
ARHITECTURA GENERALĂ

1. Arhitectura microcontrolerului permite extragerea unei instrucţiuni din


memorie simultan cu execuţia altei instrucţiuni. Discutaţi elementele
care permit realizarea acestor lucruri în paralel.
Întrebări de
2. Care este diferenţa între arhitectura von Neumann şi arhitectura
autoevaluare
Harvard a sistemelor de calcul?
3. Care este diferenţa între un microcontroler şi un microcprocesor?
4. Explicaţi rolul registrului de lucru (WREG) în arhitectura
microcontrolerului.
5. Explicaţi rolul registrului status (STATUS) în arhitectura
microcontrolerului.
6. Prezentaţi un avantaj şi un dezavantaj pentru fiecare din cele două
tipuri de arhitecturi prezentate.
7. Care sunt elementele componente ale unui sistem de calcul?
8. Care sunt fazele unei instrucţiuni?
9. Care este rolul numărătorului de program?
10. Cum este implementat pipeline-ul la nivelul unităţii de control?

Adresă
Colecţie de biţi utilizaţi pentru a identifica locaţiile de memorie
Termeni Ciclu instrucţiune
esenţiali Procesul prin care se extrage o instrucţiune din memoria program şi se
execută
CISC
Complex Instruction Set Computer
Dată
Conţinutul unei locaţii de memorie
Instrucţiuni
Comenzi pe care le execută UCP
Magistrală
Colecţie de fire prin care informaţia se transmite paralel între componentele
unui sistem de calcul
Memorie
Spaţiu de stocare
Memorie de date
Spaţiu de stocare temporar (RAM) pentru datele cu care lucrează programul

22
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Memorie program
Spaţiu de stocare pentru program
Microcontroler
Sistem de calcul încapsulat într-un singur circuit integrat
Microprocesor
Parte componentă a unui sistem de calcul, UCP
Numărător de program
Numărător binar utilizat pentru adresarea instrucţiunilor. Conţine adresa
instrucţiunii care urmează a fi executată
PIC
Programmable Intelligent Computer
Pipeline
Tehnică utilizată pentru a creşte numărul de instrucţiuni care pot fi
executate în unitatea de timp. Pipeline-ul nu reduce timpul necesar
execuţiei unei instrucţiuni, ci creşte numărul de instrucţiuni care pot fi
procesate simultan
Port
Calea de legătură a sistemului de calcul cu lumea exterioară prin care acesta
poate să trimită şi să primească date
Registru
Spaţiu de stocare
Registru de instrucţiuni
Spaţiu de stocare temporar pentru o instrucţiune extrasă din memorie
RISC
Reduced Instruction Set Computer
STATUS
Registru care indică starea operaţiilor aritmetice şi logice executate de
unitatea aritmetică şi logică
UAL
Unitate aritmetică şi logică
UCP
Unitate centrală de prelucrare
WREG
Registru de lucru / acumulator. În general conţine unul din operanzii
instrucţiunilor

23
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1. ARHITECTURA GENERALĂ

Introducere
Obiective
1.1 ARHITECTURA VON NEUMANN
Cuprins
1.1.1 Unitatea centrală de prelucrare
1.1.2 Magistralele
1.1.3 Memoria
1.1.4 Echipamentele de intrare-ieşire
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
1.4.1 Execuţia instrucţiunilor
1.4.2 Unitatea de control
1.4.3 Unitatea aritmetică şi logică
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

9
ARHITECTURA GENERALĂ

Microcontrolerele sunt în esenţă sisteme de calcul având arhitectura


modelată pe baza celei a calculatoarelor numerice. Pornind de la această
idee, capitolul curent urmăreşte câteva principii privind arhitectura şi
Introducere
modul de funcţionare al acestor tipuri de sisteme.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă deosebirile existente între arhitecturile sistemelor de
calcul de tip von Neumann şi Harvard;
Obiective - să înţeleagă relaţia dintre microcontrolere şi microprocesoare
- să cunoască rolul şi structura elementelor componente ale
sistemelor de calcul;
- să cunoască modul în care se execută instrucţiunile şi conceptul de
pipeline;
- să cunoască rolul registrului de lucru (WREG) şi al registrului
STATUS.

1.1 ARHITECTURA VON NEUMANN

Din punct de vedere istoric sistemele de calcul moderne îşi au originea în cele
dezvoltate în timpul celui de-al doilea război mondial. Aceste sisteme iniţiale îndeplineau o
funcţionalitate dedicată, fiind proiectate pentru a realiza o singură sarcină pe baza unui set de
date, iar pentru a-şi schimba comportamentul era necesară refacerea conexiunilor fizice dintre
elementele componente. Evoluţia esenţială a acestor sisteme de calcul rudimentare s-a produs
în momentul în care s-a înţeles că programul putea fi stocat în memorie alături de date. Unul
dintre avantajele acestei arhitecturi, denumită von Neumann, după numele celui care a
coordonat proiectul, îl reprezintă flexibilitatea. Astfel, modificarea programului presupune
doar încărcarea secvenţei de biţi corespunzătoare în zona de memorie potrivită.
Simplitatea arhitecturii von Neumann a făcut ca majoritatea sistemelor de calcul
moderne să fie bazate pe această structură. Elementele caracteristice ale acestor sisteme de
calcul sunt: unitatea centrală de prelucrare (UCP), memoriile, echipamentele de intrare ieşire
şi magistralele. Unitatea centrală de prelucrare conţine o unitate de control, care realizează
interpretarea, secvenţierea instrucţiunilor şi comandă celelalte componente ale sistemului, şi o
unitate aritmetică şi logică (UAL), care execută instrucţiuni. Unitatea de memorie stochează
instrucţiuni şi date, iar echipamentele periferice asigură interacţiunea dintre sistemul de calcul

10
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

şi mediul înconjurător prin introducerea instrucţiunilor şi a datelor, respectiv prin


reprezentarea rezultatelor. Magistralele furnizează căile de comunicaţie între componentele
sistemului de calcul.
În Fig. 1.1 se prezintă structura generală a sistemelor de calcul bazate pe arhitectura
von Neumann.

Fig. 1.1. Structura generală a sistemelor de calcul bazate pe arhitectura von Neumann

1.1.1 Unitatea centrală de prelucrare (UCP)

Funcţia principală a unităţii centrale de prelucrare (UCP) este de a executa o secvenţă


de instrucţiuni stocată în memorie. Acest lucru se va realiza în mod continuu şi repetat atâta
timp cât sitemul este activ. Un ciclu de instrucţiune presupune extragerea instrucţiunilor din
memorie într-un registru intern al UCP, decodificarea acestora şi apoi execuţia propriuzisă.
Extragerea succesivă a instrucţiunilor din memorie se realizează sub controlul unui circuit
denumit numărător de program (en. PC – Program Counter), care va conţine adresa
următoarei instrucţiuni din memorie care urmează a fi extrasă. Datele rezultate din execuţia
programului sau datele utilizate de program pot fi accesate din memorie. De asemenea,
unitatea centrală de prelucrare supervizează şi comandă celelalte componente ale sistemului
prin liniile de control.[8]
Structura internă a unităţii centrale de prelucrare conţine în general următoarele
componente majore:
1. O unitate de control care realizează interpretarea şi secvenţierea
instrucţiunilor, precum şi comanda celorlalte componente ale sistemului.
2. O unitate aritmetică şi logică care execută instrucţiunile din memorie. Ea este
responsabilă de manipularea datelor şi executarea operaţiilor aritmetice şi logice.
3. Regiştri interni (memorii de mare viteză), cu rol în stocarea de informaţii
necesare execuţiei instrucţiunilor (ex. Registrul de instrucţiuni, acumulatorul etc.).
În general, aceşti regiştri interni stochează doar câţiva octeţi de date, care pot fi
operanzi, rezultate, adrese de memorie etc.

11
ARHITECTURA GENERALĂ

1.1.2 Magistralele

Magistralele reprezintă căile de comunicaţie ale sistemului de calcul. Informaţia


transferată între componentele sistemului este transmisă sub formă binară, paralel pe liniile
magistralelor. Se pot identifica trei tipuri de magistrale:

1. Magistrala de date este utilizată la transferul datelor necesare procesării efectuate de


UCP. De exemplu, un sistem de calcul de 8 biţi este un sistem de calcul care dispune
de o magistrală de date cu lăţimea de 8 biţi, fiind capabil să transfere date (numere)
reprezentate pe 8 biţi. Astfel, un asemenea sistem va putea efecuta operaţii între
operanzi reprezentaţi pe 8 biţi, furnizând rezultate reprezentate pe 8 biţi.
Existenţa unei magistrale de 8 biţi nu limitează procesorul doar la utilizarea datelor cu
dimensiunea de 8 biţi, ci indică faptul că procesorul poate accesa un singur octet de
date per ciclu de memorie. De aceea, în raport cu o magistrală cu lăţimea de 16 biţi, o
magistrală de 8 biţi poate transmite doar jumătate din informaţie în unitatea de timp.
Astfel, procesoarele de 16 biţi sunt mai rapide decât cele de 8 biţi ş.a.m.d. Chiar dacă
procesoarele de 16, 32 sau 64 de biţi pot accesa date cu dimensiunea maximă egală cu
laţimea magistralelor lor, ele pot accesa la fel de bine şi locaţii de memorie cu
dimensiunea mai mică (ex. câte un octet).
Totuşi, există şi cazuri în care dimensiunea magistralei externe de date este diferită de
cea a magistralei interne a procesorului. În aceste cazuri se vor realiza mai multe
transferuri din memorie pentru a extrage un operand.

2. Magistrala de adrese este utilizată pentru specificarea adreselor locaţiilor de


memorie accesate. De exemplu, în cazul unei magistrale de adrese de 8 biţi, sistemul
poate accesa 28=256 locaţii de memorie distincte. Cu 16 linii de adresă se pot adresa
65536 locaţii de memorie.

3. Magistrala de control are rolul de a conduce semnalele de control ale UCP care
comandă componentele sistemului. De exemplu, semnalele transmise prin intermediul
magistralei de control pot specifica modul de acces la memorie în vederea realizării
unor operaţii de scriere sau de citire. Practic liniile de scriere şi citire ale magistralei
controlează direcţia datelor de pe magistrala de date. Alte semnale ale magistralei de
control pot include: tactul sistem, liniile de întrerupere, linii de stare etc.

12
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1.1.3 Memoria

Memoriile sunt caracterizate prin conţinutul pe care acestea îl stochează într-un set de
regiştri şi locaţia sau adresa individuală a fiecărui registru. În cazul arhitecturii von Neumann,
atât instrucţiunile cât şi datele se găsesc în acelaşi spaţiu de memorie. Indiferent că este
internă sau externă, memoria reprezintă un spaţiu de stocare şi poate fi accesată cu ajutorul
magistralelor dacă se specifică adresa locaţiei dorite şi tipul operaţiei (scriere sau citire).

1.1.4 Echipamentele de intrare-ieşire

Pentru a putea fi util un sistem de calcul trebuie să fie capabil să interacţioneze cu


mediul înconjurător. Acest lucru se realizează prin intermediul echipmantelor de intrare ieşire.
Comunicarea dintre UCP şi echipamentele periferice se va efectua tot prin intermediul
magistralelor printr-un set de regiştri cu adrese proprii denumite porturi. Porturile pot fi
accesate în mod similar cu memoria, în multe situaţii chiar sunt mapate în spaţiul de adrese al
memoriei. Prin intermediul porturilor pot fi configurate perifericele, pot fi trimise date direct
spre exterior sau pot fi citite date binare din exterior.

1.2 ARHITECTURA HARVARD

Principalul avantaj al arhitecturii von Neumann îl reprezintă simplitatea, totuşi,


existenţa unor magistrale comune pentru toate cele trei componente ale arhitecturii determină
faptul că sistemul de calcul în cauză nu poate realiza la un anumit moment decât un singur
lucru. Astfel, de exemplu, accesul la datele din memorie nu se poate produce în acelaşi timp
cu extragerea unei instrucţiuni din memorie.
În aceste condiţii, în prima decadă după cel de-al doilea război mondial s-a dezvoltat
la universitatea Harvard o nouă arhitectură pentru sistemele de calcul. Această arhitectură,
denumită arhitectura Harvard reprezenta o variaţie a arhitecturii von Neumann fiind
caracterizată de faptul că datele şi instrucţiunile sunt stocate separat în spaţii de memorie
distincte şi sunt accesate prin magistrale diferite. Avantajul acestei arhitecturi este dat de
posibilitatea de a accesa datele şi instrucţiunile în acelaşi timp, având drept consecinţă
creşterea complexităţii arhitecturii interne. Acesta este şi motivul pentru care arhitectura
Harvard a început să fie prezentă mai mult abia odată cu evoluţia circuitelor integrate.

13
ARHITECTURA GENERALĂ

În Fig. 1.2 sunt alăturate, cu scop comparativ, cele două tipuri de arhitecturi de sisteme
de calcul: von Neumann (Fig. 1.2-a) şi Harvard (Fig. 1.2-b). În cea din urmă se evidenţiază
cele două spaţii de memorie distincte împreună cu magistralele asociate. Fiecare memorie
dispune de propria sa magistrală de adrese, respectiv de date, astfel încât nu există nici o
legătură între adresele sau datele celor două spaţii de memorie.[10,19]

Fig. 1.2. Comparaţie între arhitecturile von Neumann şi Harvard

1.3 MICROPROCESOR SAU MICROCONTROLER?

Până acum, în paragrafele anterioare s-a făcut referire doar la câteva sisteme de calcul
care ne trimit cu gândul mai mult spre calculatoarele numerice.
Dar, ce sunt de fapt microprocesoarele, respectiv microcontrolerele?
Pe scurt, microprocesorul implementează funcţiile unităţii centrale de prelucrare.
Pentru a putea fi folosit într-un sistem de calcul, unui microprocesor trebuie să i se adauge
alte componente, cum ar fi memorie, sau componente pentru primirea şi trimiterea datelor.
Pe de altă parte microcontrolerul a fost proiectat să conţină toate cele trei
componente principale (UCP, memorie, echipamente de intrare-ieşire) într-un singur circuit
integrat. Astfel, nu mai sunt necesare alte componente externe deoarece toate perifericele
sunt deja incluse în el. Funcţiile principale ale componentelor însă rămân neschimbate fiind
aceleaşi indiferent de aplicaţia dezvoltată, dar din motive de preţ şi dimensiune
microcontrolerele dispun de un set redus de instrucţiuni şi o capacitate de adresare mai mică.
Astfel, făcând trimitere la cele două tipuri de arhitecturi prezentate anterior în Fig. 1.1
şi Fig. 1.2, microprocesorul reprezintă unitatea centrală de prelucrare, pe când
microcontrolerul reprezintă întreg sistemul de calcul.[4,6]

14
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Pentru a pune în evidenţă structura internă a microcontrolerelor se consideră următorul


exemplu.
Se analizează cazul unui sistem de control al unei sere, bazat pe
microcontroler. Acesta monitorizează parametri precum: umiditatea
solului, temperatura ambiantă sau gradul de iluminare şi comandă diferite
Exemplu
echipamente pentru a stabili condiţiile optime în seră (Fig. 1.3).

Fig. 1.3. Controlul unei sere cu ajutorul unui microsistem

Astfel, umiditatea din sol se măsoară cu ajutorul unui traductor de


umiditate care furnizează un semnal analogic. Dacă acest semnal este sub
o anumită valoare se comandă pornirea sistemului de irigaţie care
presupune deschiderea unei valve pentru apă timp de 5 secunde, apoi
închiderea acesteia timp de 5 secunde şi repetarea acestui ciclu până la
refacerea umidităţii dorite a solului
De asemenea, se monitorizează temperatura din seră cu ajutorul unui
senzor de temperatură şi se comandă deschiderea / închiderea ferestrelor,
precum şi sistemul de încalzire al serei.
În contextul acestei aplicaţii, sistemul de control trebuie să interfaţeze
diverse semnale. Astfel, pentru interfaţarea semnalelor care provin de la
traductorul de umiditate, senzorul de lumină, respectiv cel de temperatură,
vor fi necesare trei intrări analogice, respectiv un convertor analog-digital.
Convertorul analog-digital va discretiza pe rând cele trei semnale
furnizând intern valorile digitale echivalente care vor putea fi comparate
cu referinţele impuse. Pornirea iluminatului, comanda ferestrelor serei, a
sistemului de incălzire sau a sistemului de irigaţie se poate realiza prin
semnale de control discrete, de tip închis/deschis furnizate de la un port de
ieşire digital în baza logicii de control realizate prin programul memorat.
Dacă presupunem că acest sistem necesită şi o interfaţă cu utilizatorul care
să permită fixarea parametrilor de funcţionare ai serei, precum şi afişarea

15
ARHITECTURA GENERALĂ

unor informaţii utile putem completa necesarul de porturi de intrare/ieşire


digitale.

În continuare se pot rezuma resursele necesare pentru implementarea


proiectului:
- o intrare pentru un oscilator extern conectat la un counter/timer
care să furnizeze baza de timp pentru obţinerea celor 5 secunde
cerute. În general, tactul sistem este de cele mai multe ori folosit
de către un timer intern pentru obţinerea temporizărilor;
- trei intrări analogice şi un convertor analog-digital necesare pentru
măsurarea semnalelor care provin de la traductorul de umiditate,
senzorul de temperatură şi cel de lumină;
- o ieşire digitală pentru comanda valvei sistemului de irigat;
- o ieşire digitală pentru comanda motoarelor de acţionare ale
ferestrelor serei;
- o ieşire digitală pentru comanda sistemului de încălzire;
- o ieşire digitală pentru comanda sistemului de iluminat;
- intrări şi ieşiri digitale suplimentare pentru interfaţarea unui panou
de comandă care poate cuprinde butoane şi elemente de afişare
(ex. LED-uri, afişaj LCD);
- UCP pentru realizarea calculelor şi pentru efectuarea operaţiilor de
intrare-ieşire;
- Memorie program (de obicei memorie de tip ROM) pentru
stocarea logicii de control;
- Memorie de date pentru stocarea variabilelor temporare (de obicei
memorie de tip RAM).
Presupunând că programul de control nu ocupă complet toate resursele
microcontrolerului, sistemul ar mai putea transmite date la distanţă prin
intermediul unui sistem de comunicaţie.

În concluzie, pornind de la exemplul anterior se pot identifica o parte din


componentele unui microcontroler. Astfel, structura generală a microcontrolerelor include
unitatea centrală de prelucrare, memorii pentru stocarea datelor şi a programului, ceas intern,
timere, interfeţe de comunicaţie, convertoare analog-digitale, circuite de veghe şi bineînţeles
porturi pentru intrări şi ieşiri digitale şi analogice.[8]

16
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.4. Structura generală a microcontrolerelor

1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR DIN FAMILIA PIC18F

PIC este o familie de microcontrolere produse de compania Microchip Technology.


Denumirea PIC este o prescurtare de la “Programmable Intelligent Computer” (Calculator
Inteligent Programabil). Succesul de care se bucură aceste microcontrolere se datorează în
mare măsură suportului oferit de producător şi al mediului de dezvoltare MPLAB IDE
disponibil gratuit pe site-ul producătorului1. Numărul mare de aplicaţii, posibilitatea de a
dezvolta aplicaţiile în limbaj de asamblare sau în C, dar şi o mulţime de biblioteci bine
documentate permit dezvoltarea rapidă a aplicaţiilor şi fac din aceste microcontrolere un bun
candidat pentru studiul din acest curs.
PIC 18 reprezintă o familie de microcontrolere cu instrucţiuni pe 16 biţi, şi magistrală
internă de date de 8 biţi, memorie program de tip flash, spaţiu de memorie date adresabil
liniar. Familia a fost extinsă cu un număr mare de protocoale de comunicaţii, CAN, Ethernet,
USB, SPI, I2C, Irda, existând în prezent peste 100 de membri ai familiei fiecare cu alte
combinaţii de facilităţi. În continuare se prezintă câteva caracteristici ale acestor
microcontrolere.
Microcontrolerele PIC analizate în acest curs sunt bazate pe arhitectura Harvard.
Pentru a reduce din complexitatea unităţii centrale de prelucrare, aceste microcontrolere
implementează un set redus de instrucţiuni (en. RISC = Reduced Instruction Set Computer).
Spre deosebire de procesoarele RISC, procesoarele cu set complex de instrucţiuni (en. CISC =
Complex Instruction Set Computer) au fost proiectate să implementeze un set de instrucţiuni
cât mai apropiat de cel al limbajelor de nivel înalt, motiv pentru care şi numărul de
instrucţiuni este mai mare. În schimb, procesoarele RISC dispun de un set compact de
instrucţiuni şi moduri mai puţine de adresare, obţinându-se în felul acesta timpi de execuţie ai
instucţiunilor mai mici la aceeaşi frecvenţă de tact.[8]

1
http://www.microchip.com [22]

17
ARHITECTURA GENERALĂ

Unul dintre avantajele importante ale arhitecturii Harvard este dat de faptul că
magistralele celor două tipuri de memorii pot avea dimensiuni diferite. Astfel, magistrala de
date (instrucţiuni) a memoriei program împreună cu memoria program pot fi organizate pe
cuvinte (în cazul analizat este vorba de cuvinte de 16 biţi), iar magistrala şi memoria de date
sunt organizate pe octet. Acest lucru, combinat cu setul redus de instrucţiuni permit
implementarea unor instrucţiuni cu lungime fixă ce pot fi extrase într-un singur pas.

1.4.1 Execuţia instrucţiunilor

Înţelegerea ciclului instrucţiune este esenţială pentru înţelegerea modului de


funcţionare al microcontrolerelor. Un ciclu instrucţiune presupune două faze principale:
- Faza de extragere a instrucţiunilor din memoria program într-un registru intern al
UCP
- Faza de execuţie care include decodificarea instrucţiunii, extragerea operanzilor,
efectuarea operaţiei specificate în codul instrucţiunii şi depunerea rezultatului în
memorie
Durata unui ciclu instrucţiune depinde de frecvenţa de lucru a sistemului, fiind egală
cu 2x4 tacţi sistem. Astfel, tactul sistem este divizat intern la patru fiind generate patru
semnale de tact în cuadratură (Q1, Q2, Q3 şi Q4). Numărătorul program este incrementat în
Q1, iar instrucţiunea este extrasă din memorie în registrul de instrucţiuni în Q4. În
următoarele Q1 până la Q4 instrucţiunea este decodificată (Q1), se citesc datele/operanzii din
memorie (Q2), se procesează datele în funcţie tipul instrucţiunii decodificate (Q3), se scriu
datele/rezultatele în memorie (Q4). Dacă oricare din aceşti paşi lipseşte, datorită tipului de
instrucţiune care se execută, se va insera un pas fără operaţie în locul lui, astfel încât timpul de
execuţie rămâne constant.[8,15]
Analizând cele două faze ale ciclului instrucţiune se constată că în faza de extragere
UCP accesează memoria program, iar în faza de execuţie UCP accesează memoria de date.
Ţinând cont de faptul că microcontrolerul implementează o arhitectura Harvard, iar cele două
memorii pot fi accesate prin magistrale independente, pentru a creşte performanţa sistemului
s-a implementat un pipeline pe două nivele pentru instrucţiuni. Acesta permite suprapunerea
celor două faze ale instrucţiunii. Astfel, în timp ce instucţiunea curentă este extrasă cea
precedentă se execută. În acest fel se reduce la jumătate timpul de execuţie al unei
instrucţiuni, datorită faptului că la fiecare 4 tacţi sistem se terimină de executat o instrucţiune.
Excepţie prezintă instrucţiunile care modifică valoarea numărătorului de program.

18
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.5. Fazele de execuţie ale instrucţiunilor [8,15]

Fig. 1.6. Exemplu de execuţie al unui set de instrucţiuni

Pornind de la modul în care se execută instrucţiunile, UCP poate fi împărţită în două


componente: Unitatea de control şi regiştrii asociaţi, respectiv Unitatea Aritmetică şi Logică.

1.4.2 Unitatea de control

În Fig. 1.7 se prezintă structura simplificată a unităţii de control împreună cu circuitele


componente.

Fig. 1.7. Unitatea de control

Instrucţiunile care constituie programul microcontrolerului sunt stocate în memoria


program sub forma unor cuvinte binare la adrese succesive. Un numărător binar, denumit
numărător de program (en. PC = Program Counter) este utilizat pentru a adresa pe rând

19
ARHITECTURA GENERALĂ

fiecare instrucţiune. Sub controlul acestui numărător, instrucţiunile vor fi extrase pe rând din
memoria program, iar apoi vor fi executate.
Doi regiştri de instrucţiuni, care împreună formează Pipeline-ul, vor stoca codul
instrucţiunilor extrase din memoria program. Cel de sus, Registrul de Instrucţiuni 1 (RI1) va
stoca instrucţiunea n şi o va păstra pe durata următorului ciclu instrucţiune. Această structură
permite ca instrucţiunea n-1, aflată în registrul de la baza pipeline-ului (Registrul de
Instrucţiuni 2 - RI2) să fie executată în timp ce instrucţiunea n este extrasă din memorie şi
stocată în Registrul de instrucţiuni 1 al pipeline-ului. După execuţia instrucţiunii n-1 se
transferă conţinutul din registrul de instrucţiuni 1 al pipeline-ului în registrul de instrucţiuni 2,
urmând ca în timp ce instrucţiunea n+1 este extrasă din memorie şi stocată în vârful pipeline-
ului, instrucţiunea de la bază (instrucţiunea n) să fie executată.
Una din componentele de bază ale UCP, decodificatorul, are rolul de a descifra codul
instrucţiunii stocate în registrul de la baza pipeline-ului şi contribuie la generarea semnalelor
de control interne necesare pentru execuţia instrucţiunii.

1.4.3 Unitatea aritmetică şi logică

Microcontrolerul conţine o unitate aritmetică si logică (Fig. 1.8) pe 8 biţi şi un registru


de lucru de 8 biţi (en. WREG = Work Register) denumit şi acumulator. Unitatea aritmetică este
capabilă să efectueze operaţii precum: adunare, scădere, operaţii logice (ŞI, SAU, XOR etc),
deplasări şi rotiri, înmulţire. În cazul instrucţiunilor cu doi operanzi (ex. adunare) unul din
operanzi se va găsi întotdeauna în registrul de lucru. Celălalt operand poate fi o constantă sau
un registru din memorie. În funcţie de starea unui bit din codul instrucţiunii, denumit bit de
destinaţie d, rezultatul operaţiilor poate fi stocat fie în registrul de lucru (d=0) fie în registrul
din memoria de date din care provenea operandul (d=1). Rezultatul operaţiei de înmulţiere se
va stoca întotdeauna într-o pereche de regiştri speciali PRODH:PRODL.
Introducerea registrului de lucru (WREG) în structura microcontrolerului contribuie la
simplificarea substanţială a modului de reprezentare al instrucţiunilor, lucru care conduce la
creşterea vitezei de execuţie a instrucţiunilor, precum şi la reducerea cantităţii de memorie
necesară pentru stocarea instrucţiunilor. Pentru a exemplifica această idee se poate considera
cazul unei operaţii de adunare în care intervin trei termeni: doi operanzi, respectiv un rezultat.
În lipsa registrului de lucru şi a bitului de destinaţie al rezultatului, codul instrucţiunii de
adunare ar fi trebuit să cuprindă specificarea tuturor celor trei termeni, în loc de unul singur,
lucru care ar fi condus la creşterea numărului de biţi necesari pentru reprezentarea
instrucţiunii.

20
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 1.8. Structura unităţii aritmetice şi logice

Operaţiile aritmetice şi logice pot genera o serie de indicatori ce vor fi stocaţi în


registrul de stare STATUS. Aceşti indicatori sunt: bitul de transport (C - Carry), bitul de
depăşire (OV - Overflow), bitul de semn (N - Negative), rezultat zero (Z - Zero), bitul de
transport auxiliar (DC – Digit Carry). Registrul de stare poate fi şi registru de destinaţie, dar
dacă operaţia executată va conduce la setarea acestor indicatori, se va suprascrie rezultatul. De
exemplu instrucţiunea CLRF STATUS, va şterge toţi biţii registrului STATUS, dar bitul Z va
fi setat la sfârsitul instrucţiunii. În concluzie, registrul de stare va conţine întotdeauna valorile
corecte ale indicatorilor.[8]
Structura registrului de stare STATUS este prezentată mai jos:

bit 7 bit 0
- - - N OV Z DC C
Fig. 1.9. Registrul STATUS

Pornind de la ideea introductivă conform căreia microcontrolerele


reprezintă încapsularea unor sisteme de calcul, în acest curs s-au prezentat

Concluzii principalele tipuri de arhitecturi existente, s-a evidenţiat structura acestora,


rolul elementelor componente, dar şi principalele avantaje şi dezavantaje
care le caracterizează. Studiul unei aplicaţii practice a condus la
identificarea necesarului de elemente componente în structua generală a
microcontrolerelor, iar familia de microcontrolere PIC18F a furnizat
suportul pentru aprofundarea conceptelor referitoare la modul de execuţie
al instrucţiunilor, respectiv la structura internă a UCP.

21
ARHITECTURA GENERALĂ

1. Arhitectura microcontrolerului permite extragerea unei instrucţiuni din


memorie simultan cu execuţia altei instrucţiuni. Discutaţi elementele
care permit realizarea acestor lucruri în paralel.
Întrebări de
2. Care este diferenţa între arhitectura von Neumann şi arhitectura
autoevaluare
Harvard a sistemelor de calcul?
3. Care este diferenţa între un microcontroler şi un microcprocesor?
4. Explicaţi rolul registrului de lucru (WREG) în arhitectura
microcontrolerului.
5. Explicaţi rolul registrului status (STATUS) în arhitectura
microcontrolerului.
6. Prezentaţi un avantaj şi un dezavantaj pentru fiecare din cele două
tipuri de arhitecturi prezentate.
7. Care sunt elementele componente ale unui sistem de calcul?
8. Care sunt fazele unei instrucţiuni?
9. Care este rolul numărătorului de program?
10. Cum este implementat pipeline-ul la nivelul unităţii de control?

Adresă
Colecţie de biţi utilizaţi pentru a identifica locaţiile de memorie
Termeni Ciclu instrucţiune
esenţiali Procesul prin care se extrage o instrucţiune din memoria program şi se
execută
CISC
Complex Instruction Set Computer
Dată
Conţinutul unei locaţii de memorie
Instrucţiuni
Comenzi pe care le execută UCP
Magistrală
Colecţie de fire prin care informaţia se transmite paralel între componentele
unui sistem de calcul
Memorie
Spaţiu de stocare
Memorie de date
Spaţiu de stocare temporar (RAM) pentru datele cu care lucrează programul

22
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Memorie program
Spaţiu de stocare pentru program
Microcontroler
Sistem de calcul încapsulat într-un singur circuit integrat
Microprocesor
Parte componentă a unui sistem de calcul, UCP
Numărător de program
Numărător binar utilizat pentru adresarea instrucţiunilor. Conţine adresa
instrucţiunii care urmează a fi executată
PIC
Programmable Intelligent Computer
Pipeline
Tehnică utilizată pentru a creşte numărul de instrucţiuni care pot fi
executate în unitatea de timp. Pipeline-ul nu reduce timpul necesar
execuţiei unei instrucţiuni, ci creşte numărul de instrucţiuni care pot fi
procesate simultan
Port
Calea de legătură a sistemului de calcul cu lumea exterioară prin care acesta
poate să trimită şi să primească date
Registru
Spaţiu de stocare
Registru de instrucţiuni
Spaţiu de stocare temporar pentru o instrucţiune extrasă din memorie
RISC
Reduced Instruction Set Computer
STATUS
Registru care indică starea operaţiilor aritmetice şi logice executate de
unitatea aritmetică şi logică
UAL
Unitate aritmetică şi logică
UCP
Unitate centrală de prelucrare
WREG
Registru de lucru / acumulator. În general conţine unul din operanzii
instrucţiunilor

23
SETUL DE INSTRUCŢIUNI

2. SETUL DE INSTRUCŢIUNI

Introducere
Obiective
2.1 FORMATUL INSTRUCŢIUNILOR
Cuprins
2.1.1 Instrucţiuni pe octet
2.1.2 Instrucţiuni pe bit
2.1.3 Instrucţiuni cu constante
2.1.4 Instrucţiuni de control
2.2 CLASIFICAREA INSTRUCŢIUNILOR ÎN FUNCŢIE DE
OPERAŢIILE REALIZATE
2.2.1 Instrucţiuni matematice pe octet
2.2.2 Instrucţiuni logice pe octet
2.2.3 Instrucţiuni matematice şi logice cu constante
2.2.4 Instrucţiuni logice pe bit
2.2.5 Instrucţiuni de comparaţie pe bit
2.2.6 Instrucţiuni de comparaţie pe octet
2.2.7 Instrucţiuni de mutare
2.2.8 Instrucţiuni de control
2.2.9 Alte instrucţiuni
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

24
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Un program constă dintr-o serie de instrucţiuni scrise într-o anumită


ordine în vederea realizării unor sarcini. Instrucţiunile disponibile pentru
acest lucru sunt în strânsă legătură cu arhitectura microcontrolerului, iar
Introducere
un dezvoltator de microsisteme încorporate trebuie să fie foarte bine
familiarizat atât cu arhitectura software cât şi cu cea hardware, mai ales
dacă va scrie programele sale în limbaj de asamblare.
Acest capitol cuprinde prezentarea instrucţiunilor disponible pentru
microcontrolerul PIC18F4455, precum şi modul în care acestea sunt
reprezentate în memoria program.

După parcurgerea acestui capitol cursantul va trebui:


- să cunoască instrucţiunile disponibile pentru microcontrolerul
PIC18F4455;
Obiective - să cunoască modul în care sunt codificate instrucţiunile în
memoria program;
- să cunoască rolul pe care îl au parametrii instrucţiunilor;
- să utilizeze în mod adecvat instrucţiunile pentru implementarea
operaţiilor necesare diferitelor programe.

2.1 FORMATUL INSTRUCŢIUNILOR

Scrierea unui program se poate asemăna, într-o oarecare măsură, cu ridicarea unei
case. Având la dispoziţie o serie de materiale de costrucţii, constructorul le asamblează pe
acestea într-o anumită ordine pentru a obţine produsul finit. Etapele necesare construcţiei:
săparea fundaţiei, zidirea, tencuirea etc. pot fi asociate instrucţiunilor implementate de UCP,
iar materialele şi echipamentele de construcţii necesare: cărămizi, mortar, ciment etc.
reprezintă datele cu care lucrează instrucţiunile.
În conformitate cu arhitectura de tip RISC pe care este bazat, microcontrolerul
PIC18F4455 implementeză un set redus de instrucţiuni standard, format din 75 de
instrucţiuni, care este completat cu 8 instrucţiuni opţionale care formează setul extins.[15]
Din setul standard de instrucţiuni, majoritatea (71) au lungimea de un cuvânt (16 biţi),
dar există şi 4 instrucţiuni având lungimea de două cuvinte (32 biţi). Pentru reprezentarea
acestor instrucţiuni în memoria program sunt necesari 16, respectiv 32 de biţi, adică 2,
respectiv 4 locaţii de memorie consecutive. Instrucţiunile lungi au fost introduse pentru a

25
SETUL DE INSTRUCŢIUNI

putea stoca toată informaţia necesară execuţiei operaţiilor pe care le implementează (ex.
instrucţiunea MOVFF utilizează ca operanzi două adrese absolute din memorie reprezentate
fiecare pe câte 12 biţi).
În esenţă majoritatea instrucţiunilor utilizează date stocate în memorie. În aceste
condiţii, o instrucţiune trebuie să aibă posibilitatea de a informa UCP despre tipul operaţiei
pe care o implementează, respectiv despre locul unde se găsesc datele cu care această
instrucţiune operează. Astfel, o instrucţiune va codifica binar următoarele informaţii:
- codul operaţiei
- unul sau mai mulţi operanzi (adresă, constantă, bit de destinaţie, bit de acces)
Există şi câteva excepţii de la această regulă cum ar fi, de exemplu, instrucţiunea NOP
(No OPeration), care consumă timpul procesorului fără a realiza însă o operaţie.
Pentru acest microcontroler au fost definite mai multe formate de instrucţiuni.
Lungimea câmpului corespunzător codului operaţiei variază în funcţie de tipul instrucţiunii,
permiţând astfel o utilizare mai eficientă a lungimii instrucţiunii.
Setul de instrucţiuni al microcontrolerului PIC18F4455 poate fi împărţit în patru
categorii de bază:
- Instrucţiuni pe octet
- Instrucţiuni pe bit
- Instrucţiuni cu constante (literali)
- Instrucţiuni de control

2.1.1 Instrucţiuni pe octet

Majoritatea instrucţiunilor orientate pe octet au trei operanzi:


1. Registrul (specificat prin operandul f)
2. Destinaţia rezultatului (specificată prin operandul d)
3. Zona de memorie accesată (specificată prin operandul a)
În instrucţiunile pe octet, operandul f specifică registrul care urmează a fi folosit de
instrucţiune. Registrul f poate fi specificat fie prin numele său simbolic (dacă are) fie prin
adresa sa de 8 biţi.
Operandul d, denumit şi bit de destinaţie al rezultatului, specifică locul în care va fi
plasat rezultatul operaţiei realizate de instrucţiune. Dacă d=0 (d=W) rezultatul operaţiei va
fi plasat în registrul de lucru WREG. Dacă d=1 (d=F) rezultatul operaţiei va înlocui
conţinutul registrului f specificat în instrucţiune.

26
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Operandul a, denumit şi bit de acces, specifică modul de acces la registrul f. Dacă


a=0 (a=ACCESS) atunci registrul f se găseşte în Access Bank. Dacă a=1 (a=BANKED)
atunci registrul f se găseşte în Bank-uri, iar pentru a-l accesa se utilizează registrul BSR.
Asupra modului de acces se va reveni în capitolul 3.
În Fig. 2.1 se prezintă formatul instrucţiunilor pe octet. Acest format reprezintă modul
în care acest tip de instrucţiuni sunt codificate binar în memoria program a
microcontrolerului. Se poate observa că pentru codul instrucţiunii sunt alocaţi 6 biţi (biţii
<15:10>), pentru adresa registrului f sunt alocaţi 8 biţi (biţii <7:0>), rămânând 2 biţi necesari
pentru operanzii d (bitul 9), respectiv a (bitul 8).

15 10 9 8 7 0
Cod operaţie d a f (adresa registrului)
Fig. 2.1. Formatul general al instrucţiunilor orientate pe octet

În program, aceste instrucţiuni vor fi scrise sub forma prezentată în Tabelul 2.1. Tot în
acest tabel se pune în evidenţă şi cazul unor instrucţiuni care operează cu octeţi, dar care
utilizează doar două argumente

Tabel 2.1. Formatul general al instrucţiunilor orientate pe octet


Format instrucţiuni orientate pe octet Exemplu de utilizare
cod_operaţie f,d,a ADDWF REG1, W, BANKED
cod_operaţie f,a CLRF 0x01, ACCESS

f=adresa pe 8 biţi a registrului


d=0 (d=W) destinaţia rezultatului este registrul de lucru WREG
d=1 (d=F) destinaţia rezultatului este registrul f
a=0 (a=ACCESS) registrul f se găseşte în Access Bank
a=1 (a=BANKED) registrul f se găseşte în Bank-uri

Excepţie: MOVFF fs,fd MOVFF REG_s, REG_d


fs=adresa pe 12 biţi a registrului sursă
fd=adresa pe 12 biţi a registrului destinaţie

Excepţie de la modul de reprezentare din Fig. 2.1 face instrucţiunea de mutare a unui
octet de la o adresă sursă la o adresă destinaţie (MOVFF). Această instrucţiune face parte din
categoria instrucţiunilor lungi şi necesită 32 de biţi pentru reprezentare. Formatul general al
acestei instrucţiuni se prezintă în Fig. 2.2.

15 12 11 0
Cod operaţie fs (adresa registrului sursă)
15 12 11 0
1 1 1 1 fd (adresa registrului destinaţie)
Fig. 2.2. Formatul general al instrucţiunilor de mutare octet MOVFF

27
SETUL DE INSTRUCŢIUNI

În cazul instrucţiunii MOVFF, prezentată mai sus, câmpurile alocate adreselor sursă şi
destinaţie au dimensiunea de 12 biţi. Astfel, această instrucţiune permite utilizarea adreselor
absoulute în realizarea operaţiei de mutare a unui octet între cele două locaţii de memorie.
Pentru codul operaţiei sunt rezervaţi 4 biţi (biţii <15:12> din cuvântul superior), iar cei 4 biţi
rămaşi neutilizaţi sunt întotdeauna 1 (biţii <15:12> din cuvântul inferior).

2.1.2 Instrucţiuni pe bit

Toate instrucţiunile orientate pe bit au trei operanzi:


1. Registrul (specificat prin operandul f)
2. Bitul din registru (specificat prin operandul b)
3. Zona de memorie accesată (specificată prin operandul a)
În aceste instrucţiuni, operandul b, format din trei biţi, are rolul de a specifica poziţia
bitului în cadrul registrului f care este afectat de operaţia realizată de instrucţiune. Operandul
f conţine adresa de opt biţi a registrului din memorie implicat în instrucţiune, iar operandul a,
zona de memorie în care se găseşte registrul accesat.
În Fig 2.3 se prezintă modul de reprezentare al instrucţiunilor pe bit în memoria
program, iar în Tabelul 2.2 se prezintă formatul general al acestor instrucţiuni şi un exemplu
de utilizare.

15 12 11 9 8 7 0
Cod operaţie b (poziţie bit) a f (adresa registrului)
Fig. 2.3. Formatul general al instrucţiunilor orientate pe bit

Tabel 2.2. Formatul general al instrucţiunilor orientate pe bit


Format instrucţiuni orientate pe bit Exemplu de utilizare
cod_operaţie f,b,a BSF REG, 4, ACCESS

f=adresa pe 8 biţi a registrului


b=poziţia bitului (0:7) în cadrul registrului f
a=0 (a=ACCESS) registrul f se găseşte în Access Bank
a=1 (a=BANKED) registrul f se găseşte în Bank-uri

2.1.3 Instrucţiuni cu constante (literali)

Instrucţiunile cu constante utilizează un singur operand k. Acesta are rezervaţi cei opt
biţi inferiori ai instrucţiunii şi reprezintă valoarea unei constante, denumită şi literal. Modul
de reprezentare al acestor instrucţiuni în memoria program se prezintă în Fig. 2.4.

28
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

15 8 7 0
Cod operaţie k (constantă)
Fig. 2.4. Formatul general al instrucţiunilor orientate pe bit

Excepţia de la acest mod de reprezentare o constituie instrucţiunea LFSR, care este o


instrucţiune lungă şi care va încărca o constantă de 12 biţi în unul din cei trei regiştrii speciali
FSR.
Tabelul 2.3 pune în evidenţă modul de utilizare al acestor instrucţiuni în program.

Tabel 2.3. Formatul general al instrucţiunilor cu constante


Format instrucţiuni cu constante Exemplu de utilizare
cod_operaţie k MOVLW d’23’

k=valoarea efectivă pe 8 biţi

Excepţie: LFSR f,k LFSR FSR0, h’100’


f=registrul FSR utilizat
k=adresa pe 12 biţi

2.1.4 Instrucţiuni de control

În funcţie de tipul operaţiei implementate, instrucţiunile de control pot utiliza


următorii operanzi:
- o adresă din memoria program / etichetă (specificată prin operandul n)
- utilizarea stivei rapide în cazul instrucţiunilor CALL, RETURN şi RETFIE (specificată
prin operandul s)
- fără operand
Aceste instrucţiuni au rolul de a controla execuţia programului prin implementarea de
bucle, salturi, apeluri de subrutina etc. Operandul n, specifică o adresa de salt în memoria
program. În urma apelului acestor instrucţiuni se va modifica valoarea stocată în numărătorul
de program, lucru care va conduce la realizarea efectivă a saltului. Această adresă de salt
corespunde etichetelor care se introduc în codul sursă pentru a marca adresa de început a
anumitor secţiuni de cod.
În funcţie de tipul operaţiei realizate, pentru instrucţiunile de control sunt definite mai
multe moduri de reprezentare, prezentate succint în Tabelul 2.4, dar asupra cărora nu se va
insista în acest capitol. Totuşi, cu scop informativ, în Fig. 2.5 se prezintă formatul instrucţiunii
de control GOTO care permite realizarea de salturi în întreg spaţiul de adresare al memoriei
program.

29
SETUL DE INSTRUCŢIUNI

15 8 7 0
Cod operaţie n<7:0> (adresă din memoria program)
15 12 11 0
1 1 1 1 n<19:8> (adresă din memoria program)
Fig. 2.5. Formatul general al unei instrucţiuni de control

Tabel 2.4. Formatul general al instrucţiunilor de control


Format instrucţiuni de control Exemplu de utilizare
cod_operaţie n GOTO main_loop
cod_operaţie n,{s} CALL rutina
cod_operaţie s RETURN FAST
cod_operaţie NOP

n=etichetă (adresă din memoria program)


s= utilizare stivă rapidă

Excepţie: RETLW k RETLW 0x15


k=constantă pe 8 biţi

2.2 CLASIFICAREA INSTRUCŢIUNILOR ÎN FUNCŢIE DE OPERAŢIILE


REALIZATE

Pentru o mai bună înţelegere şi pentru identificarea facilă a instrucţiunilor necesare


implementării diferitelor programe, acest paragraf conţine o clasificare a instrucţiunilor
disponibile în funcţie de operaţiile realizate.

2.2.1 Instrucţiuni matematice pe octet

În acestă categorie s-au considerat instrucţiunile care realizează operaţii matematice


elementare asupra datelor cu dimensiunea de opt biţi. Operaţiile realizate sunt: adunarea,
scăderea, incrementarea, decremenetarea şi înmulţirea.

Se analizează cazul instrucţiunii cu forma generală:


ADDWF f, d, a
Această instrucţiune adună conţinutul registrului de lucru WREG cu
Exemplu
conţinutul registrului a cărui adresă este specificată prin parametrul f. Dacă
bitul de destinaţie al rezultatului va fi d=0 (d=W), rezultatul obţinut în
urma operaţiei va fi depus în registrul de lucru WREG. Dacă bitul de
destinaţie al rezultatului va fi d=1 (d=F), rezultatul obţinut în urma
operaţiei va fi stocat în registrul f, înlocuind astfel operandul care se găsea

30
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

acolo. Cele două situaţii posibile sunt puse în evidenţă în Fig. 2.6.
Parametrul a intervine în modul de formare al adresei f. Asupra acestui
parametru se va reveni în capitolul 3. În exemplele care vor urma acest
parametru se consideră ca având valoarea a=0.

Fig. 2.6. Selectarea destinaţiei rezultatului pentru instrucţiunea ADDWF

În continuare se va analiza exemplul prezentat în Fig. 2.6. Se consideră că


înaintea execuţiei instrucţiunii în registrul de lucru WREG se găseşte
valoarea b’00101001’=h’29’=d’41’, iar în registrul de la adresa
0x02C se găseşte valoarea b’01100111’=h’67’=d’103’.

În cazul a., în urma realizării operaţiei:


ADDWF 0x2C, W, 0
rezultatul obţinut b’10010000’=h’90’=d’144’ va fi stocat în
registrul de lucru WREG, înlocuind operandul 1.

31
SETUL DE INSTRUCŢIUNI

În cazul b.:
ADDWF 0x2C, F, 0
se produce acelaşi rezultat, dar acesta va fi stocat în memorie la adresa
0x02C, înlocuind operandul 2.
După cum se poate vedea şi din figură, operaţiile realizate pot influenţa şi
starea biţilor indicatori din registrul STATUS. Bineînţeles, pentru valorile
alese ale operanzilor, registrul STATUS nu este influenţat în urma execuţiei
instrucţiunii.

În aceeaşi categorie a instrucţiunilor matematice pe octet se regăsesc şi instrucţiunile


din Tabelul 2.5.
Tabel 2.5. Instrucţiuni matematice pe octet
Instrucţiuni Descriere Cicluri instr.
ADDWF f,d,a Adună WREG cu f 1
ADDWFC f,d,a Adună WREG cu f şi cu bitul de transport 1
SUBWF f,d,a Scade WREG din f 1
SUBWFB f,d,a Scade f din WREG cu bitul de împrunut 1
SUBFWB f,d,a Scade WREG din f cu bitul de împrumut 1
INCF f,d,a Incrementează f 1
DECF f,d,a Decrementează f 1
MULWF f,a Înmulţeşte f cu WREG1 1
NEGF f,a Negare f 1

2.2.2 Instrucţiuni logice pe octet

În acestă categorie s-au considerat instrucţiunile care realizează operaţii logice asupra
datelor cu dimensiunea de opt biţi. Printre operaţiile realizate se pot aminti: ŞI logic, SAU
logic, SAU-EXCLUSIV, Complement, rotire de biţi etc.
Tabelul 2.6 cuprinde instrucţiunile care se încadrează în categoria instrucţiunilor
logice pe octet.
O analiză comparativă între instrucţiunile din această categorie şi cele din categoria
instrucţiunilor matematice pe octet pune în evidenţă faptul că parametrii acestor instrucţiuni
(f,d,a) sunt aceeaşi şi îndeplinesc acelaşi rol. Se pot identifica totuşi câteva instrucţiuni, a
căror înţelegere poate ridica mici probleme. Este vorba despre instrucţiunile de rotire, la
stânga sau la dreapta, cu sau fără bit de transport (en. Carry). Aceste instrucţiuni vor fi
analizate în exemplul următor.

1
rezultatul acestei operaţii se va regăsi în regiştrii PRODH:PRODL

32
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Tabel 2.6. Instrucţiuni logice pe octet


Instrucţiuni Descriere Cicluri instr.
ANDWF f,d,a ŞI logic între WREG şi f 1
IORWF f,d,a SAU logic între WREG şi f 1
XORWF f,d,a SAU-EXCLUSIV între WREG şi f 1
COMF f,d,a Complement f 1
CLRF f,a Resetare biţi din registrul f 1
SETF f,a Setare biţi din registrul f 1
SWAPF f,d,a Interschimbare semiocteţi din registrul f 1
RLCF f,d,a Rotire f la stânga cu bit de transport 1
RLNCF f,d,a Rotire f la stânga fără bit de transport 1
RRCF f,d,a Rotire f la dreapta cu bit de transport 1
RRNCF f,d,a Rotire f la dreapta fără bit de transport 1

Se analizează cazul instrucţiunii cu forma generală:


RLCF f, d, a
Această instrucţiune realizează rotirea spre stânga cu bit de transport a
Exemplu
conţinutului de la adresa specificată prin parametrul f. Rezultatul obţinut
va fi stocat în registrul f sau în registrul de lucru WREG, în funcţie de
starea bitului de destinaţie al rezultatului d.
Rotirea spre stânga cu bit de transport este evidenţiată în Fig. 2.7. Bitul de
transport (en. Carry) este un bit al registrului STATUS.

Fig. 2.7. Rotirea spre stânga cu bit de transport RLCF

Modul de utilizare al instrucţiunii de rotire cu bit de transport este


evidenţiat în continuare:

RLCF REG, W, 0

Înaintea instrucţiunii:
REG = 11100110
C = 0
După instrucţiune:
REG = 11100110
WREG = 11001100
C = 1

33
SETUL DE INSTRUCŢIUNI

Se analizează cazul instrucţiunii cu forma generală:


RLNCF f, d, a
Această instrucţiune realizează rotirea spre stânga fără bit de transport a
Exemplu
conţinutului de la adresa specificată prin parametrul f. Rezultatul obţinut
va fi stocat în registrul f sau în registrul de lucru WREG, în funcţie de
starea bitului de destinaţie al rezultatului d.
Rotirea spre stânga fără bit de transport este evidenţiată în Fig. 2.8.

Fig. 2.8. Rotirea spre stânga cu bit de transport RLNCF

Modul de utilizare al instrucţiunii de rotire fără bit de transport este


evidenţiat în continuare:

RLCF REG, W, 0

Înaintea instrucţiunii:
REG = 11100110
C = 0
După instrucţiune:
REG = 11100110
WREG = 11001101
C = 1

În cele două exemple prezentate anterior, parametrul f al instrucţiunii este specificat


prin intermediul unei nume simbolic care înlocuieşte adresa fizică a registrului. Acest nume
simbolic trebuie declarat anterior utilizării. Mai multe detalii despre numele simbolice vor fi
prezentate în capitolul 4.
Rotirile spre dreapta, implementate de instrucţiunile RRCF şi RRNCF, se realizează în
mod asemănător.

34
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

2.2.3 Instrucţiuni matematice şi logice cu constante

Aceste instrucţiuni au fost grupate într-o singură categorie deoarece respectă acelaşi
format şi acelaşi principiu de funcţionare, după cum se poate vedea din Tabelul 2.7, dar şi în
exemplul considerat.

Tabel 2.7. Instrucţiuni matematice şi logice cu constante


Instrucţiuni Descriere Cicluri instr.
ADDLW k Adună WREG cu literal 1
SUBLW k Scade WREG din literal 1
MULLW k Înmulţeşte WREG cu literal 1
ANDLW k ŞI logic între WREG şi literal 1
IORLW k SAU logic între WREG şi literal 1
XORLW k SAU-EXCLUSIV între WREG şi literal 1

Cu excepţia instrucţiunii de înmulţire MULLW, toate instrucţiunile din această


categorie vor avea unul dintre operanzi în registrul de lucru WREG, cel de-al doilea operand va
fi constanta k, iar rezultatul obţinut în urma operaţiei va fi stocat în registrul de lucru.
Instrucţiunea de înmulţire cu o constantă MULLW, la fel ca şi cealaltă instrucţiune de
înmulţire MULWF, amintită în categoria instrucţiunilor matematice pe octet, va depune
întotdeauna rezultatul în doi regiştri speciali PRODH:PRODL. Acest lucru se datorează
faptului că înmulţirea a două valori reprezentate pe opt biţi poate conduce la un rezultat cu o
dimensiune mai mare de opt biţi, care nu poate fi stocat nici în registrul de lucru WREG, nici în
registrul f. (10 x 30 = 300. 300 este o valoare care se reprezintă pe 9 biţi)

Se analizează cazul instrucţiunii cu forma generală:


ANDLW k
Această instrucţiune realizează operaţia logică ŞI între conţinutul registrul
Exemplu
de lucru şi constanta de 8 biţi k. Rezultatul obţinut va fi stocat în registrul
de lucru WREG.

Modul de utilizare al acestei instrucţiuni este evidenţiat în continuare:

ANDLW 0x0F

Înaintea instrucţiunii:
WREG = 11100110
După instrucţiune:
WREG = 00000110

35
SETUL DE INSTRUCŢIUNI

2.2.4 Instrucţiuni logice pe bit

În această categorie au fost grupate instrucţiunile care manipulează starea unui singur
bit prin realizarea unor operaţii de setare, resetare sau negare a stării (en. toggle). De altfel,
această categorie cuprinde doar trei instrucţiuni cu format asemănător care implementează
cele trei operaţii amintite anterior. Tabelul 2.8 centralizează aceste instrucţiuni.

Tabel 2.8. Instrucţiuni logice pe bit


Instrucţiuni Descriere Cicluri instr.
BCF f,b,a Resetează bitul b din registrul f 1
BSF f,b,a Setează bitul b din registrul f 1
BTG f,b,a Neagă starea bitului b din registrul f 1

Pentru a exemplifica modul de utilizare al acestor instrucţiuni se consideră următorul


exemplu.

Se analizează cazul instrucţiunii cu forma generală:


BCF f, b, a
Această instrucţiune realizează operaţia de resetare, sau punere pe 0 logic,
Exemplu
a bitului de pe poziţia b din registrul a cărui adresă se sprecifică prin
parametrul f al instrucţiunii. Rezultatul obţinut în urma acestei operaţii se
va regăsi întotdeauna în registrul f.
Având în vedere că regiştrii microcontrolerului sunt de 8 biţi, parametrul
b al acestor instrucţiuni va avea întotdeauna o valoare cuprinsă între 0 şi
7, unde 0 identifică bitul cel mai puţin semnificativ, iar 7 identifică bitul
cel mai semnificativ al unui octet.

Modul de utilizare al acestei instrucţiuni este evidenţiat în continuare:

BCF REG, 2, 0

Înaintea instrucţiunii:
REG = 11100110
După instrucţiune:
REG = 11100010

36
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

2.2.5 Instrucţiuni de comparaţie pe bit

O categorie aparte de instrucţiuni sunt instrucţiunile de comparaţie, deoarece acestea


permit implementarea ramificaţiilor de tip if în programele realizate în limbaj de asamblare.
Instrucţiunile de comparaţie pe bit sunt doar două la număr şi permit testarea stării unui
anumit bit dintr-un registru. În Tabelul 2.9 sunt menţionate cele două instrucţiuni.

Tabel 2.9. Instrucţiuni de comparaţie pe bit


Instrucţiuni Descriere Cicluri instr.
BTFSC f,b,a Testează bitul b din reg. f, salt dacă este 0 1 (2 sau 3)
BTFSS f,b,a Testează bitul b din reg. f, salt dacă este 1 1 (2 sau 3)

Se analizează cazul instrucţiunii cu forma generală:


BTFSC f, b, a
Această instrucţiune compară dacă bitul de pe poziţia b din cadrul
Exemplu
registrului f este 0. Dacă bitul este 0 se face salt peste instrucţiunea
următoare. Fig. 2.9 curpinde o diagramă care prezintă principiul de
funcţionare al acestei instrucţiuni.

Fig. 2.9. Principiul de funcţionare al instrucţiunii BTFSC

În cazul prezentat în Fig. 2.9, având în vedere că în registrul cu numele


simbolic REG se găseşte valoarea 01011001, care are bitul 3 setat,
instrucţiunea care se va executa dupa BTFSC va fi instrucţiunea 1.

37
SETUL DE INSTRUCŢIUNI

2.2.6 Instrucţiuni de comparaţie pe octet

Instrucţiunile de comparaţie pe octet pot fi grupate în două sub-categorii: instrucţiuni


cu doi parametri, care realizează doar o comparaţie urmată sau nu de un salt, respectiv
instrucţiuni cu trei parametri care mai realizează în plus o operaţie de incrementare sau
decrementare. În funcţie de specificul lor aceste instrucţiuni vor fi utilizate fie la
implementarea unor ramificaţii de tip if, fie la implementarea unor bucle iterative de tip
for.
Pentru a evidenţia principiul de funcţionare al instrucţiunilor din cele două sub-
categorii se va considera câte un exemplu semnificativ pentru ambele formate de instrucţiuni.

Se analizează cazul instrucţiunii cu forma generală:


CPFSEQ f, a
Această instrucţiune compară conţinutul registrului f cu cel al registrului
Exemplu
de lucru WREG. Dacă cele două sunt identice se face salt peste
instrucţiunea următoare. În Fig. 2.10 se prezintă principiul de funcţionare
al acestei instrucţiuni.

Fig. 2.10. Principiul de funcţionare al instrucţiunii CPFSEQ

Se analizează cazul instrucţiunii cu forma generală:


DECFSZ f, d, a
Această instrucţiune realizează o decrementare a valorii stocate în
Exemplu
registrul f, iar dacă rezultatul obţinut în urma decrementării este 0 se
excută un salt peste instrucţiunea următoare. Prezenţa parametrului d în
codul instrucţiunii indică faptul că rezultatul decrementării poate fi stocat
fie în registrul de lucru WREG, fie la adresa specificată prin f.

38
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

În Fig. 2.11 se prezintă principiul de funcţionare al acestei instrucţiuni.

Fig. 2.11. Principiul de funcţionare al instrucţiunii DECFSZ

Instrucţiunea DECFSZ, prezentată anterior poate fi utilizată cu uşurinţă pentru


realizarea unor bucle de tip for. Exemplul următor consideră o secţiune de cod care
realizează acest lucru.

Se consideră cazul implementării unei bucle de tip for care permite


execuţia unei instrucţiuni oarecare de o sută de ori.
Se porneşte de la premisa conform căreia registrul REG, utilizat pe post de
Exemplu
iterator, este în prealabil iniţializat cu valoarea 100. În aceste condiţii
secvenţa următoare de cod permite execuţia instrucţiunii CLRF de o sută
de ori.

Bucla_for
CLRF 0x00, 0
DECFSZ REG, F, 0
GOTO Bucla_for

Instrucţiunile de comparaţie pe octet sunt centralizate în Tabelul 2.10.

39
SETUL DE INSTRUCŢIUNI

Tabel 2.10. Instrucţiuni de comparaţie pe octet


Instrucţiuni Descriere Cicluri instr.
CPFSEQ f,a Compară f cu WREG, salt dacă f=WREG 1 (2 sau 3)
CPFSGT f,a Compară f cu WREG, salt dacă f>WREG 1 (2 sau 3)
CPFSLT f,a Compară f cu WREG, salt dacă f<WREG 1 (2 sau 3)
TSTFSZ f,a Testează f, salt dacă f=0 1 (2 sau 3)
INCFSZ f,d,a Incrementează f, salt dacă rezultatul = 0 1 (2 sau 3)
INCFSNZ f,d,a Incrementează f, salt dacă rezultatul ≠ 0 1 (2 sau 3)
DECFSZ f,d,a Decrementează f, salt dacă rezultatul = 0 1 (2 sau 3)
DECFSNZ f,d,a Decrementează f, salt dacă rezultatul ≠ 0 1 (2 sau 3)

2.2.7 Instrucţiuni de mutare

Instrucţiunile din această categorie permit mutarea datelor dintr-o locaţie în alta a
memoriei de date sau permit încărcarea unor constante în anumiţi regiştri. Aceste instrucţiuni
sunt prezentate în Tabelul 2.11.

Tabel 2.11. Instrucţiuni de mutare


Instrucţiuni Descriere Cicluri instr.
MOVWF f,a Mută WREG în f 1
MOVF f,d,a Mută f 1
MOVFF fs,fd Mută fs(sursa) în fd(destinaţie) 2
MOVLW k Mută literal în WREG 1
MOVLB k Mută literal (4 biţi) în BSR 1
LFSR f,k Mută literal (12 biţi) în FSR(f) 2

Se consideră cazul iniţializării locaţiei de memorie de la adresa 0x2A cu


valoarea 0x55. Secvenţa de cod următoare realizează acest lucru.

Exemplu
MOVLW 0x55 ; 0x55Æ WREG
MOVWF 0x2A, 0 ; WREGÆ[F02A]

După cum se poate observa locaţia de memorie considerată nu se poate


iniţializa direct cu valoarea dorită. Acest lucru se realizează prin
intermediul registrului de lucru.

40
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

2.2.8 Instrucţiuni de control

Majoritatea instrucţiunilor din această categorie controlează modul de execuţie al


programului ca urmare a modificării valorii numărătorului de program, prin realizarea de
salturi condiţionate sau necondiţionate, apeluri de subrutină, revenire din subrutină etc.
Tabelul 2.12 cuprinde lista acestor instrucţiuni.

Tabel 2.11. Instrucţiuni de control


Instrucţiuni Descriere Cicluri instr.
BC n Salt dacă bitul de transport (carry) este 1 1 (2)
BN n Salt dacă bitul negativ este 1 1 (2)
BOV n Salt dacă bitul de depăşire (overflow) este 1 1 (2)
BZ n Salt dacă bitul zero este 1 1 (2)
BNC n Salt dacă bitul de transport (carry) este 0 1 (2)
BNN n Salt dacă bitul negativ este 0 1 (2)
BNOV n Salt dacă bitul de depăşire (overflow) este 0 1 (2)
BNZ n Salt dacă bitul zero este 0 1 (2)
BRA n Salt necondiţionat 2
GOTO n Salt la adresa / etichetă 2
PUSH Pune în stivă (Salvează PC în stivă) 1
POP Scoate din stivă (Reface PC) 1
CALL n,s Apel de subrutină 2
RETURN s Revenire din subrutină 2
RETLW k Revenire din subrutină cu literal în WREG 2
RETFIE s Revenire din rutina de tratare a întreruperii 2
NOP Nici o operaţie 1

Instrucţiunile de salt condiţionat (BC, BN, BNC, BNN, BNOV, BNZ, BOV,
BZ) realizează saltul la o instrucţiune destinaţie marcată printr-o etichetă dacă rezultatul
operaţiilor anterioare îndeplineşte anumite criterii care pot fi verificate prin intermediul biţilor
indicatori din registrul STATUS.
Instrucţiunile de salt necondiţionat vor realiza saltul prin modificarea directă a valorii
numărătorului program. Astfel, instrucţiunea BRA realizează un salt la o instrucţiune
destinaţie prin adaugarea unui offset la adresa curentă stocată de numărătorul program, iar
instrucţiunea GOTO realizează saltul direct la orice adresă din spaţiul de memorie al
programului. În consecinţă, instrucţiunea BRA realizează un salt relativ, iar instrucţiunea
GOTO realizează un salt absolut în memoria program.
Modul de execuţie al celor două instrucţiuni se prezintă în Fig. 2.12.

41
SETUL DE INSTRUCŢIUNI

Fig. 2.12. Exemplificarea diferenţei între saltul necondiţionat relativ (BRA)şi cel absolut (GOTO)

Conform figurii de mai sus, la execuţia instrucţiunii BRA .+6, numărătorul de


program (PC) indică, din cauza existenţei pipeline-ului, spre instrucţiunea următoare
(PC=h’008’). Execuţia acestei instrucţiuni modifică valoarea efectivă a numărătorului de
program, realizând un salt peste n cuvinte (n x 16 biţi) din memoria program. Deci, noua
adresă a numărătorului de program, şi implicit a noii instrucţiuni care va fi extrasă din
memorie în vederea execuţiei, va fi: PC = h’008’+2xn = h’008’+h’00C’=h’014’.
Pe de altă parte, instrucţiunea GOTO determină saltul absolut în memoria program la
instrucţiunea găsită la adresa fizică h’07F2’, codificată prin Eticheta_2.
Asupra instrucţiunilor de apel şi revenire din subrutină (CALL, RETURN,
RETFIE, RETLW) şi a celor care intervin în utilizarea stivei (PUSH, POP) se va reveni în
capitolele următoare.

2.2.9 Alte instrucţiuni

Instrucţiunile cuprinse în această categorie permit realizarea scrierii şi citirii tabelare


din memoria program. Aceste instrucţiuni, vor fi doar amintite în acest capitol, în Tabelul
2.12, fiind prezentate mai detaliat în unul din capitolele următoare.

42
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Tabel 2.11. Instrucţiuni de scriere şi citire tabelară


Instrucţiuni Descriere Cicluri instr.
TBLRD* Citire tabelară 2
TBLRD*+ Citire tabelară cu post incrementare
TBLRD*- Citire tabelară cu post decrementare
TBLRD+* Citire tabelară cu pre incrementare
TBLWT* Scriere tabelară 2
TBLWT*+ Scriere tabelară cu post incrementare
TBLWT*- Scriere tabelară cu post decrementare
TBLWT+* Scriere tabelară cu pre incrementare

Acest capitol cuprinde prezentarea setului de instrucţiuni al


microcontrolerului PIC18F4455. Este prezentat modul în care sunt

Concluzii codificate aceste instrucţiuni în memoria program, sunt prezentaţi


parametrii instrucţiunilor, iar clasificarea din subcapitolul 2.2 are scopul
de a facilita identificarea diferitelor instrucţiuni necesare pentru realizarea
programelor în funcţie de tipul de operaţie realizat. De asemenea,
exemplele întâlnite în acest capitol au rolul de a evidenţia caracteristicile
comune ale diferitelor grupe de instrucţiuni.
În vederea unei cât mai bune înţelegeri a instrucţiunilor
disponibile şi a modului de utilizare al acestora, se propune încheierea
capitolului cu următorul exemplu:

Se consideră următoarea aplicaţie, care implementează succesiv nişte


operaţii după cum urmează:
- se iniţializează registrul de la adresa 0x37 cu valoarea 71
Exemplu
- se incrementează această valoare de 50 de ori
- se setează bitul 4 al rezultatului
- dacă rezultatul obţinut este mai mare decât 200 se şterge
conţinutul registrului de la adresa 0x37
- dacă rezultatul obţinut este mai mic decât 200 se setează toţi biţii
registrului de la adresa 0x37
Se cere codul sursă care implementează funcţionalitatea propusă.

REG EQU 0X37


CONTOR EQU 0X00

43
SETUL DE INSTRUCŢIUNI

MOVLW D’71’
MOVWF REG, 0
MOVLW D’50’
MOVWF CONTOR, 0

Bucla_for:
INCF REG, F, 0
DECFSZ CONTOR, F, 0
GOTO Bucla_for

BSF REG, 4, 0

MOVLW D’200’
CPFSGT REG, 0
SETF REG,0
CLRF REG,0

1. Ce rol îndeplineşte parametrul d în codul instrucţiunii?


2. Care este diferenţa între instrucţiunile GOTO şi BRA?
3. Care va fi conţinutul registrului de lucru WREG ca urmare a celor
Întrebări de
două operaţii implementate prin următorul cod sursă:
autoevaluare
ADDWF REG, W
SUBWF REG, W
4. Cum s-ar implementa o operaţie de deplasare la stânga cu 2 biţi?
5. Ce reprezintă operandul f din codul instrucţiunii?
6. Identificaţi cele 4 instrucţiuni reprezentate pe 32 de biţi
7. Explicaţi instrucţiunea IORWF.
8. Să se scrie un mic program care iniţializează registrul de lucru cu
valoarea 100, roteşte la stânga conţinutul registrului de lucru de 100
de ori apoi setează bitul 3 şi resetează bitul 2.

Carry
Bit de transport. Se găseşte în registrul STATUS
Termeni Codul operaţiei
esenţiali Tipul de operaţie implementat de o anumită instrucţiune
Cuvânt
Doi octeţi. 16 biţi
Decrementare
Operaţie matematică echivalentă cu scăderea cu 1

44
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Etichetă
Identificator introdus în codul sursă pentru a marca adresa de început a
unei instrucţiuni
Incrementare
Operaţie matematică echivalentă adunării cu 1
Instrucţiuni
Comenzi codificate binar pe care le execută UCP
Literal
Valoarea numerică constantă
Memorie
Spaţiu de stocare
Memorie de date
Spaţiu de stocare temporar (RAM) pentru datele cu care lucrează
programul
Memorie program
Spaţiu de stocare pentru program
Numărător de program
Numărător binar utilizat pentru adresarea instrucţiunilor. Conţine adresa
instrucţiunii care urmează a fi executată
Octet
1 Byte = 8 biţi. Capacitatea de stocare a unui registru
Registru
Spaţiu de stocare . Locaţie de memorie .
Resetare
Punerea unui bit sau a unui grup de biţi pe 0 logic
RISC
Reduced Instruction Set Computer
Setare
Punerea unui bit sau a unui grup de biţi pe 1 logic
STATUS
Registru care indică starea operaţiilor aritmetice executate de unitatea
aritmetică şi logică
WREG
Registru de lucru / acumulator. În general conţine unul din operanzii
instrucţiunilor

45
ORGANIZAREA MEMORIEI

3. ORGANIZAREA MEMORIEI

Introducere
Obiective
3.1 MEMORIA PROGRAM
Cuprins
3.1.1 Structura memoriei program
3.1.2 Numărătorul de program
3.1.3 Stiva adreselor de revenire
3.2 MEMORIA DE DATE RAM
3.2.1 Utilizarea Bank-urilor
3.2.2 Utilizarea Access Bank-ului
3.2.3 Utilizarea instrucţiunii MOVFF
3.3 MEMORIA DE DATE EEPROM
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

46
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Buna înţelegere a organizării memoriei permite realizarea unor programe


care utilizează eficient memoria. În cazul microcontrolerelor, această
problemă este deosebit de importantă din cauza limitărilor impuse de
Introducere
resursele fizice disponibile. Microcontrolerele din familia PIC18 cuprind
de regulă în arhitectura lor trei tipuri de memorie:
- memorie program;
- memorie de date RAM;
- memorie de date EEPROM.
După parcurgerea acestui capitol cursantul va trebui:
- să cunoască structura şi harta memoriei program şi a memoriei de
date, dar şi rolul pe care aceste memorii îl îndeplinesc în cadrul
Obiective microcontrolerului PIC18F4455;
- să înţeleagă mecanismul de adresare implementat prin bank-uri şi
legătura sa cu registrul de selecţie al bank-urilor BSR
- să cunoască rolul şi structura Access Bank-ului
- să cunoască rolul şi structura stivei
- să cunoască rolul şi structura numărătorului de program şi a
regiştrilor asociaţi

3.1 MEMORIA PROGRAM

3.1.1 Stuctura memoriei program

Rolul pe care îl îndeplineşte memoria program este de a furniza un spaţiu de stocare


pentru instrucţiunile care formează programul executat de microcontroler.
Capacitatea totală de adresare a microcontrolerelor din familia PIC18 este de 2MByte.
În aceste condiţii magistrala de adrese a memoriei program va avea lăţimea de 21 de biţi
(2MByte=221Byte), iar numărătorul de program, asupra căruia se va reveni în paragraful
următor, va avea şi el dimensiunea de 21 de biţi. Din cei 2MBytes, în cazul
microcontrolerului PIC18F4455 este implementată fizic o memorie program de tip Flash cu
dimensiunea de 24KBytes. Acest lucru permite ca memoria să poată fi ştearsă şi rescrisă de
foarte multe ori, datele tehnice menţionând un număr de 100000 de ştergeri/scrieri posibile.
Din punct de vedere al dimensiunii programului care poate fi stocat în această
memorie, o scurtă analiză ne conduce la concluzia conform căreia în 24kB de memorie

47
ORGANIZAREA MEMORIEI

program se poate stoca un program format din până la 12268 de instrucţiuni scurte (de 16
biţi).
Accesarea unei locaţii de memorie cuprinsă între limita superioară a memoriei
implementate fizic şi limita maximă a spaţiului de adresare de 2MByte va întoarce valoarea
zero, fiind echivalentă execuţiei instrucţiunii NOP (No OPeration).
Microcontrolerele din familia PIC18 dispun de doi vectori de întrerupere care se
găsesc la adresele 0008h şi 0018h. La apariţia unor înteruperi vor fi executate în mod
automat instrucţiunile care se vor regăsi în memorie la aceste adrese. Asupra acestei chestiuni
se va reveni în capitolul dedicat sistemului de întreruperi. Adresa de reset a
microcontrolerului se găseşte la locaţia 0000h. Aceasta este adresa la care se resetează
numărătorul de program. În afara acestor trei locaţii de memorie mai speciale, restul locaţiilor
memoriei program sunt echivalente.[10,15]
În Fig. 3.1 se prezintă harta memoriei program pentru microcontrolerul PIC18F4455.

Fig. 3.1. Harta memoriei program

După cum s-a putut vedea în capitolul anterior, din punct de vedere al dimensiunii,
instrucţiunile pot fi împărţite în două categorii: instrucţiuni scurte (16 biţi) şi instrucţiuni lungi
(32 biţi). Instrucţiunile scurte vor ocupa două locaţii de memorie succesive, iar instrucţiunile
lungi vor ocupa patru locaţii de memorie. În ambele cazuri octetul cel mai puţin semnificativ
al instrucţiunii va ocupa o adresă pară. Următorul exemplu prezintă modul de reprezentare al
instrucţiunilor în memoria program.

48
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Se consideră o secţiune de cod formată din trei instrucţiuni scurte a căror


codificare în memoria program are forma prezentată în Fig. 3.2.

Exemplu

Fig. 3.2. Reprezentarea instrucţiunilor în memoria program

Citirea si scrierea memoriei program a microcontrolerelor (fără a lua în considerare


execuţia propriu-zisă a codului) se realizează de regulă utilizând un circuit extern de
programare şi un set de pini bine definiţi pentru acest scop. Microcontrolerul PIC18F4455
permite citirea şi scrierea memoriei program şi prin intermediul instrucţiunilor de sciere/citire
tabelară de tip TBLRD/TBLWT. Utilizând aceste instrucţiuni, se poate citi codul, se pot
efectua programatic modificări asupra codului, se pot stoca date şi se pot citi date din
memoria program.[8]

3.1.2 Numărătorul de program

Numărătorul de program (en. PC=Program Counter) conţine adresa următoarei


instrucţiuni care va fi extrasă din memorie. Pentru a putea adresa întreaga memorie,
numărătorul de program are dimensiunea de 21 de biţi împărţiţi în trei regiştri de 8 biţi: PCL,
PCH şi PCU.
Registrul PCL (en. Program Counter Low) conţine primii opt biţi ai numărătorului de
program PC<7:0>, registrul PCH (en. Program Counter High) conţine următorii opt biţi ai
numărătorului de program PC<15:8>, iar registrul PCU (en. Program Counter Upper)
conţine cei cinci biţi superiori ai numărătorului de program PC<20:16>.
În mod normal, numărătorul de program se incrementează de două ori, automat, după
fiecare fază de extragere a unei instrucţiuni din memorie, funcţionând în esenţă asemenea
unui numărător binar uzual. Totuşi, instrucţiuni precum GOTO, care permit efectuarea de

49
ORGANIZAREA MEMORIEI

salturi la diverse instrucţiuni din memoria program, intervin în incrementarea obişnuită


realizată de numărătorul de program modificându-i valoarea. Chiar dacă modificarea valorii
numărătorului program este lăsată de obicei în seama instrucţiunilor specializate, există
posibilitatea de a accesa regiştrii numărătorului program şi de a interveni în evoluţia sa
normală. În general, acest lucru este util atunci când se doreşte accesul la elementele unor
tablouri implementate în memoria program, după cum se va vedea în unul din capitolele
următoare.
Accesul la regiştrii numărătorului de program este într-o oarecare măsură problematic,
din cauza faptului că regiştrii săi au dimensiunea de opt biţi, iar toate modificările
numărătorului de program trebuie să afecteze simultan toţi cei 21 de biţi ai săi, pentru a
realiza modificarea atomică a valorii sale.
Dintre regiştrii numărătorului de program, doar PCL poate fi scris şi citit direct, fiind
mapat sub forma unui registru special în memorie. Pentru PCH şi PCU s-au introdus doi
regiştri tampon PCLATH (en. PC LATch High) şi PCLATU (en. PC LATch Upper).
Pentru a rezolva problema modificării conţinutului numărătorului de program, scrierea
unei valori în registrul PCL (ex. MOVWF PCL) transferă simultan şi conţinutul regiştrilor
tampon PCLATU:PCLATH în regiştrii PCU:PCH. La citirea registrului PCL (ex. MOVF
PCL,W) se transferă simultan şi conţinutul regiştrilor PCU:PCH în regiştrii tampon
PCLATU:PCLATH. În acest fel, scrierea şi citirea valorii efective a numărătorului de program
se realizează într-un singur pas.[6,8,15]
Structura numărătorului de program şi modul în care se face accesul la regiştrii săi se
prezintă în Fig. 3.3.

Fig. 3.3. Structura numărătorului de program şi accesul la regiştrii săi

Pentru a ilustra procesul de modificare a valorii numărătorului de program se


consideră exemplul următor

50
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Se analizează cazul creşterii valorii numărătorului de program cu 32


(PC+32) realizându-se astfel un salt peste următoarele 16 instrucţiuni (32
octeţi) ale programului fără a se utiliza instrucţiuni de control al execuţiei.
Exemplu
Presupunând că a fost declarat în prealabil un registru de uz general denumit
TEMP, atunci următoarea porţiune de cod va realiza cele propuse.

MOVF PCL,W ; se salvează PCL în registrul TEMP


MOVWF TEMP
MOVLW d’32’ ; se mută constanta 24 în WREG
ADDWF TEMP,F ; se adună la valoarea din PCL
MOVLW 0 ; se pune valoarea 0 în WREG
ADDWFC PCLATH,F ; se adună bitul de transport la PCLATH
MOVLW 0 ; se pune valoarea 0 în WREG
ADDWFC PCLATU,F ; se adună bitul de transport la PCLATU
MOVF TEMP,W ; se înscrie noua valoare în PCL pentru a
MOVWF PCL ; actualiza şi restul regiştrilor PC

Depăşirea cu o unitate a valorii maxime stocate într-unul din regiştrii


numărătorului program nu conduce la incrementarea automată a valorii
registrului superior.
Codul prezentat mai sus oferă o soluţie la această problemă. Astfel,
deoarece nu se cunoaşte valoarea iniţială a PC, adunarea valorii 32 la PCL
poate conduce la depăşirea valorii maxime care poate fi stocată pe 8 biţi
(255) în acest registru. Prin utilizarea bitului de transport care se adună la
valoarea din PCLATH, şi apoi la valoarea din PCLATU se asigură
modificarea corectă a valorii PC.

Ca o măsură de protecţie suplimentară, bitul 0 al numărătorului program va avea tot


timpul valoarea 0 (PC<0>=0). În acest fel se evită obţinerea de adrese invalide ca urmare a
modificării valorii numărătorului de program, iar acesta va indica întotdeauna spre adresa de
început a unei instrucţiuni.

3.1.3 Stiva adreselor de revenire

Apelul unei subrutine este echivalent cu încărcarea adresei primei instrucţiuni a


subrutinei în numărătorul de program (PC), efectuându-se astfel un salt la adresa respectivă,
practic un GOTO. Astfel, dacă subrutina noastră (denumită SR_exemplu) ar începe la adresa
0400h în memoria program, atunci GOTO 0x400 ar fi echivalent cu apelul subrutinei.

51
ORGANIZAREA MEMORIEI

Presupunând că programatorul a plasat eticheta SR_exemplu înaintea primei instrucţiuni a


subrutinei, atunci am avea GOTO SR_exemplu.
Apare totuşi o problemă în mecanismul prezentat. Procesorul trebuie să îşi aducă
aminte din ce loc al programului s-a efectuat apelul subrutinei, pentru a se putea întoarce cu
execuţia la instrucţiunea imediat următoare apelului de subrutină, odată ce a finalizat de
executat instrucţiunile din subrutină. Acest lucru este pus în evidenţă în Fig. 3.4 unde apelul
de subrutină se poate produce din două locuri diferite ale programului principal sau chiar
dintr-o altă subrutină, după cum se va vedea în Fig. 3.6.

Fig. 3.4. Apelul de subrutină

O soluţie la această problemă este de a salva, înainte de a efectua apelul/saltul, adresa


de revenire într-un registru de adrese sau într-o locaţie de memorie. La sfârşitul subrutinei,
adresa salvată poate fi mutată înapoi în numărătorul de program, realizându-se astfel
întoarcerea din subrutină. Din păcate, această abordare nu va funcţiona în cazul apelului a
două subrutine imbricate, deoarece la apelul celei de-a doua subrutine se va suprascrie adresa
de revenire a primei subrutine şi evoluţia programului nu va mai fi cea dorită. Prin utilizarea
unui număr mai mare de regiştri de adresă sau locaţii de memorie, care vor forma o stivă de
tip LIFO (Last In First Out) şi care va stoca adresele de revenire s-ar rezolva şi această
problemă.
Microcontrolerele din seria PIC18 implementează o stivă formată din 31 de regiştri cu
dimensiunea de 21 de biţi utilizată pentru stocarea adreselor de revenire a subrutinelor şi
rutinelor de tratare a întreruperilor. În Fig. 3.5 se prezintă această structură cunoscută sub
denumirea de stiva adreselor de revenire. Această stivă reprezintă un spaţiu de memorie
distinct, nefiind mapată în spaţiul de adrese al memoriei de date, iar structura ei permite
efectuarea unui număr maxim de 31 de apeluri de subrutine imbricate.[10,15]

52
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 3.5. Utilizarea stivei adreselor de revenire

Stiva are asociat un indicator de stivă (en. Stack Pointer) cu dimensiunea de 5 biţi,
care se găseşte în registrul STKPTR, biţii <4:0>. La fiecare apel de subrutină (CALL)
indicatorul de sitvă se incrementează automat şi starea numărătorului de program este copiată
în registrul din stivă spre care acesta indică. Adresa salvată reprezintă adresa instrucţiunii
imediat următoare (după CALL). După ce PC a fost pus pe stivă, acesta este suprascris cu
adresa instrucţiunii destinaţie. La fel ca şi în cazul instrucţiunii GOTO, şi instrucţiunea CALL
este tot o instrucţiune lungă, lucru care permite subrutinelor implementate să fie plasate
oriunde în spaţiul memoriei program.
Fig. 3.5-a prezintă configuraţia stivei la reset, atunci când indicatorul de stivă are
valoarea 0. Adresa 0 a stivei nu este utilizată niciodată, deoarece întotdeauna indicatorul de
stivă se incrementează înainterea punerii PC pe stivă. În situaţia prezentată în Fig. 3.5-b se
arată configuraţia stivei după apelul unei subrutine cu eticheta SR_exemplu.
Apelul subrutinei CALL SR_exemplu determină următoarele:
1. Indicatorul de stivă se incrementează;
2. Cei 21 de biţi ai PC se copiază în locaţia din stivă spre care indică indicatorul de stivă.
Datele stocate reprezintă adresa instrucţiunii care urmează după CALL;

53
ORGANIZAREA MEMORIEI

3. Adresa instrucţiunii de destinaţie, marcată prin eticheta SR_exemplu, care


corespunde primei instrucţiuni a subrutinei, va suprascrie PC. Acest lucru determină
transferul execuţiei către subrutină.
Revenirea din subrutină, prezentată în Fig. 3.5-c, se produce la execuţia instrucţiunii
RETURN, şi determină următoarele operaţii:
1. Se copiază în PC adresa de 21 de biţi din registrul stivei spre care indică indicatorul
de stivă;
2. Se decrementează indicatorul de stivă.[6]
Mecanismul implementat de stivă şi prezentat în Fig. 3.5 permite execuţia corectă a
apelurilor de subrutină, dar avantajul oferit de stivă este mult mai evident în cazul subrutinelor
imbricate. Petru a exemplifica acest lucru se consideră situaţia prezentată în Fig. 3.6, unde
programul principal apelează subrutina SR_1, care apelează la rândul ei subrutina SR_2,
revenindu-se apoi pe rând la programul principal. Structura de tip LIFO a stivei permite
rezolvarea oricărei situaţii de imbricare de până la 31 de subrutine.

Fig. 3.6. Subrutine imbricate

Pe lângă funcţionarea automată a stivei, care a fost prezentată până acum, există şi
posibilitatea de a accesa manual conţinutul stivei. În Fig. 3.7 se prezintă structura stivei care
utilizează, pe lângă indicatorul de stivă din registrul STKPTR, şi tripletul format din regiştrii
de la vârful stivei: TOSU:TOSH:TOSL (Top Of Stack Upper/High/Low). La orice moment
dat, regiştrii TOS conţin cei 21 de biţi de date de pe poziţia din stivă spre care indică

54
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

indicatorul de stivă STKPTR<4:0>. Modificarea regiştrilor TOS va conduce la modificarea


conţinutului de pe poziţia corespunzătoare a stivei. În acest fel se permite examinarea sau
chiar modificarea valorilor adreselor de revenire stocate în stivă.

Fig. 3.7. Structura stivei adreselor de revenire

Prin deplasarea indicatorului de stivă în sus şi în jos pot fi accesate datele localizate pe
diferite poziţii în stivă. Astfel, indicatorul de stivă STKPTR<4:0> poate lua valori de la 0 la
31. În momentul în care ajunge la valoarea 31, bitul STKFUL (en. STAcK FuLl) este pus pe 1
indicând stiva plină, iar în momentul în care ajunge la valoarea 0, bitul STKFUNF (en.
STAcK UNderFlow) este pus pe 1. Structura registrului STKPTR care conţine indicatorul de
stivă şi cei doi biţi de stare se prezintă în Fig. 3.8.

7 0
STKFUL STKUNF - SP4 SP3 SP2 SP1 SP0
Fig. 3.8. Structura registrului STKPTR

În afara instrucţiunilor de apel şi revenire din subrutină, setul de instrucţiuni al


microcontrolerelor din seria PIC18 mai curpinde două instrucţiuni: PUSH şi POP special
concepute pentru manipularea indicatorului de stivă fără a produce saltul spre sau revenirea
dintr-o subrutină.
Instrucţiunea PUSH, prezentată în Fig. 3.9-a, incrementează indicatorul de stivă şi
copiază conţinutul numărătorului de program (care indică spre instrucţiunea care urmează
după PUSH) pe stivă, care va fi apoi accesibil prin regiştrii TOS. Instrucţiunea este
asemănătoare lui CALL fără a suprascrie însă PC cu adresa de început a unei subrutine.
Instrucţiunea POP, prezentată în Fig. 3.9-b, decrementează indicatorul de stivă, iar
TOS se modifică pentru a reflecta conţinutul stivei de pe noua poziţie spre care indică
indicatorul de stivă.[6]

55
ORGANIZAREA MEMORIEI

Fig. 3.9. Instrucţiunile PUSH şi POP

3.2 MEMORIA DE DATE RAM

Acest tip de memorie este utilizat de regulă pentru stocarea datelor temporare necesare
rulării programelor (ex. variabile şi constante de program).
Capacitatea totală de adresare a memoriei RAM pentru microcontrolerele din familia
PIC18 este de 4096 de octeţi, fiecare octet purtând denumirea de registru. Aceşti regiştri sunt
împărţiţi în două categorii: regiştri destinaţi stocării datelor denumiţi Regiştri de Uz General
(en. GPR = General Purpose Registers), respectiv regiştri cu anumite funcţii de configurare /
monitorizare cunoscuţi sub denumirea de Regiştri Speciali (en. SFR = Special Function
Registers). Maparea regiştrilor GPR şi SFR în acelaşi spaţiu de adrese permite accesarea lor
prin intermediul unui singur set de instrucţiuni. Din cei 4096 octeţi de memorie RAM,
microcontrolerul PIC18F4455 implementează un total de 2048 de octeţi.
Un spaţiu de stocare de 4kBytes necesită o adresă de 12 biţi (4096 Bytes = 212 Bytes).
După cum s-a putut vedea în capitolul anterior, pentru marea majoritate a instrucţiunilor,
câmpul prevăzut pentru adresă în codul instrucţiunii este de doar 8 biţi. Există patru modalităţi
de a ocoli acest inconvenient pentru a putea accesa întreaga memorie:
- utilizarea Bank-urilor;
- utilizarea Access Bank-ului;
- utilizarea instrucţiunii MOVFF;
- utilizarea pointerilor (vezi capitolul următor).

56
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

3.2.1 Utilizarea Bank-urilor

Pentru a asigura adresarea pe un octet a întregii zone de memorie (utilizând


instrucţiuni scurte), memoria de date este împărţită în bank-uri (Fig. 3.10). O asemenea
împărţire înseamnă că nu este necesară specificarea întregii adrese (de 12 biţi) pentru fiecare
operaţie de scriere sau citire a memoriei, ci doar a unei părţi a acesteia (8 biţi din cei 12).

Fig. 3.10. Structura memoriei RAM la microcontrolerul PIC18F4455 conform foii de catalog [15]

Numărul de bank-uri pentru seria PIC18 este de 16, fiecare bank conţinând 256 de
octeţi. Din aceste 16 bank-uri, microcontrolerul PIC18F4455 implementează doar 8. Regiştrii
SFR sunt implementaţi în partea superioară a bank-ului 15 (160 de octeţi), iar în rest regiştrii
sunt de uz general. Dacă se utilizează comunicarea prin USB, bank-urile 4-7 sunt folosite
pentru a asigura transferul de date USB.

57
ORGANIZAREA MEMORIEI

Pentru formarea adresei complete de 12 biţi se va utiliza un octet care specifică adresa
în cadrul bank-ului (cei 8 biţi inferiori ai adresei complete) şi 4 biţi reprezentând numărul
bank-ului accesat (restul de 4 biţi ai adresei complete).
Majoritatea instrucţiunilor din familia PIC18 utilizează cei 4 biţi pentru selecţia bank-
ului, aceştia fiind accesibili prin intermediul registrului special BSR (en. Bank Select
Register). Acest registru conţine biţii cei mai semnificativi ai adresei de 12 biţi (BSR<3:0>),
ceilalţi 8 biţi ai adresei fiind specificaţi în cadrul instrucţiunii.
Pentru modificarea conţinutului acestui registru este disponibilă o instrucţiune
specială: MOVLB (en. Move Literal to BSR).
De exemplu, selectarea bank-ului 2 se poate realiza cu următoarea instrucţiune:
MOVLB 0x02
sau, luând în considerare că BSR este un simplu registru ca oricare altul, valoarea sa se poate
modifica şi pe baza următoarei secvenţe de instrucţiuni:
MOVLW 0x02
MOVWF BSR
Trebuie menţionat faptul că toate instrucţiunile de lucru cu regiştrii se aplică şi asupra
registrului BSR.

În exemplul următor se prezintă modul de adresare al memoriei folosind bank-urile.


Pentru a modifica valoarea registrului de la adresa 0x20 din Bank-ul 2
trebuie parcurşi următorii paşi:
- se mută constanta 2 în registrul BSR
Exemplu
- se accesează registrul de la adresa 0x20 asigurându-ne că bitul a din
codul instrucţiunii are valoarea 1 (a=1 sau a=BANKED)
Următoarea secvenţă de cod şterge conţinutul registrului de la adresa 0x202.
;selectare Bank 2 (BSR = 2)
MOVLB 0x02
;accesare registrul 0x20 din Bank 2
CLRF 0x20, BANKED

Având în vedere că până la 16 regiştri pot avea aceeaşi adresă inferioară, utilizatorul
trebuie să se asigure că a selectat bank-ul de lucru potrivit înainte de a realiza operaţii de
scriere sau citire. Această situaţie este exemplificată în continuare:

58
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

;selectare Bank 2 (BSR = 2)


MOVLB 0x02
;accesare registrul 0x00 din Bank 2.
CLRF 0x00, BANKED
Exemplu
;selectare Bank 3 (BSR = 3)
MOVLB 0x03
;accesare registrul 0x00 din Bank 3
INCF 0x00, BANKED

În exemplul anterior se observă faptul că cei doi regiştri accesaţi, unul din bank-
ul 2 şi celălalt din bank-ul 3, dispun de aceeaşi adresă inferioară (0x00)
introdusă prin intermediul instrucţiunilor.
În Fig. 3.11 se prezintă modul de formare al adresei complete în cazul accesării
directe a memoriei prin intermediul bank-urilor şi a registrului BSR.

Fig. 3.11. Formarea adresei în vederea accesării memoriei RAM prin Bank-uri

3.2.2 Utilizarea Access Bank-ului

Utilizarea registrului BSR împreună cu adresa de 8 biţi specificată prin intermediul


instrucţiunilor permite adresarea întregii memorii, dar ridică şi anumite inconveniente pe care
utilizatorul trebuie să le ia în considerare. Acesta trebuie să se asigure întotdeauna că este
selectat bank-ul de lucru corect, pentru a accesa datele din zona dorită de memorie. Aceste
inconveniente sunt mai evidente atunci când se doreşte accesul la regiştrii speciali (care se
găsesc în Bank 15) pentru anumite configurări, lucru care presupune schimbarea bank-ului de
lucru, iar apoi revenirea la bank-ul curent de lucru în vederea utilizării regiştrilor de uz
general. Astfel, verificarea şi/sau modificarea conţinutului registrului BSR pentru fiecare

59
ORGANIZAREA MEMORIEI

operaţie de scriere sau citire a memoriei poate deveni foarte ineficientă din cauza creşterii
numărului de instrucţiuni utilizate, care conduce, în mod evident, spre creşterea timpului de
execuţie al programului, şi predispune frecvent la erori.
Această problemă a fost rezolvată prin introducerea unei zone virtuale de memorie
denumită Access Bank, accesibilă fără modificarea bank-ului. Această zonă de memorie
mapează primii 96 de regiştri GPR (din Bank 0) şi cei 160 de regiştri SFR (din Bank 15).
Pentru a accesa zona de memorie mapată în Access Bank, utilizatorul va fi nevoit să
reseteze bitul de acces (a=0 sau a=ACCESS) existent în cadrul instrucţiunilor.
Astfel, când bitul de access (a) al instrucţiunilor va avea valoarea 1 (BANKED), la
formarea adresei se va lua în considerare conţinutul registrului BSR, iar operandul f al
instrucţiunilor va reprezenta locaţia accesată din cadrul bank-ului selectat. Când bitul de
access (a) al instrucţiunilor va avea valoarea 0 (ACCESS), conţinutul registrului BSR este
ignorat, iar operandul f al instrucţiunilor va reprezenta adresa unei locaţii din Access Bank.

În exemplul următor se prezintă modul de adresare al memoriei prin intermediul


Access Bank-ul.
Se consideră cazul accesului la registrul special TRISA, aflat în Bank-ul 15
la adresa 0xF92, precum şi accesul la registrul de uz general de la adresa
0x007 din Bank-ul 0, ambii regiştri utilizaţi fiind mapaţi în Access Bank:
Exemplu
CLRF TRISA, ACCESS
BSF TRISA, 4, ACCESS
INCF 0x07, ACCESS

3.2.3 Utilizarea instrucţiunii MOVFF

Instrucţiunea MOVFF permite mutarea unui octet de date dintr-un loc în orice alt loc al
memoriei RAM de date. MOVFF este una din cele doar patru instrucţiuni lungi (având 32 biţi)
disponibile în setul de instrucţiuni al microcontrolerului, lucru care îi permite să stocheze, de
una singură, adresele complete de 12 biţi ale regiştrilor sursă şi destinaţie. Astfel, dacă se
doreşte, de exemplu, să se mute un octet din registrul de la adresa 0xF81 (PORTB) în locaţia
de memorie de la adresa 0x220 se poate utiliza MOVFF 0xF81, 0x220, fără a recurge la
Access Bank sau Bank-uri. Totuşi, având în vedere că MOVFF este o instrucţiune lungă,
aceasta va necesita două cicluri instrucţiune pentru a fi extrasă din memoria program, având
astfel un timp de execuţie dublu faţă de instrucţiunile simple.

60
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

3.3 MEMORIA DE DATE EEPROM

Memoria EEPROM este o memorie nevolatilă utilizată de regulă pentru stocarea


datelor program persistente. De exemplu, această zonă de memorie poate fi utilă la
memorarea configurărilor unui proces, astfel încât acestea să nu se piardă când sistemul nu
este alimentat. Numărul de octeţi EEPROM disponibili pentru P18F4455 este de 256. Datele
se citesc şi se scriu pe un octet. Specificaţiile tehnice menţionează un număr de 1.000.000 de
stergeri/scrieri posibile.
Memoria EEPROM nu este mapată în spaţiul de memorie RAM sau program. În
schimb, se accesează indirect utilizând un set de regiştri speciali: EECON1, EECON2,
EEDATA şi EEADR.

În acest capitol s-a prezentat modul de organizare a memoriei


microcontrolerului PIC18F4455. Acest microcontroler dispune de trei

Concluzii tipuri diferite de memorie.


Memoria program este utilizată pentru stocarea programului,
având o capacitate totală de adresare de 2MB, din care sunt implementaţi
fizic 24kB. Pentru a putea adresa întreaga memorie, microcontrolerul
dispune de un numărător de program cu dimensiunea de 21 de biţi, care
poate fi accesat prin intermediul a trei regiştri mapaţi în spaţiul de
memorie RAM. Stiva adreselor de revenire este implementată sub forma
unei structuri LIFO cu 31 de nivele.
Memoria RAM de date are rolul de a stoca datele temporare
necesare rulării programelor. Are dimensiunea de 4kB, fiind împărţită în
16 Bank-uri de 256B. Primii 96 de regiştri GPR din Bank 0 şi cei 160 de
regiştri SFR din Bank 15 pot fi accesaţi prin intermediul unei zone
virtuale de memorie denumită Access Bank.
Memoria EEPROM este o memorie nevolatilă utilizată pentru
stocarea datelor program persistente care poate fi accesată prin
instucţiunile cunoscute cu ajutorul unor regiştri SFR mapaţi în memoria
RAM.

61
ORGANIZAREA MEMORIEI

1. Cum se formează adresa completă în cazul utilizării Access Bank-


ului?
2. De ce este necesară modificarea atomică a regiştrilor numărătorului
Întrebări de
de program?
autoevaluare
3. Care este diferenţa între instrucţiunile GOTO şi CALL din punct de
vedere al stivei şi al numărătorului de program?
4. Care este rolul Access Bank-ului?
5. Cum se poate modifica manual conţinutul stivei?
6. Ce rol îndeplineşte parametrul a în codul instrucţiunii?
7. Cum se formează adresa completă în cazul utilizării Bank-urilor?
8. Ce rol îndeplineşte registrul BSR?

Access Bank
Zonă virtuală de memorie prin intermediul căreia se pot accesa primii 96
Termeni de regiştri GPR din Bank 0 şi cei 160 de regiştri SFR din Bank 15.
esenţiali Bank
Zonă de memorie formată din 256 de octeţi utilizată ca diviziune a
memoriei RAM de date.
BSR
Bank Select Register. Registru de selecţie a Bank-urilor
EEPROM
Electrically Erasable Programmable Read-Only Memory. Memorie
nevolatilă utilizată pentru a stoca mici cantităţi de date care trebuie
păstrate în lipsa alimentării.
Etichetă
Identificator introdus în codul sursă pentru a marca adresa de început a
unei instrucţiuni
GPR
General Purpose Registers. Regiştri de uz general
LIFO
Last In First Out. Mod în care sunt stocate şi scoase datele din stivă.
Memorie de date
Spaţiu de stocare temporar (RAM) pentru datele cu care lucrează
programul

62
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Memorie program
Spaţiu de stocare pentru program
Memorie virtuală
Tehnică de gestiune a memoriei care virtualizează diferite forme de
stocare a datelor (ex. RAM) care pot fi accesate din program în mod
asemănător memoriei fizice.
Numărător de program
Numărător binar utilizat pentru adresarea instrucţiunilor. Conţine adresa
instrucţiunii care urmează a fi executată
Octet
1 Byte = 8 biţi. Capacitatea de stocare a unui registru
PCL
Program Counter Low. Registrul care conţine biţii <7:0> ai numărătorului
de program.
PCLATH
Program Counter Latch High. Registru tampon asociat PCH
PCLATU
Program Counter Latch Upper. Registru tampon asociat PCU
PCH
Program Counter High. Registrul care conţine biţii <15:8> ai
numărătorului de program. Este un registru ascuns şi nu poate fi accesat
direct.
PCU
Program Counter Upper. Registrul care conţine biţii <20:16> ai
numărătorului de program. Este un registru ascuns şi nu poate fi accesat
direct.
Registru
Spaţiu de stocare . Locaţie de memorie. Octet în memoria RAM de date
SFR
Special Function Registers. Regiştri cu funcţii speciale
STKPTR
Stack Pointer Register. Registrul care conţine indicatorul de stivă şi doi
biţi care indică starea stivei.

63
ORGANIZAREA MEMORIEI

Stivă
Spaţiu de memorie în care se salvează adresele de revenire în cazul
apelurilor de subrutină
TOS
Top of stack. Regiştrii de la vârful stivei (TOSU:TOSH:TOSL) care
conţin imaginea datelor din stivă spre care indică indicatorul de stivă

64
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

4. ADRESAREA MEMORIEI DE DATE

Introducere
Obiective
4.1 VARIABILE ŞI NUME SIMBOLICE
Cuprins
4.2 ADRESAREA DIRECTĂ
4.3 ADRESAREA INDIRECTĂ
4.3.1 Regiştri de adresare şi accesare conţinut
4.3.2 Adresarea indexată
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

65
ADRESAREA MEMORIEI DE DATE

Fiecare octet din memorie dispune de o adresă unică. Majoritatea


instrucţiunilor microcontrolerului au ca operand adresa unei locaţii de
memorie. Modurile de adresare indică felul în care se specifică operanzii
Introducere
unei instrucţiuni. Aceste moduri de adresare influenţează flexibilitatea
obţinerii adreselor accesate, dar şi complexitatea operaţiilor care pot fi
executate. Pentru a putea accesa întreaga memorie RAM există
disponibile mai multe modalităţi de adresare asupra cărora ne vom opri în
acest capitol.
După parcurgerea acestui capitol cursantul va trebui:
- să utilizeze corect numele simbolice
- să înţeleagă rolul regiştrilor de adresare şi accesare conţinut
Obiective - să cunoască diferenţa între adresarea directă şi adresarea indirectă
- să poată implementa tablouri utilizând adresarea indexată

4.1 VARIABILE ŞI NUME SIMBOLICE

Noţiunea de „variabilă” presupune în varianta cea mai simplă o zonă de memorie care
are asociat un nume şi care îşi poate modifica valoarea pe parcursul execuţiei programului.
Spre deosebire de limbajele de nivel înalt (cum ar fi limbajul C), unde localizarea exactă în
memorie şi legarea numelui simbolic de adresa fizică nu sunt cunoscute, în domeniul
microcontrolerelor, utilizatorul are control total asupra implementării noţiunii de variabilă.
Variabila poate reprezenta un registru GPR, un registru SFR, un octet din memoria
EEPROM sau chiar un octet din memoria program. Deoarece variabilele sunt asociate datelor
care se modifcă frecvent (la nivel de microsecundă), utilizarea EEPROM-ului sau a memoriei
program pentru implementarea acestora nu pare a fi o soluţie viabilă. De regulă, memoria
EEPROM şi memoria program sunt folosite pentru stocarea constantelor sau a unor valori
care se modifică la intervale de timp foarte mari (la nivel de secunde sau chiar ore). Din
această cauză, singura soluţie practică pentru implementarea variabilelor rămâne cea a
memoriei RAM de date.[8]
Acestea fiind zise, putem considera o variabilă ca fiind un registru situat într-un
anumit bank (de la 0 la 15) şi având o anumită adresă (de la 0 la 255). Manipularea variabilei
se poate realiza fie utilizând adresa fizică, fie prin ataşarea unui nume simbolic adresei
respective.

66
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Pentru exemplificare să considerăm situaţia în care dorim să configurăm direcţia


pinilor portului B după cum urmează: pinii RB<6:0> intrări, iar pinul RB7 ieşire. Codul care
ar realiza acest lucru este dat mai jos:
MOVLW 0x7F ; secvenţa binară de iniţializare în WREG
MOVWF 0xF93 ; RB7 ieşire, RB<6:0> intrări prin
; configurarea registrului TRISB

Chiar dacă acest fragment de cod este corect, iar cu ajutorul comentariilor funcţionarea
sa poate fi urmărită şi înţeleasă, nu este totuşi prea lizibil. O alternativă la acest cod, dar care
este identică din punct de vedere al asamblorului, poate fi următoarea:
TRISB EQU 0xF93 ; registrul de configurare a direcţiei
; portului B de la adresa 0xF93

MOVLW 0x7F ; secvenţa binară de iniţializare în WREG


MOVWF TRISB ; RB7 ieşire, RB<6:0> intrări prin
; configurarea registrului TRISB

Bineînţeles, cea de a doua variantă este de preferat întrucât creşterea clarităţii codului
conduce la reducerea erorilor şi face programele mai uşor de depanat şi de modificat.

Să considerăm un alt exemplu în care o variabilă aflată în bank-ul 0, la adresa 2,


trebuie iniţializată cu o valoare. Cele două fragmente de cod prezentate mai jos sunt
echivalente din punct de vedere al funcţionalităţii implementate.
MOVLW B’10001010’
MOVWF 0x02

VAR EQU 0x02


MOVLW B’10001010’
MOVWF VAR

În cele două exemple considerate, ataşarea de nume simbolice unor valori s-a realizat
cu ajutorul directivei EQU, prin care se informează asamblorul că în continuare, în program,
valorile numerice respective vor fi înlocuite prin nişte nume. Directiva EQU înseamnă
“EQUivalent to”1 şi este o pseudoinstrucţiune care nu produce cod maşină suplimentar, ci
permite doar transmiterea unei informaţii de la program către compilator.
Astfel, directiva TRISB EQU 0xF93 informează compilatorul că în instrucţiunile
care utilizează numele TRISB ca operand, la preprocesare, acesta să fie înlocuit cu valoarea
0xF93. La fel se întâmplă şi în cazul celui de-al doilea exemplu în care valoarea 0x02, care
reprezintă o adresă din memorie, are ataşată numele simbolic VAR.

1
Această directivă este echivalentă directivei #define din limbajul C

67
ADRESAREA MEMORIEI DE DATE

Cele două exemple prezentate anterior surprind două situaţii în care se realizează
adresarea simbolică: prima în care se utilizează numele simbolic pentru a înlocui adresa unui
registru special (TRISB) în codul instrucţiunii şi cea de-a doua în care se utilizează numele
simbolic pentru a defini adresa unui registru de uz general (0x002).
În realitate numele simbolice asociate regiştrilor SFR sunt predefinite în biblioteca
introdusă la începutul programelor prin directive de tipul #include “p18f4455.inc”
şi nu trebuie declarate de programator. De altfel, nu este recomandată implementarea de
variabile în spaţiul de memorie alocat SFR, deoarece modificarea necontrolată a acestor
regiştri poate altera funcţionarea microcontrolerului.

În programul următor se poate observa ataşarea unor nume simbolice la


două variabile şi la două constante, dar şi utilizarea numelor simbolice
pentru a adresa doi regiştri GPR (VAR1, VAR2) şi un registru SFR (LATB),
Exemplu
a cărui nume simbolic a fost introdus prin directiva #include.[8]
#include “p18f4455.inc”

;Secţiune variabile
VAR1 EQU 0x02
VAR2 EQU 0x03

;Secţiune constante
CONST1 EQU B’10001010’
CONST2 EQU D’20’

ORG 0x800 ; adresa de început


; a programului
MOVLW CONST1
MOVWF VAR1 ;CONST1->VAR1
MOVLW CONST2
MOVWF VAR2 ;CONST2->VAR2
INCF VAR1 ;VAR1++
MOVF VAR1, W ;VAR1->WREG
ADDWF VAR2, F ;WREG+VAR2->VAR2
MOVFF VAR2, LATB ;VAR2->LATB

END

Având în vedere că numele simbolice se ataşează unor valori numerice, utilizarea


acestora trebuie realizată cu atenţie deoarece valoarea numerică respectivă poate fi
considerată drept adresă a unui registru sau o valoare constantă în funcţie de instrucţiunea în
care intervine numele simbolic considerat. Exemplul următor pune în evidenţă acest lucru.

68
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

X EQU 0x02 ; declarare nume simbolic

MOVLW X ; X este constanta cu valoarea


; 0x02
Exemplu ADDWF X ; X este adresa 0x02 a unui
; registru GPR

De multe ori, apare situaţia în care se doreşte alocarea unui număr mare de variabile
sau utilizarea unor nume simbolice care au ataşate o serie de valori în ordine crescătoare. În
acest context se poate utiliza un bloc de nume simbolice în felul următor:
CBLOCK 0x00 ;valoare de start
VAR1 ;VAR1=0
VAR2 ;VAR2=1
VAR3 ;VAR3=2
VAR4 ;VAR4=3
VAR5 ;VAR5=4
ENDC

Utilizarea unui bloc de simboluri se realizează identic cu utilizarea numelor simbolice


declarate prin EQU. De fapt, directiva CBLOCK permite stabilirea valorii unui simbol, urmând
ca valorile celorlalte să fie atribuite în mod consecutiv.[8]

4.2 ADRESAREA DIRECTĂ

În cazul adresării directe (Fig. 4.1) câmpul alocat adresei în codul instrucţiunii conţine
adresa efectivă a operandului. Acest mod de adresare necesită o singură referire la memorie,
şi nu necesită un calcul de adresă. Dezavantajul este că permite un spaţiu de adresare limitat,
deoarece lungimea câmpului de adresă este mai mică decât lungimea cuvântului.[5]

Fig. 4.1. Adresarea directă

În cazul instrucţiunilor scurte ale microcontrolerului PIC18F4455 lungimea câmpului


de adresă este de 8 biţi (vezi formatul instrucţiunilor din Capitolul 2) şi ocupă octetul inferior
al codului instrucţiunii. Practic, prin aceşti 8 biţi se pot accesa doar 256 de locaţii de memorie

69
ADRESAREA MEMORIEI DE DATE

distincte. Pentru a extinde capacitatea de adresare până la cei 12 biţi necesari pentru formarea
adresei complete se utilizează bitul 8 al instrucţiunilor, denumit bit de acces a. Dacă acest bit
este 0 atunci pot fi accesate adresele din domeniul 0x000-0x07F (96 de regiştri GPR) şi
0xF80-0xFFF (160 de regiştri speciali). Pentru a accesa celelalte adrese ale memoriei
RAM, bitul a trebuie setat şi atunci se utilizează octetul inferior al registrului BSR pentru a
completa adresa cu cei patru biţi necesari.
Majoritatea instrucţiunilor ce utilizează adresarea directă au posibilitatea de a plasa
rezultatul operaţiei implementate în registrul de lucru WREG sau înapoi în memoria RAM la
adresa specificată în instrucţiune. Bitul 9 din codul instrucţiunii, denumit bit de destinaţie al
rezultatului d specifică locul în care se va regăsi rezultatul.

În continuare se prezintă câte un exemplu pentru adresarea directă prin Access Bank,
respectiv pentru adresarea directă prin Bank-uri, în care adresa fizică a locaţiei de memorie
accesate este specificată în mod explicit în codul instrucţiunii.

Instrucţiunile
ADDWF 0x3A, w, 0
ADDWF 0x3A, f, 0
Exemplu sunt codificate binar sub forma:
001001 0 0 00111010
respectiv
001001 1 0 00111010
şi în ambele cazuri conţinutul de la adresa 0x3A din Access Bank (a=0)
este adunat cu conţinutul registrului de lucru WREG. Prima instrucţiune
plasează rezultatul operaţiei în WREG (d=0), iar cea de-a doua instrucţiune
suprascrie data de la adresa 0x3A (d=1).

Selecţia bank-ului de lucru cu numărul 3 se face cu instrucţiunea MOVLB 2.


Instrucţiunile
ADDWF 0x3A, w, 1
Exemplu ADDWF 0x3A, f, 1
sunt codificate binar sub forma:
001001 0 1 00111010
respectiv
001001 1 1 00111010

70
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

şi în ambele cazuri se accesează conţinutul de la adresa fizică 0x23A


(locaţia 0x3A din Bank-ul 2) care este adunat cu conţinutul registrului de
lucru WREG. Prima instrucţiune plasează rezultatul operaţiei în WREG (d=0),
iar cea de-a doua instrucţiune suprascrie data de la adresa 0x23A.

După cum s-a văzut în exemplele anterioare cei opt biţi de adresă ai operandului sunt
specificaţi în mod explicit, fiind parte integrantă a instrucţiunii şi nu pot fi modificaţi în
timpul execuţiei programului. Chiar dacă aparent aceasta este modalitatea de a localiza exact
o adresă în memoria de date, există situaţii în care această variantă de adresare este restrictivă,
după cum se va vedea din exemplul următor.

Se va analiza cazul unei secţiuni de cod care trebuie să şteargă (reseteze)


regiştrii din Bank-ul 0 mapaţi în Access Bank. Aceşti regiştri se găsesc în
spaţiul de adrese cuprins între adresa 0x000 şi 0x05F (vezi Fig. 3.10).
Exemplu
STERG_VECTOR:
CLRF H’00’ ; şterg registrul 0
CLRF H’01’ ; şterg registrul 1
CLRF H’02’
CLRF H’03’
CLRF H’04’
CLRF H’05’
CLRF H’06’ ; şterg registrul 5
.... ..... ; etc.
CLRF H’05E’
CLRF H’05F’ ; şterg registrul 94
; şterg registrul 95.
; Am terminat!

Stilul de programare din acest exemplu, deşi funcţionează, dovedeşte lipsa


de flexibilitate a adresării directe, care, prin utilizarea instrucţiunii CLRF de
96 de ori, realizează exact acealşi lucru de fiecare dată, dar asupra unei
locaţii de memorie diferite.
Dacă am fi puşi în situaţia de a şterge conţinutul tuturor regiştrilor GPR (7
Bank x 256 = 1792 regiştri GPR), utilizând aceeaşi metodă, ar fi necesare
1792 de apeluri ale instrucţiunii CLRF. Având în vedere că memoria
program a microcontrolerului PIC18F4455 este de 24kB, iar fiecare
instrucţiune CLRF ocupă doi octeţi din memoria program, atunci porţiunea
de cod care realizează această sarcină, relativ simplă, ar ocupa 14% din
totalul memoriei program.

71
ADRESAREA MEMORIEI DE DATE

4.3 ADRESAREA INDIRECTĂ

În exemplele prezentate până acum, partea de adresă a instrucţiunilor a fost


întotdeauna constantă, fiind parte integrantă a instrucţiunii (ex. MOVWF 0x20) şi, în
consecinţă, fiind stocată permanent în memoria program. În multe situaţii, această abordare se
dovedeşte inflexibilă, iar o adresă variabilă ar fi mult mai utilă. Adresarea indirectă permite
accesarea locaţiilor din memoria de date RAM fără a utiliza o adresă fixă în instrucţiuni.
Marea majoritate a procesoarelor utilizează, într-o formă sau alta, adresarea indirectă,
în care unul sau mai mulţi regiştri interni sunt utilizaţi pentru a stoca adresa operandului din
memorie. Aceşti regiştri de adresă sunt utilizaţi ca pointeri către datele din memorie.
Diferenţa fundamanetală faţă de cazul adresării directe constă în faptul că aceşti regiştri
pointer pot fi modificaţi în timpul execuţiei programului, altfel spus adresa spre datele
accesate poate fi modificată. În acest fel, ea nu mai este fixată permanent în memoria program
ci devine variabilă.
De fapt, utilizarea adresării indirecte este asemănătoare cu utilizarea pointerilor din
limbajul C, unde există o notaţie pentru referirea adresei (variabila pointer), şi o altă notaţie
pentru accesarea conţinutului (utilizarea operatorului *). În cazul microcontrolerului PIC cele
două notaţii vor fi înlocuite de un set de regiştri speciali utilizaţi pentru referirea adresei (vor
îndeplini rolul variabilelor pointer) şi de regiştri speciali utilizaţi pentru accesarea conţinutului
spre care indică pointerii.

4.3.1 Regiştri de adresare şi accesare conţinut

Microcontrolerul PIC18F4455 implementează perechi de regiştri FSR (en. File Select


Registers) utilizaţi pentru adresarea memoriei. În total există trei asemenea perechi: FSR0,
FSR1 şi FSR2 având funcţionalităţi identice. În Fig. 4.2 se prezintă structura regiştrilor
FSR0. Celelalte perechi de regiştri oferă funcţionalităţi identice, şi în afara numelui, aceşti
regiştri nu se deosebesc cu nimic unii de alţii.
Regiştrii FSRn vor fi utilizaţi pentru a stoca adresele absolute, reprezentate pe 12 biţi,
ale locaţiilor de memorie accesate. Posibilitatea utilizării a 12 biţi de adresă permite accesarea
întregii memorii RAM, fără a ţine cont de existenţa bank-urilor.
Pentru a putea stoca adresele de 12 biţi ale locaţiilor de memorie, regiştrii FSRn sunt
formaţi din doi regiştri de 8 biţi: FSRnH şi FSRnL, unde n∈{0,1,2}. Registrul FSRnL
stochează octetul inferior al adresei, iar registrul FSRnH stochează semi-octetul superior al
adresei.[8,15]
72
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

7 4 0 7 0
- - - - Cei 4 biţi superiori ai adresei octetul inferior al adresei

FSR0H FSR0L
Fig 4.2. Structura FSR0 format din perechea FSR0H:FSR0L

Regiştrii FSRnH şi FSRnL sunt accesibili prin instrucţiuni uzuale de manipulare a


regiştrilor, după cum se poate vedea şi din secvenţa de cod următoare, care încarcă în
perechea de regiştri FSR0 valoarea 0x200, reprezentând adresa de 12 biţi a locaţiei 0x200
din memorie.
MOVLW 0x00
MOVWF FSR0L
MOVLW 0x02
MOVWF FSR0H

Setul de instrucţiuni al microcontrolerului PIC18F4455 include o instrucţiune care


permite modificarea ambilor regiştri simultan, într-un singur pas. Astfel, instrucţiunea LFSR
(en. Literal to FSR) stochează în perechea FSRnH:FSRnL valoarea dată ca argument.
De exemplu, instrucţiunea următoare are acelaşi efect ca şi secvenţa de cod anterioară:
va stoca adresa 0x200 în perechea de regiştri FSR0:
LFSR FSR0, 0x200
Accesarea conţinutului de la adresele stocate în FSRn se face prin intermediul
regiştrilor INDFn (en. Indirect File Operands). Astfel, fiecărei perechi de regiştri FSR îi
corespunde un registru INDFn (dat de indexul n∈{0,1,2}) (vezi Fig. 4.3).

7 0
Conţinutul adresei stocate în FSR0H:FSR0L
INDF0
Fig. 4.3. Structura registrului INDF0 corespunzător FSR0 (FSR0H:FSR0L)

Modul în care se realizează adresarea indirectă, folosind regiştrii de adresare şi


accesare conţinut este evidenţiat, pentru cazul utilizării FSR0 şi INDF0, în Fig. 4.4.

73
ADRESAREA MEMORIEI DE DATE

Fig. 4.4. Adresarea indirectă

Regiştrii INDFn sunt utilizaţi în instrucţiunile uzuale de manipulare a regiştrilor, după


cum se poate vedea şi în Fig. 4.5 sau în exemplul următor.[15]

Utilizarea unei instrucţiuni


având registrul INDF1 ca
operand. Conţinutul
locaţiei ECCh se va
aduna la registrul de
lucru, iar rezultatul va fi
stocat la adresa ECCh

Registrul FSR1 stochează


adresa de 12 biti ECCh

INDF1 conţine iniţial data


care se găseşte în
memorie la adresa ECCh,
iar ulterior rezultatul
operaţiei efectuate
Fig. 4.5. Utilizarea instrucţiunilor pentru realizarea adresării indirecte

Se realizează stocarea adresei 200h în registrul de adresă FSR0 prin


utilizarea instrucţiunii LFSR, iar apoi se realizează o serie de operaţii
folosind registrul INDF0.
Exemplu

; incarcă în FSR0 adresa 0x200


LFSR FSR0, 0x200

; adună conţinutul registrului de lucru WREG


; cu conţinutul de la adresa 0x200 şi pune
; rezultatul operaţiei la adresa 0x200
ADDWF INDF0, F

74
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

; incrementează conţinutul de la adresa 0x200


; şi pune rezultatul la adresa 0x200
INCF INDF0, F

; mută conţinutul adresei 0x200 la adresa 0x00


MOVFF INDF0, 0x00

În continuare se va relua exemplul de la sfârşitul paragrafului 4.2, dar de această dată


iniţializarea respectivă se va realiza în cadrul unei bucle folosind adresarea indirectă.
Se va analiza cazul resetării conţinutului tuturor locaţiilor de memorie din
Bank-ul 0 care sunt mapate în Access Bank utilizând adresarea indirectă. Este
vorba despre regiştrii din memoria RAM cuprinşi între adresele 0x000 şi
Exemplu
0x05F.
Acest lucru se poate realiza prin intermediul unei bucle de tip for în care la
fiecare iteraţie se resetează câte o locaţie de memorie. Diagrama din Fig. 4.6
descrie acest algoritm.

Fig. 4.6. Utilizarea unei bucle pentru a şterge un vector de date

Implementarea pas cu pas a acestui program parcurge următoarele etape:


1. Se iniţializează regiştrii FSR0 cu adresa primului element al
vectorului, registrul de la adresa 0x000
2. Prin intermediul lui INDF0 se şterge conţinutul de la această adresă
3. Se incrementează adresa din FSR0

75
ADRESAREA MEMORIEI DE DATE

4. Se verifică dacă pointerul a ajuns la capăt. În cazul de faţă se verifică


dacă s-a ajuns la adresa 0x060. Dacă nu s-a ajuns la capătul
vectorului se face salt la pasul 2.
5. Se continuă programul
Algoritmul prezentat poate fi vizualizat în Fig. 4.7. Structura liniară a
programului implementat în paragraful 4.2 este dezvoltată acum sub forma
unei bucle prezentată prin săgeţile colorate în nuanţe de gri care permite
pargurgerea vectorului prin incrementarea pointerului FSR0 la fiecare trecere
prin buclă. La un moment dat pointerul va depăşi domeniul de adrese
considerat, iar programul va trece la următoarea secţiune de cod
implementată.[6]

Fig. 4.7. Parcurgerea vectorului

Secţiunea de cod care implementează acest algoritm este următoarea:


LFSR FSR0, 0x00 ; iniţializare FSR0
MOVLW 0x60 ; adresa finală

Bucla_for:
CLRF INDF0 ; şterg registrul
INCF FSR0L,F ; incrementez adresa
CPFSEQ FSR0L ; verific condiţia de
GOTO Bucla_for ; oprire şi fac salt la
; iteraţia următoare dacă
; FSR0L≠0x60

Codul de mai sus produce acealaşi rezultat ca şi cel realizat utilizând


adresarea directă, dar în loc de 96 de instrucţiuni utilizează doar 6.

După cum se va vedea în paragraful următor, parcurgerea unui vector de date


reprezintă o operaţie suficient de frecvent utilizată încât microcontrolerul este prevăzut cu
încă patru moduri suplimentare de a realiza adresarea indirectă pentru fiecare din cei trei
pointeri FSRn.

76
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

4.3.2 Adresarea indexată

Utilizarea regiştrilor FSRn şi INDFn pentru parcurgerea unui tablou de date


implementat în memorie necesită instrucţiuni de incrementare la fiecare pas a regiştrilor de
adresă FSRnH şi FSRnL. În plus, dacă aceşti regiştri sunt incrementaţi prin instrucţiuni
uzuale, un overflow al registrului FSRnL nu duce la incrementarea automată a registrului
FSRnH.
Astfel, pentru a rezolva această problemă, fiecare pereche de regiştri FSRn este
prevăzută cu patru operanzi adiţionali care completează funcţionalitatea oferită de operandul
INDFn şi permit realizarea adresării indexate. Asemenea lui INDFn, aceşti operanzi sunt de
fapt niştre regiştri virtuali al căror conţinut poate fi accesat doar cu ajutorul perechii FSRn
asociate, şi în plus implementează o anumită operaţie asupra adresei stocate în FSRn-ul
corespunzător în momentul în care sunt accesaţi.

Cele cinci moduri de a realiza adresarea indirectă invocate prin intermediul regiştrilor
de accesare a conţinutului disponibili pentru fiecare din cei trei regiştri de adresare FSRn sunt
enumerate în continuare:
• INDFn: accesează conţinutul de la adresa stocată în FSRn
• POSTDECn: accesează conţinutul de la adresa stocată în FSRn, apoi
decrementează automat cu ‘1’ această adresă
• POSTINCn: accesează conţinutul de la adresa stocată în FSRn, apoi
incrementează automat cu ‘1’ această adresă
• PREINCn: incrementează cu ’1’ adresa din FSRn, apoi accesează conţinutul
noii adrese
• PLUSWn: adună valoarea (de la -127 la 128) conţinută în registrul de lucru
WREG la valoarea din FSRn, apoi accesează conţinutul de la adresa nou
obţinută

Un exemplu de utilizare al acestor regiştri este următorul:[8]


; iniţializarea FSR0 cu adresa 0x100
LFSR FSR0, 0x100
Exemplu
; F[100h]=0, FSR0++ => FSR0 = 0x101
CLRF POSTINC0

; F[101h]=0xFF, FSR0-- => FSR0 = 0x100


SETF POSTDEC0, F
77
ADRESAREA MEMORIEI DE DATE

; F[101h] = 0x00 (overflow), FSR0++ => FSR0 = 0x101


INCF PREINC0, F

În general, adresarea indexată este utilizată la implementarea tablourilor, oferind prin


intermediul regiştrilor virtuali un acces secvenţial rapid la datele din memoria RAM.
Următorul exemplu reia secţiunea de cod utilizată pentru iniţializarea regiştrilor din memorie
cuprinşi între adresele 0x000 la 0x05F.
Prin înlocuirea registrului INDF0 cu POSTINC0 se realizează în mod
automat incrementarea adresei din FSR0, după ce aceasta a fost utilizată. În
aceste condiţii, codul obţinut este mai avantajos din două puncte de vedere:
Exemplu
- nu se mai utilizează instrucţiunea INCF. În acest fel codul devine
mai scurt şi timpul de execuţie se reduce cu durata a 96 de cicluri
instrucţiune;
- incrementarea realizată prin utilizarea lui POSTINC0 se aplică
întregii adrese de 12 biţi, lucru care nu se întâmpla în cazul
instrucţiunii INCF.
Astfel, codul obţinut este următorul:
LFSR FSR0, 0x000 ; iniţializare FSR0
MOVLW 0x60 ; adresa finală

Bucla_for:
CLRF POSTINC0 ;şterg registrul, FSR0++
CPFSEQ FSR0L ;verific condiţia de
GOTO Bucla_for ;oprire şi fac salt la
;iteraţia următoare dacă
; FSR0L≠0x60

Metodele de adresare cuprind modurile prin care se pot specifica adresele


în cadrul instrucţiunilor. În acest capitol s-au prezentat două metode

Termeni principale de adresare a memoriei RAM de date a microcontrolerului

esenţiali PIC18F4455: adresarea directă, respectiv adresarea indirectă.


Adresarea directă se poate realiza prin Access Bank sau prin Bank-uri şi
utilizează o adresă fixă de opt biţi, menţionată explicit în codul
instrucţiunii. Adresarea indirectă utilizează regiştrii de adresare FSRn şi
mai multe moduri de a accesa conţinutul de la adresa stocată în FSRn prin

78
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

intermediul regiştrilor virtuali INDFn, POSTINCn, POSTDECn,


PREINCn şi PLUSWn.
Utilizarea numelor simbolice poate îmbunătăţi substanţial codul utilizator
prin înlocuirea unor valori numerice cu denumiri specificate de utilizator.
Dacă aceste denumiri sunt asociate unor adrese, atunci pe lângă cele două
metode de adresare amintite, putem vorbi şi despre o adresare simbolică.

1. Ce este un nume simbolic?


2. Care este diferenţa între directivele EQU şi CBLOCK?
3. Ce rol au regiştrii FSR şi INDF?
Întrebări de
4. Care este diferenţa între adresarea directă şi adresarea indirectă?
autoevaluare
5. Ce înţelegeţi prin adresare simbolică?
6. Scrieţi o porţiune de cod care adună conţinutul de la adresele
0x212 şi 0x315 şi stochează rezultatul în WREG. Scriţi codul în
două variante în care să utilizaţi adresarea directă, apoi adresarea
indirectă
7. Scrieţi o porţiune de cod care incrementează corect (prin overflow)
regiştrii FSR0.
8. Scrieţi o porţiune de cod care iniţializează Bank-ul 3 cu valori
crescătoare, începând cu valoarea 0.

Access Bank
Zonă virtuală de memorie prin intermediul căreia se pot accesa primii 96
Termeni de regiştri GPR din Bank 0 şi cei 160 de regiştri SFR din Bank 15.
esenţiali Bank
Zonă de memorie formată din 256 de octeţi utilizată ca diviziune a
memoriei RAM de date.
BSR
Bank Select Register. Registru de selecţie a Bank-urilor
CBLOCK
Directivă ce permite declararea unui bloc de nume simbolice ce iau valori
consecutive

79
ADRESAREA MEMORIEI DE DATE

Directivă
Pseudo-instrucţiune adresată asamblorului
EQU
Directivă ce permite ataşarea de nume simbolice unei valori numerice
FSR
File Select Register. Registru de adresare. Conţine o adresă absolută (12
biţi) din memorie. Este format din FSR0H:FSR0L
GPR
General Purpose Registers. Regiştri de uz general
INDF
Indirect File Operand. Registru de accesare conţinut. Permite accesul la
data stocată în memorie la adresa conţinută în FSR.
Nume simbolic
Denumire ataşată unei valori numerice. Poate fi interpretată ca variabilă
sau constantă.
Pointer
Variabilă ce conţine adrese. În cazul microcntrolerului, ia forma unui
registru de adresare FSR.
POSTINC
Post-incrementare. Accesează conţinutul apoi incrementează adresa
POSTDEC
Post-decrementare. Accesează conţinutul apoi decrementează adresa
PREINC
Pre-incrementare. Incrementează adresa apoi accesează conţinutul.
SFR
Special Function Registers. Regiştri speciali
Variabilă
Locaţie de memorie care are ataşat un nume simbolic

80
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

5. STRUCTURI DE PROGRAM

Introducere
Obiective
5.1 MACROURI
Cuprins
5.2 SUBRUTINE
5.3 TABLOURI
5.3.1 Implementarea tablourilor utilizând instrucţiuni
microprocesor
5.3.2 Implementarea tablourilor utilizând instrucţiuni
dedicate
5.3.3 Implementarea tablourilor utilizând adresarea
indirectă
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

81
STRUCTURI DE PROGRAM

În limbaj de asamblare, codul dezvoltat este greu de urmărit şi modificat.


Pentru a realiza programe scalabile şi uşor lizibile, codul şi datele trebuie
grupate. Structurarea codului folosind macrouri şi subrutine reprezintă o
Introducere
bună practică de programare, aceste structuri formând baza unor limbaje
de nivel înalt precum C-ul. De asemenea, gruparea datelor în structuri
denumite tablouri poate îmbunătăţi codul realizat

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă diferenţa dintre macrouri şi subrutine
- să înţeleagă diferenţa între tablourile implementate în memoria
Obiective program şi cele implementate în memoria RAM de date
- să implementeze corect structurile de program prezentate
- să structureze codul programelor realizate

5.1 MACROURI

Asamblorul utilizat permite programatorului să-şi definească propria sa secvenţă de


instrucţiuni sub forma unei macro instrucţiuni. Ulterior aceste macro instrucţiuni pot fi
utilizate asemenea instrucţiunilor obişnuite din setul de instrucţiuni al microcontrolerului. De
exemplu, codul următor defineşte un macro care permite selectarea Bank-ului de lucru cu
numărul 2.
Bank2 MACRO
MOVLW 2
MOVWF BSR
ENDM

Perechea de directive MACRO-ENDM se utilizează pentru a delimita o secţiune de cod


formată din instrucţiuni native ale microcontrolerului, care ulterior vor fi înlocuite prin apelul
macroului. Apelul coincide cu utilizarea denumirii macroului, în cazul de faţă Bank2, în
codul programului. Macrourile oferă o claritate în plus programelor întrucât chiar şi cele mai
simple seturi de instrucţiuni pot fi înlocuite cu o expresie familiară programatorului.
În limbajul C, macrourile (cunoscute şi sub denumirea de macrodefiniţii sau
macroinstrucţiuni) sunt definiţii care înlocuiesc constante, variabile sau expresii, fiind
declarate cu ajutorul directivei #define. În cadrul asamblorului considerat, macrourile sunt
secvenţe de instrucţiuni care înlocuiesc un apel al macroului.[8]

82
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Sintaxa generală utilizată pentru definirea unui macro este:


Etichetă MACRO [ARG1, ARG2, …]
[INSTRUCŢIUNE 1]
[INSTRUCŢIUNE 2]
[…]
ENDM

În exemplul prezentat anterior, macroul de selectare a Bankului 2 nu utiliza nici un fel


de operand. Asemenea instrucţiunilor obişnuite şi macrourile pot avea unul sau mai mulţi
operanzi.

Să analizăm cazul unei macro-instrucţiuni, denumită Movlf (Move literal


to file register) utilizată pentru iniţializarea directă a unui registru cu o
valoare. Deoarece o asemenea instrucţiune nu există în setul de instrucţiuni
Exemplu
al microcontrolerului, rămâne în sarcina noastră să o definim.
Astfel, macroul Movlf poate fi definit în felul următor:
Movlf MACRO Literal, Destinatie ;operanzi

PUSH ;salvare WREG & STATUS


MOVWF TOSL ;in stiva hardware
MOVFF STATUS, TOSH

MOVLW Literal ;Literal->WREG


MOVWF Destinatie ;WREG->Destinatie

MOVF TOSL,W ;restaurare WREG & STATUS


MOVFF TOSH, STATUS
POP

ENDM

Dacă programatorul ar dori să iniţializeze registrul de la adresa 0x20 cu


valoarea 0x55, atunci macroul definit anterior ar putea fi utilizat în felul
următor:
Movlf 0x55, 0x20
Deoarece instrucţiunile cuprinse în macro pot afecta regiştrii WREG şi
STATUS, iar acest lucru poate influenţa rezultatele operaţiilor din afara
macroului, macroul definit anterior este prevăzut cu câteva instrucţiuni care
salvează conţinutul regiştrilor WREG şi STATUS în stiva hardware, înainte
de a muta constanta în WREG şi apoi în registrul destinaţie. La finalul
macroului valorile celor doi regiştri sunt refăcute din stivă.

83
STRUCTURI DE PROGRAM

În exemplul prezentat anterior s-au utilizat doi operanzi pentru macro. În general
macrourile pot avea diferite grade de complexitate ce implică utilizarea mai multor parametri.
Se recomandă ca numele date macrourilor să nu fie aceleaşi cu cele ale instrucţiunilor
microcontrolerului. Dacă definirea macroului implică utilizarea unor etichete în corpul
macroului, atunci se recomandă ca acestea să fie introduse prin directiva local. În acest fel
se pot evita eventualele conflicte care ar putea apărea din cauza denumirii etichetelor din
exteriorul macroului sau din cauza mai multor apeluri ale aceluiaşi macro.
Ceea ce este specific macrourilor este faptul că fiecare apel al acestora echivalează cu
o inserare a setului de instrucţiuni din corpul macroului la adresa de apel. Folosirea acestor
structuri se pretează de regulă în situaţii în care acestea nu conţin multe instrucţiuni şi
integrarea altor structuri (cum ar fi cele cu salt) ar duce la o creştere a timpului de execuţie.
Utilizarea frecventă a macrourilor poate conduce la dificultăţi în depanarea
programelor, mai ales atunci când o simplă macro instrucţiune poate ascunde un număr de
efecte secundare asupra unor regiştri GPR şi SFR sau asupra unor biţi indicatori. Aceste
efecte pot fi reduse prin tehnici de programare cum a fost cea ilustrată în exemplul anterior,
dar nu pot fi eliminate în totalitate de fiecare dată. De exemplu, o sursă frecventă de erori
poate fi cauzată de utilizarea unor instrucţiuni de salt condiţionat peste apelul macroului:
DECFSZ CONTOR, F
My_macro
[…]
Deoarece apelul macroului este de fapt o colecţie de instrucţiuni care formează corpul
macroului, saltul de mai sus va fi de fapt în interiorul macroului, având consecinţe
neprevăzute.

Printre avantajele pe care le aduce utilizarea macrourilor în programe se pot aminti:


- creşterea clarităţii codului prin posibilitatea redenumirii unor seturi de instrucţiuni
folosind expresii familiare programatorului;
- reducerea dimensiunii codului la scriere prin definirea de macrouri pentru seturi de
instrucţiuni care se repetă;
- eficienţă ridicată la execuţia setului de instrucţiuni inclus în macro întrucât acestea
sunt inserate în cod la compilare, nefiind necesară efectuarea unui salt, sau apel de
subrutină.

Dezavantajele care rezultă din utilizarea macrourilor vizează:


- apariţia unor erori subtile de programare datorate ignorării conţinutului macroului (ex.
modificarea unor zone nedorite de memorie)

84
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

- creşterea în dimensiuni a codului compilat, deoarece fiecare apel al macroului


înlocuieşte de fapt un grup de instrucţiuni care sunt inserate la adresa de apel a
macroului la compilare.[8]

5.2 SUBRUTINE

Pentru a executa aceleaşi instrucţiuni de mai multe ori fără a recurge la reinserarea
codului, se pot folosi subrutine. În cadrul limbajelor de asamblare, subrutinele iau forma unor
instrucţiuni cuprinse între o etichetă şi o instrucţiune de revenire din subrutină.
În utilizarea subrutinelor se impune respectarea următoarelor cerinţe privind sintaxa şi
modul de utilizare:
- subrutina trebuie apelată folosind instrucţiunea CALL;
- punctul de intrare în subrutină (adresa primei instrucţiuni din subrutină) trebuie marcat
printr-o etichetă. Această etichetă va fi numele instrucţiunii.
- punctul de ieşire din subrutină trebuie să fie o instrucţiune de revenire din subrutină.
Astfel, sintaxa generală utilizată pentru definirea unei subrutine ia forma următoare:
Etichetă:
[INSTRUCŢIUNE 1]
[INSTRUCŢIUNE 2]
[…]
RETURN sau RETLW sau RETFIE

Utilizarea subrutinelor este în strânsă legătură cu stiva adreselor de revenire (vezi


Capitolul 3), iar apelul unei subrutine determină următoarea succesiune evenimente:
1. Indicatorul de stivă se incrementează;
2. Se salvează pe stivă adresa de revenire din subrutină (valoarea numărătorului de
program). Adresa de revenire reprezintă adresa instrucţiunii care urmează după
CALL;
3. Se încarcă în numărătorul de program adresa instrucţiunii marcată de eticheta
subrutinei. Această instrucţiune corespunde primei instrucţiuni a subrutinei. Se
transferă astfel execuţia către subrutină.
4. Se execută instrucţiunile din subrutină până la întâlnirea instrucţiunii RETURN
5. La execuţia instrucţiunii RETURN se stochează în numărătorul de program adresa de
revenire spre care indică indicatorul de stivă, apoi
6. Se decrementează indicatorul de stivă
7. Se execută instrucţiunile din program existente după CALL.[6,8]
85
STRUCTURI DE PROGRAM

Analizând succesiunea evenimentelor produse de apelul unei subrutine putem constata


că paşii 1 şi 2 sunt echivalenţi operaţiei PUSH, iar pasul 6 corespunde operaţiei POP (vezi
Capitolul 3).

Utilizarea subrutinelor este pusă în evidenţă în exemplul următor.


Se analizează cazul unei subrutine care iniţializează direcţia pinilor portului
B după cum urmează: pinii RB<6:0> intrări, iar pinul RB7 ieşire.
GOTO Main
Exemplu
Setare_Port:
MOVLW 0x7F
MOVWF TRISB
RETURN

Main:
[…]
CALL Setare_Port
[…]

Există situaţii în care doar salvarea numărătorului de program, asigurată în mod


automat de stiva hardware, nu este suficientă pentru revenirea programului la starea avută
înaintea apelului de subrutină sau a apelului unei subrutine de tratare a întreruperii.

Să presupunem că ne aflăm în mijlocul transferului unei constante cu


valoarea 0x55 din registrul de lucru WREG într-un registru GPR aflat la
adresa 0x20. Acest transfer se realizează din doi paşi. Dacă după primul
Exemplu
pas se face apelul subrutinei Setare_Port la adresa 0x20 se va stoca
valoarea 0x7F necesară iniţializării portului, în loc de valoarea dorită
0x55.
GOTO Main

Setare_Port:
MOVLW 0x7F ;0x7F->WREG
MOVWF TRISB ;WREG->TRISB
RETURN

Main:
MOVLW 0x55 ;0x55->WREG (pas 1)
CALL Setare_Port ;0x7F->WREG !!!
MOVWF 0x20 ;WREG->F[20h] (pas 2)

86
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Aceaşi situaţie se poate produce şi în cazul apariţiei unei întreruperi în timpul


transferului (între pasul 1 şi pasul 2) care va conduce la suspendarea programului şi la
execuţia unei rutine de tratare a întreruperii.
Pentru a rezolva această problemă, microcontrolerul PIC18F4455 este prevăzut cu o
stivă temporară cu un singur nivel (en. Fast Register Stack) în care se pot salva în mod
automat regiştrii WREG, STATUS şi BSR. Prin intermediul bitului s prezent în codul
instrucţiunilor CALL, RETURN şi RETFIE utilizatorul poate specifica dacă doreşte salvarea /
restaurarea regiştrilor respectivi.
Astfel, dacă avem o subrutină, denumită Rutina_Exemplu, în care se modifică
conţinutul registrului WREG, atunci prin utilizarea bitului s=1 (s=FAST) la apelul
instrucţiunii RETURN se va reface valoarea WREG cu cea salvată în prealabil în stiva rapidă.
Pentru ca apelul unei asemenea rutine să determine salvarea celor trei regiştri în stiva rapidă
instrucţiunea CALL va trebui să utilizeze bitul s=1.
GOTO Main

Rutina_Exemplu:
[…]
RETURN FAST ; restaurare valori salvate
; în stiva rapidă
Main:
[…]
CALL Rutina_Exemplu, FAST ; salvarea regiştrilor WREG,
[…] ; STATUS, BSR în stiva rapidă

În cazul întreruperilor, cei trei regiştri sunt salvaţi automat, însă utilizatorul poate opta
pentru restaurarea valorilor prin folosirea următoarei sintaxe a instrucţiunii de revenire din
subrutina de tratare a întreruperii:
RETFIE FAST
Existenţa stivei rapide cu un nivel permite salvarea şi refacerea contextului în cazul
existenţei unor subrutine neimbricate. În cazul subrutinelor imbricate, însă, se recomandă
salvarea manuală a acestor trei regiştri în nişte locaţii de memorie prevăzute de programator
special pentru acest lucru, iar apoi refacerea regiştrilor respectivi înainte de ieşirea din
subrutină.
Toate instrucţiunile disponibile pentru utilizarea subrutinelor şi variantele lor sunt
prezentate în Tabelul 5.1.[6,15]

87
STRUCTURI DE PROGRAM

Tabel 5.1. Instrucţiuni asociate subrutinelor


Operaţia Format instrucţiune Descriere
Apel Transferă execuţia către subrutină
de subrutină CALL n PC pus pe stivă, <n>→PC
cu revenire rapidă CALL n, 1 Idem, salvează WREG, STATUS, BSR în stiva rapidă
relativ RCALL ±offset PC pus pe stivă, PC±offset→PC
Revenire Transferă execuţia către apelant
din subrutină RETURN PC scos din stivă
rapidă din subrutină RETURN 1 Idem, restaurează WREG, STATUS, BSR din stiva
rapidă
cu literal în WREG RETLW k Idem, k în WREG
din întrerupere RETFIE Revenire cu bitul GIE (INTCON<7>) setat
din întrerupere rapid RETFIE 1 Idem, restaurează WREG, STATUS, BSR din stiva
rapidă

Utilizarea subrutinelor aduce o serie de avantaje cum ar fi:


- creşterea clarităţii codului sursă
- permite modularizarea aplicaţiilor dezvoltate
- posibilitatea execuţiei aceleiaşi secvenţe de cod din puncte diferite de program
folosind salturi, fără includerea codului, aşa cum se întâmplă în cazul macrourilor.

Ca principal dezavantaj se poate menţiona creşterea timpului de execuţie ca urmare a


efectuării celor două salturi: la adresa de început a subrutinei, respectiv la adresa de revenire.

5.3 TABLOURI

Pentru gruparea datelor în structuri denumite tablouri, se pot folosi instrucţiuni


microprocesor, instrucţiuni tabelare sau adresarea indirectă. Metoda utilizată depinde de locul
în care va fi stocat tabloul, fiind permisă stocarea datelor atât în memoria program cât şi în
memoria de date. Toate aceste metode vor fi prezentate în acest paragraf.
Majoritatea aplicaţiilor implementate pe microcontrolere utilizează pentru codul sursă
doar o parte a memoriei program disponibile. De exemplu, dacă o aplicaţie utilizează 10kByte
de cod executabil, spaţiul de memorie program rămas disponibil, 14kByte, este irosit. Există
posibilitatea, la familia de microcontrolere PIC18, de a stoca date cu caracter semi-permanent
în memoria program. În mod normal aceste date sunt scrise în memoria program în acelaşi
timp cu codul executabil. Anumite microcontrolere permit chiar scrierea datelor în memoria

88
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

program în timp ce execuţia este suspendată. Totuşi, datorită arhitecturii Harvard, care separă
complet memoria program de memoria de date, accesul la datele stocate în memoria program
nu se poate realiza prin intermediul instrucţiunilor obişnuite.
În cazul anumitor microcontrolere s-a ocolit această restricţie impusă de arhitectură
prin implementarea instrucţiunii RETLW care permite realizarea de subrutine care pot întoarce
în registrul de lucru WREG constante de opt biţi din memoria program. Această soluţie este
costisitoare din punct de vedere al memoriei utilizate deoarece fiecare constantă de opt biţi
este stocată sub forma unei instrucţiuni de 16 biţi. În plus nu există un mecanism care să
permită modificarea valorilor după ce acestea au fost programate în memorie.
A doua metodă de implementare a tablourilor în memoria program o reprezintă
utilizarea unor instrucţiuni speciale de scriere şi citire tabelară care sunt implementate la seria
de microcontrolere PIC18.
După cum s-a vazut în Capitolul 4, adresarea indirectă oferă cea de-a treia metodă de
implementare a tabelelor, aceste tabele fiind implementate în memoria RAM de date.

5.3.1 Implementarea tablourilor utilizând instrucţiuni microprocesor

Această metodă presupune stocarea valorilor tabloului în memoria program şi poate fi


folosită în situaţiile în care valorile respective nu se modifică (tablou de constante). Metoda
implică instrucţiuni de manipulare a numărătorului de program şi instrucţiunea RETLW.
Această instrucţiune este o instrucţiune de revenire din subrutină (vezi Tabel 5.1) care va
realiza în plus stocarea unei constante numerice de opt biţi, specificată prin argumentul
instrucţiunii, în registrul de lucru WREG.
Cu toate că valorile tabloului nu se pot modifica (din cauza instrucţiunii RETLW),
acestă metodă are avantajul că permite stocarea unui număr mult mai mare de valori decât ar
fi posibil prin folosirea RAM-ului.

Să analizăm cazul unei subrutine care implementează un tabel compus din


opt elemente aleatoare. Accesul la valorile tabelului se realizează indexat
folosind ca variabilă index registrul de lucru WREG. Întregul tablou
Exemplu
reprezintă un set de instrucţiuni care va fi stocat în memoria program la
inscripţionarea microcontrolerului. Ideea de bază a implementării tabelului
constă în modificarea valorii numărătorului de program pentru a se executa
instrucţiunea RETLW corespunzătoare indexului dorit

89
STRUCTURI DE PROGRAM

TEMP EQU 0x00

GOTO Main

Tabel:
ADDWF WREG,W ;WREG=index+index
MOVFF PCL,TEMP ;PCL→TEMP,PCH→PCLATH,PCU→PCLATU
ADDWF PCL, F ;PCL+2*index→PCL
RETLW d’101’ ;index 0
RETLW d’115’ ;index 1
RETLW d’90’ ;index 2
RETLW d’83’ ;index 3
RETLW d’85’ ;…
RETLW d’99’
RETLW d’150’
RETLW d’149’

Main:
[…]
MOVLW d’3’ ;accesarea valorii cu indexul 3
CALL Tabel ;WREG=83
[…]

În cazul subrutinei Tabel prima instruţiune ADDWF WREG,W are rolul de


a dubla valoarea indexului, care este justificată de cei 2 octeţi necesari
pentru reprezentarea instrucţiunii RETLW în memoria program. Astfel
pentru a returna valoarea de la un anumit index, mai întâi indexul respectiv
este dublat, după care rezultatul este adunat la numărătorul de program.
Instrucţiunea care se va executa după ADDWF PCL,F va avea adresa
PC+Index*2, unde PC conţine adresa primei instrucţiuni RETLW.
Prezenţa instrucţiunii MOVFF PCL,TEMP are doar rolul de a efectua o
citire a PCL pentru a produce transferul conţinutului PCH şi PCU în regiştrii
tampon asociaţi (PCLATH, PCALTU) pentru iniţializarea acestora. Acest
lucru este necesar deoarece operaţia ADDWF PCL, F va determina
transferul invers (regiştri tampon → PC), iar dacă regiştrii tampon nu au
fost în prealabil iniţializaţi atunci se pot realiza salturi neprevăzute în
memorie.[8]

Deşi este corectă, această variantă de implementare a tablourilor trebuie folosită cu


precauţie şi avut grijă la dimensiunea tabloului şi la adresa sa de început a acestuia în
memoria program, deoarece modificarea valorii PCL pentru a accesa instrucţiunea RETLW
corespunzătoare indexului dorit nu se răsfrânge şi asupra celorlalţi doi regiştri ai

90
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

numărătorului de program. Astfel, depăşirea cu o unitate a valorii maxime a PCL nu conduce


la incrementarea automată a valorii registrului superior PCH, respectiv PCU.
O variantă mai completă a implementării aceluiaşi tablou se prezintă în exemplul
următor.
Să analizăm cazul unei subrutine care implementează acelaşi tabel compus
din opt elemente. Accesul la valorile tabelului se realizează indexat prin
intermediul registrului de lucru WREG. Ideea de bază a implementării
Exemplu
tabelului constă în modificarea valorii numărătorului de program pentru a se
executa instrucţiunea RETLW corespunzătoare indexului dorit. Se asigură
modificarea corectă a tuturor celor trei regiştri ai numărătorului de program.

TEMP EQU 0x00

GOTO Main

Tabel:
ADDWF WREG,W ;WREG=index+index
MOVFF PCL,TEMP ;PCL→TEMP,PCH→PCLATH,PCU→PCLATU
ADDLW d’16’ ;16+2*index
ADDWF TEMP,F ;TEMP=TEMP+16+2*index
MOVLW 0 ;PCLATH++ dacă e cazul
ADDWFC PCLATH,F
MOVLW 0 ;PCLATU++ dacă e cazul
ADDWFC PCLATU,F
MOVFF TEMP,PCL ;TEMP→PCL,PCLATH→PCH,PCLATU→PCU
RETLW d’101’ ;index 0
RETLW d’115’ ;index 1
RETLW d’90’ ;index 2
RETLW d’83’ ;index 3
RETLW d’85’ ;…
RETLW d’99’
RETLW d’150’
RETLW d’149’

Main:
[…]
MOVLW d’3’ ;accesarea valorii cu indexul 3
CALL Tabel ;WREG=83
[…]

În cazul acestei variante a subrutinei Tabel este necesar un salt calculat


peste 16 adrese de memorie program pentru a accesa prima instrucţiune
RETLW corespunzătoare indexului 0. Cele 16 adrese sunt ocupate de 6
instrucţiuni scurte şi o instrucţiune lungă în care se realizeză incrementarea
prin bitul de transport a regiştrilor PCLATH şi PCLATU, şi actualizarea PC.

91
STRUCTURI DE PROGRAM

5.3.2 Implementarea tablourilor utilizând instrucţiuni dedicate

O altă variantă de implementare a tablourilor în memoria program o reprezintă


folosirea instrucţiunilor tabelare ale microcontrolerelor PIC18. Acestea oferă posibilitatea
citirii memoriei program octet cu octet şi scrierea acesteia prin blocuri de minim 32 de octeţi.
Astfel, pentru a citi şi scrie memoria program sunt prevăzute două operaţii care permit
procesorului să mute octeţi între memoria program şi memoria de date RAM:
• Citirea tabelară: TBLRD
• Scrierea tabelară: TBLWT
Operaţiile de scriere şi citire mută datele între cele două spaţii de memorie la nivel de
octet prin intermediul unui registru de 8 biţi (TABLAT) mapat în zona SFR a memoriei RAM
de date.
Registrul folosit pentru adresarea octeţilor din memoria program este TBLPTR (en.
Table Pointer register). Întrucât capacitatea de adresare a memoriei program este de până la
2MByte pentru a putea forma adresa de 21 de biţi necesară adresării fiecărui octet, TBLPTR
este format din trei regiştri speciali: Table Pointer Upper Byte, Table Pointer High Byte,
Table Pointer Low Byte (TBLPTRU:TBLPTRH:TBLPTRL)
Aceşti regiştri sunt utilizaţi de instrucţiunile TBLRD şi TBLWT pentru accesarea
datelor din memoria program. Operaţiile de citire tabelară extrag datele din memoria program
şi le plasează în memoria de date RAM (Fig. 5.1). În registrul special de 8 biţi TABLAT se
transferă un octet din memoria program la execuţia unei instrucţiuni de citire tabelară. Adresa
octetului citit trebuie introdusă în prealabil în TBLPTR prin intermediul celor 3 regiştri de
adresă.

Fig.5.1. Citirea tabelară. Utilizarea instrucţiunii TBLRD*

Operaţia de scriere tabelară realizează transferul de date între memoria de date RAM şi
memoria program prin blocuri de minim de 32 de octeţi. Aceste operaţii sunt folosite intern
pentru a incărca o serie de regiştri necesari programării memoriei Flash. Deoarece, registrul

92
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

TABLAT are dimensiunea de un octet, instrucţiunea TBLWT va trebui executată de 32 de ori


pentru fiecare operaţie de programare a memoriei. Având în vedere faptul că operaţia de
scriere tabelară dispune de un grad mai ridicat de complexitate se recomandă cititorului să
consulte documentaţia tehnică (foaia de catalog) a microcontrolerului PIC18F4455, secţiunea
6.5 Writing to Program Flash Memory.
Instrucţiunile tabelare TBLRD şi TBLWT oferă şi posibilitatea modificării automate a
regiştrilor de adresare TBLPTR printr-o singură instrucţiune. Formele acestor instrucţiuni şi
operaţiile asociate se prezintă în Tabelul 5.2.[6,15]

Tabel 5.2. Instrucţiuni tabelare


Operaţia Instrucţiune Descriere
Citire tabelară Citeşte în TABLAT octetul din memoria program de la adresa
stocată înTBLPTR
TBLPTR nemodificat TBLRD* <TBLPTR>→[TABLAT]
TBLPTR post incrementat TBLRD*+ <TBLPTR>→[TABLAT], TBLPTR++
TBLPTR post decrementat TBLRD*- <TBLPTR>→[TABLAT], TBLPTR--
TBLPTR pre incrementat TBLRD+* TBLPTR++, <TBLPTR>→[TABLAT]
Scriere tabelară Scrie în memoria program de la adresa stocată în TBLPTR
octetul din TABLAT
TBLPTR nemodificat TBLWT* [TABLAT]→<TBLPTR>
TBLPTR post incrementat TBLWT*+ [TABLAT]→<TBLPTR>, TBLPTR++
TBLPTR post decrementat TBLWT*- [TABLAT]→<TBLPTR>, TBLPTR--
TBLPTR pre incrementat TBLWT+* TBLPTR++, [TABLAT]→<TBLPTR>

Se consideră stocarea unei secvenţe de biţi în memoria program şi citirea


aceasteia folosind instrucţiunea TBLRD*.[8]
O asemenea aplicaţie necesită încărcarea unui tabel în memoria program.
Exemplu
Acest lucru se realizează cu ajutorul directivei db (Data Byte) urmată de o
secvenţă de octeţi care definesc elementele tabloului.
Imediat după tablou urmează codul executabil. Subrutina Init_Adresa
nu face altceva decât să copieze în TBLPTR adresa de început a tabelului.
Se poate observa utilizarea celor trei operatori low, high şi upper pentru
extragerea octeţilor corespunzători ai adresei marcate de eticheta Tablou.
Ulterior elementele tabloului pot fi accesate pe rând folosind
postincrementarea sau se poate specifica o secţiune de cod care permite
citirea valorii de pe o anumită poziţie a tabloului.

93
STRUCTURI DE PROGRAM

; stocarea şirului de valori


Tablou:
db 0x12, 0x13, 0x90, 0x20, 0x18, 0x23, 0x11

; Rutină de iniţializare a regiştrilor de adresare


Init_Adresa:
MOVLW low Tablou
MOVWF TBLPTRL
MOVLW high Tablou
MOVWF TBLPTRH
MOVLW upper Tablou
MOVWF TBLPTRU
RETURN

; Apelul rutinei de iniţializare


CALL Init_Adresa

; Accesarea elementelor folosind postincrementarea


TBLRD*+
MOVF TABLAT, W

; Accesul la elementul de la indexul 3


MOVLW d’3’
ADDWF TBLPTRL, F
MOVLW d’0’
ADDWFC TBLTRH, F
MOVLW d’0’
ADDWFC TBLTRU, F
TBLRD*
MOVF TABLAT, W

Dacă se modifică „manual” valorile din regiştrii de adresă trebuie avut grijă
la depăşirea valorii 255, când trebuie modificat şi registrul imediat superior.
Acest lucru se poate vedea în secţiunea de cod corespunzătoare accesului la
elementul cu indexul 3 al tabelului unde s-a realizat incrementarea prin bitul
de transport a regiştrilor TBLPTRH şi TBLPTRU.

Cu ajutorul instrucţiunilor de scriere şi citire tabelară, utilizatorul poate construi


aplicaţii de tip „Boot-loader” sau poate implementa tablouri modificabile a căror dimensiune
este limitată doar de dimensiunea memoriei program.[8]

94
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

5.3.3 Implementarea tablourilor utilizând adresarea indirectă

Adresarea indirectă oferă posibilitatea accesării unei locaţii de memorie RAM fără
precizarea unei adrese fixe în instrucţiune. Folosind această metodă, se pot implementa
tablouri de variabile, ce pot fi modificate pe parcursul execuţiei programului (prin folosirea
RAM-ului ca zonă de stocare).
Microcontrolerele PIC fac posibilă adresarea indirectă prin implementarea unui set de
regiştrii speciali de adresare FSRn (en. File Select Register) şi a unor regiştri de accesare a
conţinutului INDFn (en. Indirect File Operands) de la adresa stocată în FSR. De asemenea,
patru operanzi adiţionali implementaţi sub forma regiştrilor virtuali POSTINCn, POSTDECn,
PREINCn şi PLUSWn permit realizarea unei adresări indexate utilă la accesarea şi
parcurgerea elementelor unui tablou. (pentru detalii suplimentare vezi Capitolul 4)

Se consideră implementarea unui tablou cu opt elemente în memoria RAM


de date folosind adresarea indirectă.
În acest scop se construieşte subrutina Stocare_Valori utilizată pentru
Exemplu
stocarea valorilor tabloului în memorie. Aceste valori vor fi accesate prin
rutina de returnare a unei valori Return_Valoare de pe o anumită
poziţie a tabelului. Indexul valorii dorite trebuie încărcat în registrul de
lucru WREG, rezultatul fiind returnat tot în acest registru.[8]

GOTO Main

Stocare_Valori: ; stocarea valorilor


LFSR FSR0, 0x200
MOVLW d’101’
MOVWF POSTINC0
MOVLW d’115’
MOVWF POSTINC0
MOVLW d’90’
MOVWF POSTINC0
MOVLW d’83’
MOVWF POSTINC0
MOVLW d’85’
MOVWF POSTINC0
MOVLW d’99’
MOVWF POSTINC0
MOVLW d’150’
MOVWF POSTINC0
MOVLW d’149’
MOVWF POSTINC0
RETURN

95
STRUCTURI DE PROGRAM

Return_Valoare: ; returnarea valorii


LFSR FSR1,0x200
ADDWF FSR1L, F
MOVLW d’0’
ADDWFC FSR1H, F
MOVF INDF1, W
RETURN

Main:
[…]
CALL Stocare_Valori

; accesarea valorii cu indexul 3


MOVLW d’3’
CALL Return_Valoare ;WREG=83

[…]

Macrourile şi subrutinele reprezintă soluţii utile în ceea ce priveşte


structurarea codului în scopul realizării unor programe scalabile şi uşor

Concluzii lizibile. Datele, la rândul lor, pot fi şi ele structurate sub forma unor
tablouri în memoria program sau în memoria RAM de date.
Acest capitol, foarte orientat spre exemple, a prezentat diferite variante de
implementare ale acestor structuri de program în limbaj de asamblare.

1. Discutaţi modul de utilizare al stivei hardware pentru salvarea


regiştrilor WREG şi STATUS.
2. Ce alte soluţii aţi putea găsi pentru salvarea contextului?
Întrebări de
3. Care este principiul de funcţionare al instrucţiunii RETLW?
autoevaluare
Daţi un exemplu de utilizare al acestei instrucţiuni.
4. Care este diferenţa între macrouri şi subrutine?
5. Cum se implementează un tabel în memoria program, dacă se
doreşte accesul la elementele sale cu instrucţiunea TBLRD*.
6. Scrieţi un macro care realizează adunarea a două valori numerice
stocate în prealabil la adresele 0x00 şi 0x01 în memorie şi pune
rezultatul în registrul de lucru.
7. Scrieţi o subrutină care realizează adunarea a două valori numerice
stocate în prealabil la adresele 0x00 şi 0x01 în memorie şi pune

96
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

rezultatul în registrul de lucru.


8. Ce diferenţe există între cele două metode de implementare a
tablourilor în memoria program?
9. Cum se realizează citirea tabelară?

Adresare indirectă
Metoda de adresare în care accesul la locaţiile din memoria de date RAM
Termeni se face fără a utiliza o adresă fixă în instrucţiuni
esenţiali Directivă
Pseudo-instrucţiune adresată asamblorului
FSR
File Select Register. Registru de adresare. Conţine o adresă absolută (12
biţi) din memorie. Este format din FSR0H:FSR0L
GPR
General Purpose Registers. Regiştri de uz general
INDF
Indirect File Operand. Registru de accesare conţinut. Permite accesul la
data stocată în memorie la adresa conţinută în FSR.
Macro
Secţiune de cod formată din instrucţiuni native ale microcontrolerului,
care ulterior vor fi înlocuite prin apelul macroului
Memorie de date
Spaţiu de stocare temporar (RAM) pentru datele cu care lucrează
programul
Memorie program
Spaţiu de stocare pentru program
PC
Program Counter. Numărător de program. Conţine adresa instrucţiunii
următoare din memorie. Are dimensiunea de 8 biţi şi poate fi accesat prin
intermediul regiştrilor PCL, PCLATH şi PCLATU
SFR
Special Function Registers. Regiştri speciali
Stiva rapidă
Spaţiu de stocare temporar, care nu poate fi accesat direct, utilizat pentru

97
STRUCTURI DE PROGRAM

salvarea regiştrilor WREG, STATUS şi BSR la apelul de subrutine sau


rutine de tratare a întreruperilor
Stiva hardware
Stiva adreselor de revenire. Spaţiu de memorie în care se salvează
adresele de revenire în cazul apelurilor de subrutină
Subrutină
Structură de organizare a programelor care ia forma unor instrucţiuni
cuprinse între o etichetă şi o instrucţiune de revenire din subrutină.
Unitate independentă de program, plasată în memorie în altă zonă decât
programul principal
TABLAT
Registrul folosit pentru accesul la octetul de date din memoria program a
cărui adresă este stocată în TBLPTR
Tablou
O colecţie de date de acelaşi tip aranjate continuu în memorie
TBLPTR
Registrul folosit pentru adresarea octeţilor de date din memoria program.
Este format din trei octeţi stocaţi în TBLPTRU:TBLPTRH:TBLPTRL
TOS
Top of stack. Regiştrii de la vârful stivei (TOSU:TOSH:TOSL) care
conţin imaginea datelor din stivă spre care indică indicatorul de stivă

98
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

6. PORTURI DE INTRARE-IEŞIRE

Introducere
Obiective
6.1 STRUCTURA GENERALĂ A PORTURILOR
Cuprins
6.1.1 Preliminarii
6.1.2 Implementarea hardware a porturilor
6.1.3 Iniţializarea porturilor
6.2 CONECTAREA CIRCUITELOR EXTERNE
6.3 APLICAŢII
6.3.1 Implementarea unui program de test al
butoanelor
6.3.2 Implementarea unui protocol Handshake
6.3.3 Comanda unui afişaj cu 7 segmente şi 4 digiţi
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

99
PORTURI DE INTRARE-IEŞIRE

Microcontrolerele nu şi-ar justifica existenţa dacă nu ar oferi posibilitatea


de a modifica sau monitoriza, prin intermediul programului implementat,
starea pinilor conectaţi la diferite circuite din lumea exterioară. Aceşti pini
Introducere
de intrare-ieşire sunt de obicei dispuşi în grupuri având dimensiunea
maximă egală cu dimensiunea magistralei interne de date. La familia de
microcontrolere PIC18 porturile paralele de intrare-ieşire permit ca un
număr de până la 8 biţi de date externi să poată fi citiţi sau scrişi simultan.
Numărul total al acestor linii de date paralele diferă de la un
microcontroler la altul, în cazul PIC18F4455 fiind disponibili 34 de pini
de intrare-ieşire din totalul de 40 de pini ai capsulei.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă principiul de funcţionare al porturilor paralele de
intrare-ieşire ale microcontrolerului;
Obiective - să poată configura porturile;
- să înţeleagă structura porturilor de intrare-ieşire;
- să poată realiza aplicaţii care utilizează porturile de intrare-ieşire.

6.1 STRUCTURA GENERALĂ A PORTURILOR

6.1.1 Preliminarii

Porturile de intrare-ieşire ale unui microcontroler reprezintă legătura cu lumea


exterioară prin care acesta poate să trimită sau să primească date.
Microcontrolerul PIC18F4455 (Fig. 6.1) are 5 porturi de intrare-ieşire (notate cu A, B,
C, D şi E) fiecare pin al acestora fiind multiplexat cu mai multe funcţionalităţi. De exemplu,
pinul 2 al microcontrolerului (RA0/AN0) poate fi pin de intrare-ieşire digital, bitul 0 al
portului A (RA0) sau pin de intrare analogic, reprezentând canalul 0 al convertorului analog
digital (AN0). În general, dacă se foloseşte un periferic atunci pinii corespunzători acestuia nu
pot fi utilizaţi ca pini de intrare-ieşire digitali.

100
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 6.1. Pinii şi porturile microcontrolerului PIC18F4455 conform foii de catalog [15]

Numărul de biţi disponibil în porturile microcontrolerului PIC18F4455 şi denumirea


pinilor asociaţi se prezintă în Tabelul 6.1
Tabel 6.1.Porturile microcontrolerului PIC18F4455 şi pinii asociaţi
Portul Nr biţi disponibili Denumire pini
PORTA 7 RA[6:0]
PORTB 8 RB[7:0]
PORTC 7 RC[7:4], RC[2:0]
PORTD 8 RD[7:0]
PORTE 4 RE[3:0]

În mod normal porturile de intrare-ieşire ar trebui să se comporte asemenea unor


regiştri al căror conţinut poate fi vizibil şi accesat din lumea exterioară. Totuşi, porturile de
intrare-ieşire sunt puţin diferite faţă de regiştrii interni. De exemplu, fiecare bit al portului
paralel poate fi configurat individual pentru a reflecta starea fizică a pinului sau pentru a pune
pe 1 sau 0 logic pinul asociat. Altfel spus, fiecare pin poate fi configurat ca pin de intrare, care
poate fi citit sau pin de ieşire care poate fi scris.
Astfel, fiecare port n={A,B,C,D,E} are trei regiştri folosiţi pentru configurarea şi
manipularea lui:
- registrul TRISn (de configurare a direcţiei portului)
- registrul PORTn (de citire a stării pinilor microcontrolerului)
- registrul LATn (de scriere a datelor pe port)
Fiecare bit al portului are echivalent un bit în registrul TRIS prin care se poate
configura direcţia individuală a pinului asociat. Astfel, un bit egal cu 0 în registrul TRIS va
seta pinul corespunzător pe ieşire, iar un bit egal cu 1 va seta pinul corespunzător pe intrare.

101
PORTURI DE INTRARE-IEŞIRE

Să considerăm o situaţie în care pinul RA0 şi pinii RB[7:0] sunt ieşiri, iar
restul de pini ai portului A sunt intrări. Următoarea subrutină realizează
configurarea direcţiei pinilor utilizaţi.
Exemplu

Initializare
MOVLW b’1111110’ ;RA0 ieşire
MOVWF TRISA ;RA[1:7] intrări
CLRF TRISB ;RB[0:7] ieşiri
RETURN

Orice resetare a microcontrolerului va conduce la setarea tuturor biţilor din regiştrii


TRIS. Altfel spus, în urma resetării toţi pinii microcontrolerului vor fi pini de intrare. Această
configuraţie se poate explica prin faptul că în situaţia în care un pin ar fi de ieşire înainte ca
programul să-l iniţializeze cu această stare, atunci acest pin ar putea ieşi din starea de reset
având o tensiune neprevăzută care ar putea acţiona diferite circuite conectate la
microcontroler într-un mod nedorit.
Odată realizată configurarea direcţiei porturilor utilizate, se poate efectua citirea sau
scrierea datelor într-o manieră similară accesului la regiştrii interni, realizându-se în acest fel
interacţiunea cu mediul exterior. Astfel,
- pentru a monitoriza / citi starea oricărui pin configurat ca intrare se pot folosi
instrucţiunile BTFSC sau BTFSS. De exemplu, BTFSS PORTB,1 sare peste
instrucţiunea următoare dacă pinul RB1 este în stare logică 1. Pentru a citi simultan
starea mai multor pini se poate copia conţinutul registrului PORT în WREG (ex. MOVF
PORTB, W) sau într-un registru de uz general pentru procesări suplimentare (MOVFF
PORTB, 0x00)
- pentru a modifica / scrie starea oricărui pin configurat ca ieşire se pot utiliza
instrucţiunile pe bit BCF, BSF sau BTG. De exemplu, BCF LATA, 2 va aduce starea
pinului RA2 pe 0 logic. De asemenea, există posibilitatea de a modifica simultan
starea mai multor pini prin copierea conţinutului unui registru oarecare în registrul
LAT corespunzător. De exemplu, dacă toţi pinii portului B sunt pini de ieşire atunci
instrucţiunile următoare: MOVLW b’1111000’: MOVWF LATB vor seta pinii
RB[7:4] şi vor reseta pinii RB[3:0].

102
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

6.1.2 Implementarea hardware a porturilor

Pentru a înţelege modul de funcţionare al porturilor de intrare-ieşire vom analiza în


continuare implementarea hardware a acestora. În Fig. 6.2 se prezintă structura simplificată a
unui singur bit al unui port de intrare-ieşire.[15] În figură se evidenţiază trei componente
majore care intervin în structura portului: bistabilul D pentru date, bistabilul TRIS care
comandă circuitul tristate (2) şi latch-ul de intrare.

Fig. 6.2. Implementarea hardware a unei linii a unui port de intrare-ieşire

Bistabilul D reprezintă celula elementară de memorie. Scrierea datelor pe port va


încărca bistabilul D cu data disponibilă pe magistrală. Acesta va menţine datele cât timp
microcontrolerul este alimentat sau până la suprascrierea acestora cu date noi.
De exemplu:
MOVLW b‘11110000’
MOVWF LATB
va încărca cele patru bistabile superioare ale registrului cu 1, iar cele patru bistabile inferioare
cu 0. Încărcarea acestor bistabile cu date se va realiza indiferent de modul în care este
configurat pinul, ca intrare sau ieşire. Pentru ca datele din bistabil să se regăsească pe pin,

103
PORTURI DE INTRARE-IEŞIRE

circuitul tristate (2) aflat la ieşirea bistabilului trebuie activat. În această situaţie (Fig. 6.3-b),
ieşirea bistabilului este conectată direct la lumea exterioară prin intermediul pinului, care
acum este pin de ieşire. Pentru a activa circuitul tristate (2), bistabilul D TRIS trebuie
încărcat în prealabil cu valoarea 0.
Citirea stării pinului se poate realiza prin intermediul latch-ului de date inferior a cărui
ieşire reflectă starea fizică a pinului. La execuţia unei comenzi de citire a portului, intrarea EN
a acestui latch este 0, bitul citit este menţinut la ieşirea circuitului tristate (4) pe durata citirii.
Această citire nu este influenţată de direcţia pinului (Fig. 6.3-a,c).
Din Fig. 6.2 se poate observa că bitul TRIS poate fi scris şi citit. Chiar dacă citirea
registrului TRIS este aparent nejustificată să considerăm cazul în care utilizatorul doreşte să
configureze direcţia unui pin. Pentru acest lucru se poate utiliza instrucţiunea:
BCF TRISB,2 ;şterge bitul 2 al registrului TRISB
Instrucţiunea BCF (Bit Clear File) este un exemplu de instrucţiune care realizează operaţiile
de citire-modificare-sciere, prin care starea registrului TRISB este mai întâi citită în UCP,
apoi modificată şi în cele din urmă scrisă înapoi în TRISB (vezi capitolul 1, fazele
instrucţiunilor). Pentru a putea realiza acest lucru, UCP trebuie să aibă posibilitatea de a
accesa registrul TRIS atât pentru scriere cât şi pentru citire. Acest lucru este valabil şi pentru
alte instrucţiuni. De fapt, majoritatea instrucţiunilor (ex. MOVWF) realizează un microciclu de
citire în Q2, înaintea operaţiei efective de scriere din Q4.
Pentru a evita problemele ce pot apărea din citirea stării fizice a pinilor,
microcontrolerele din seria PIC18 au introdus un circuit tristate suplimentar (1), asociat
bistabilului D de date, care permite UCP să realizeze direct citirea biţilor de date ca o
alternativă la citirea stării pinilor. Astfel, scrierea datelor în registrul LATn este echivalentă cu
scrierea datelor în registrul PORTn, iar citirea LATn va furniza datele stocate în registrul de
date, care de cele mai multe ori vor fi identice cu datele privind starea fizica a pinilor.
Deoarece pinii unui port pot fi configuraţi ca intrări, ieşiri sau combinaţii de intrări şi
ieşiri, este interesant de ştiut ce se întâmplă atunci când se citesc sau se scriu regiştrii
implicaţi. De exemplu, ce s-ar întâmpla dacă se realizează din program citirea unui port de
ieşire? Cele patru situaţii prezentate în Fig. 6.3 sunt descrise în continuare:
a. Citirea unui port de intrare (TRIS = 1)
În această situaţie circuitul tristate (2) este dezactivat, iar starea bistabilului de date
rămâne neschimbată. De exemplu, instrucţiunea MOVF PORTB, W citeşte starea
pinilor portului B în registrul de lucru WREG.

104
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

b. Scrierea la un port de ieşire (TRIS = 0)


În acest caz circuitul tristate (2) este activat, iar conţinutul bistabilului de date este
modificat ca urmare a operaţiei de scriere. Ieşirea bistabilului D este reflectată şi în
starea pinului de ieşire. De exemplu, dacă toţi pinii portului B sunt configuraţi ca
ieşiri, atunci MOVLW 0x01: MOVWF LATB va aduce pinul RB0 în stare logică 1,
ceilalţi pini RB[7:1] fiind în stare logică 0
c. Citirea unui port de ieşire (TRIS = 0)
În acest caz circuitul tristate (2) este activat, iar pinul de ieşire reflectă starea ieşirii
bistabilului de date. Prin citire se va realiza copierea efectivă a valorii de la ieşirea
bistabilului de date în UCP.
d. Scrierea la un port de intrare (TRIS = 1)
În această situaţie se realizează modificarea conţinutului bistabilului de date. Totuşi,
datele din bistabil nu vor fi puse pe pin până la schimbarea direcţiei pinului.[6]

Fig. 6.3. Citirea şi scrierea unui bit al unui port conectat la un pin de intrare sau de ieşire

105
PORTURI DE INTRARE-IEŞIRE

6.1.3 Iniţializarea porturilor

Înainte de a utiliza porturile pentru operaţii de intrare-ieşire acestea trebuie iniţializate.


Iniţializarea presupune următoarele etape:
- Ştergerea regiştrilor de date PORTn şi LATn pentru a elimina datele „reziduale” care
s-ar putea găsi acolo – pentru porturile A, B, C, D şi E;
- Configurarea pinilor ca pini digitali de intrare-ieşire de uz general în registrul
ADCON1 al convertorului Analog/Digital – pentru porturile A, B şi E. Pinii acestor
porturi sunt multiplexaţi cu convertorul Analog/Digital
- Oprirea comparatoarelor prin configurarea registrului CMCON – pentru portul A;
- Configurarea direcţiei pinilor, prin intermediul regiştrilor TRISn – pentru porturile
A, B, C, D şi E.
Cele patru etape de iniţializare de mai sus sunt puse în evidenţă în exemplul următor

Se consideră o secţiune de cod care realizează iniţializarea portului A.

CLRF PORTA ;ştergerea reg. PORTA


Exemplu
CLRF LATA ;ştergerea reg. LATA

MOVLW 0x0F ;Configurare convertor A/D


MOVWF ADCON1 ;pt. pini I/O digitali

MOVLW 07h ;Oprire comparatoare


MOVWF CMCON
MOVLW B’11111100’ ;pinii RA[7:2] intrari
MOVWF TRISA ;şi RA[1:0] ieşiri

6.2 CONECTAREA CIRCUITELOR EXTERNE

Pentru conectarea butoanelor, a LED-uri, dar şi a altor componente externe la un


microcontroler, trebuie respectate cu stricteţe limitele curenţilor de intrare şi ieşire ale
microcontrolerului (Tabelul 6.2) precum şi cele asociate componentelor externe.
Nerespectarea limitelor impuse poate conduce la arderea pinilor sau chiar a porturilor precum
şi la arderea componentelor externe.

106
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Tabel 6.2. Caracteristici electrice ale porturilor [8,15]


Caracteristica Valoare [mA]
Curentul maxim de ieşire pe Vss 300
Curentul maxim de intrare pe Vdd 250
Curentul maxim de intrare pe pinul oricărui port 25
Curentul maxim de ieşire pe pinul oricărui port 25
Curentul maxim de intrare pe toate porturile 200
Curentul maxim de ieşire pe toate porturile 200

În cele ce urmează se prezintă câteva exemple de conectare a unor circuite externe la


microcontroler.

a. Conectarea butoanelor b. Conectarea LED-urilor

Fig. 6.4. Conectarea butoanelor (a întrerupătoarelor) şi a LED-urilor cu consum mai mic de 20mA

Pentru conectarea unor LED-uri la microcontroler trebuie respectate specificaţiile


electrice ale acestora. Câteva dintre caracteristicile LED-urilor sunt prezentate în Tabelul 6.3.

Tabel 6.3. Caracteristicile principale ale LED-urilor [8]


Culoare Lungimea de undă Materialul de Tensiunea de Intensitatea
coresp. intensităţii bază deschidere la luminousă la
luminoase maxime 10mA 10mA
[nm] [V] [m cd]
Infraroşu 900 Galiu-Arseniu 1.3-1.5
Roşu 655 Galiu-Arseniu-Fosfor 1.6-1.8 0.4-1.0
Roşu deschis 635 Galiu-Arseniu-Fosfor 2.0-2.2 2.0-4.0
Galben 583 Galiu-Arseniu-Fosfor 2.0-2.2 1.0-3.0
Verde 565 Galiu-Fosfor 2.2-2.4 0.5-3.0
Albastru 490 Galiu-Fosfor 3.0-5.0 0.5-2.0

După cum se vede şi din Fig. 6.4-b nu se recomandă conectarea directă a LED-urilor
la microcontroler, ci prin intermediul unei rezistenţe. Dacă se iau în considerare datele din

107
PORTURI DE INTRARE-IEŞIRE

Tabelul 6.3, pentru un LED având tensiunea de deschidere de 2V la un curent de 10mA,


5−2
valoarea rezistenţei se calculează în felul următor: = 300Ω .
10 ×10−3
Pentru conectarea unor LED-uri cu un consum mai mare de 20mA se recomandă
utilizarea schemei din Fig. 6.5.

Fig. 6.5. Conectarea LED-urilor cu consum mai mare de 20mA

Numeroase aplicaţii pentru microcontrolere necesită activarea sau dezactivarea unor


circuite de putere. Acest lucru se realizează de multe ori cu ajutorul releelor. Pentru a realiza
comanda unui releu cu ajutorul unui microcontroler se poate utiliza schema din Fig. 6.6.

Fig. 6.6. Schema de comandă a unui releu

În ciuda utilizării tot mai frecvente a afişajelor cu cristale lichide, afişajele cu şapte
segmente nu au dispărut din practică acestea având încă multiple utilizări mai ales în aplicaţii
care necesită afişarea unor valori numerice, aceste module fiind foarte eficiente în condiţii de
iluminare scăzută sau atunci când se doresc afişaje de dimensiuni mari. Afişajele cu şapte

108
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

segmente sunt în esenţă afişaje cu LED-uri, fiecare segment fiind reprezentat de un LED, şi
sunt disponibile în două variante de implementare: cu anod comun, respectiv cu catod comun.
Dispunerea segmentelor şi cele două variante de implementare se prezintă în Fig. 6.7.

Fig. 6.7. Afişaj cu şapte segmente

În cazul utilizării unor afişaje multiplexate cu şapte segmente cu patru digiţi se pot
utiliza următoarele scheme de conectare la microcontroler (Fig. 6.8 – anod comun, Fig.6.9 –
catod comun). Liniile de date (a,b,c,..g,dp) fiind comune pentru toate cele patru afişaje, prin
multiplexare se asigură comanda succesivă a fiecărui afişaj. Practic, la un moment dat doar un
afişaj este comandat. Prin baleerea de la un afişaj la altul cu o frecvenţă suficient de mare se
crează impresia că toate cele patru cifre sunt afişate simultan. În paragraful 6.3.3 se va
prezenta un exemplu de aplicaţie care realizează comanda acestui tip de afişaje.

Fig.6.8. Conectarea unui afişaj multiplexat de 7 segmente cu anod comun de 4 digiţi

109
PORTURI DE INTRARE-IEŞIRE

Fig. 6.9. Conectarea unui afişaj multiplexat de 7 segmente cu catod comun de 4 digiţi

6.3 APLICAŢII

6.3.1 Implementarea unui program de test al butoanelor

În cele ce urmează se va prezenta schema electrică de conectare (Fig. 6.10), diagrama


de activitate (Fig. 6.11) şi implementarea unui simplu program care testează apăsarea a două
butoane, conectate pe pinii RD0 şi RD1. Dacă butoanele sunt apăsate, se vor aprinde LED-
urile corespunzătoare (pentru butonul de pe RD0 se va aprinde LED-ul conectat pe RD2, iar
pentru butonul de pe RD1 se va aprinde LED-ul conectat pe pinul RD3).[8]

Fig. 6.10. Schema electrică de conectare

110
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Conform montajului din Fig. 6.10, la apăsarea unui buton se va citi pe port valorea 0
logic, iar atunci când butonul este eliberat se citeşte valoarea 1 logic. LED-urile se vor aprinde
prin setarea bitului corespunzător.

Fig. 6.11. Diagrama de activiate

LIST P=18F4455 ;definire tip procesor


#include <P18F4455.INC> ;definire variabile procesor

ORG 0x800 ;Adresa de reset

;Programul principal

Initializare_port:
CLRF PORTD ;ştergere buffere
CLRF LATD

MOVLW b'00000011' ;configurare direcţie pini


MOVWF TRISD ;RD0, RD1 – intrări
;RD2, RD3 – ieşiri

Test_buton1:
BTFSS PORTD, 0 ;test buton legat pe pinul RD0
GOTO Buton1_apasat
GOTO Buton1_eliberat

111
PORTURI DE INTRARE-IEŞIRE

Test_buton2:
BTFSS PORTD, 1 ;test buton legat pe pinul RD1
GOTO Buton2_apasat
GOTO Buton2_eliberat

Buton1_apasat:
BSF LATD, 2 ;aprinde LED conectat la RD2
GOTO Test_buton2

Buton1_eliberat:
BCF LATD, 2 ;stinge LED conectat la RD2
GOTO Test_buton2

Buton2_apasat:
BSF LATD, 3 ;aprinde LED conectat la RD3
GOTO Test_buton1

Buton2_eliberat:
BCF LATD, 3 ;stinge LED conectat la RD3
GOTO Test_buton1

END ;sfârşitul programului

6.3.2 Implementarea unui protocol Handshake

Să considerăm cazul unei aplicaţii în care un echipament periferic extern solicită


microcontrolerului un octet de date din registrul 0x2C, care va fi transferat prin intermediul
portului B, de fiecare dată când aduce linia de intrare RD7 în stare logică 0. Semnalul provenit
de la periferic este denumit ready şi indică disponibilitatea sa de a primi datele de la
microcontroler. Când microcontrolerul răspunde, acesta pune datele pe portul B apoi dă un
impuls pe pinul RD6, denumit strobe , prin care informează perifericul despre prezenţa datelor
pe liniile paralele, urmând ca acesta să le citească. La resetare pinii portului B trebuie aduşi în
stare logică 0, iar pinul RD6 în stare logică 1.
Un asemenea protocol (Fig. 6.12) poartă denumirea de handshake şi permite
realizarea unei comunicaţii fără pierdere de date între două echipamente ne-sincrone.
În Fig. 6.13 se prezintă scheama de conectare a microcontrolerului cu echipamentul
periferic (ex. imprimantă).

112
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 6.12. Protocolul handshake

Fig. 6.13. Schema electrică de conectare

Programul care implementează protocolul de comunicaţie se prezintă în continuare.


După etapa de iniţializare a porturilor se va iniţializa şi starea liniilor conform specificaţiilor.
Astfel, liniile de date corespunzătoare pinilor RB[7:0] vor fi aduse în stare logică 0 (toţi
biţii de date sunt 0), iar linia RD7 va fi adusă în stare logică 1.
După iniţializare se testează starea pinului RD7. La apariţia unui 0 logic pe acest pin,
datele din registrul de la adresa 0x2C se copiază pe port prin intermediul registrului de lucru,
apoi pinul RD6 este adus în stare logică 0. Pentru a genera impulsul se utilizează o
instrucţiune NOP înainte de a pune un 1 logic pe acest pin. Se utilizează instrucţiunea NOP,
deoarece în exemplul considerat nu se specifică durata impulsului. În alte situaţii, NOP poate
fi înlocuit cu apelul unei subrutine care implementează o întârziere.
Starea pinului RD7 este testată din nou, în aşteptarea unui 1 logic care să indice citirea
datelor de către periferic şi implicit încheierea transferului.

113
PORTURI DE INTRARE-IEŞIRE

LIST P=18F4455 ;definire tip procesor


#include <P18F4455.INC> ;definire variabile procesor

Date EQU 0x2C

ORG 0x800 ;Adresa de reset

;Programul principal

Initializare_port:
CLRF PORTB ;ştergere buffere
CLRF LATB
CLRF PORTD
CLRF LATD

MOVLW 0x0F ;Configurare convertor A/D


MOVWF ADCON1 ;pt. pini I/O digitali

MOVLW 07h ;Oprire comparatoare


MOVWF CMCON

BCF TRISD, 6 ;pin RD6 ieşire (strobe)


BSF TRISD, 7 ;pin RD7 intrare (ready)
CLRF TRISB ;pini RB[7:0] ieşire

BSF LATD, 6 ;stare iniţială pini


CLRF LATB

;testare pin RA7 (ready) în aşteptarea unui 0 logic


Test_Ready_0:
BTFSC PORTD, 7
GOTO Test_Ready_0

MOVFF Date, LATB ;se pun datele pe linie

BCF LATD, 6 ;impuls pe RD6


NOP
BSF LATD, 6

;testare pin RA7 (ready) în aşteptarea unui 1 logic


Test_Ready_1:
BTFSS PORTD, 7
GOTO Test_Ready_1
GOTO Test_Ready_0

114
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

6.3.3 Comanda unui afişaj cu 7 segmente şi 4 digiţi

Se consideră montajul din Fig. 6.9 în care la microcontroler este conectat un afişaj
multiplexat cu 7 segmente cu catod comun de 4 digiţi. Liniile de date ale afişajului (a,b,...,g,
dp) sunt conectate la portul B (a-RB[0], b-RB[1],...,g-RB[6],dp-RB[7]), iar cele patru
linii de selecţie la pinii RA[3:0]. Având în vedere că afişajul este cu catod comun, LED-
urile se vor aprinde atunci când pe pinii corespunzători liniilor de date vom avea un 1 logic.
Multiplexarea se va realiza prin intermediul liniilor de selecţie, iar programul va trebui să
asigure selectarea succesivă a fiecărui digit prin comanda tranzistorilor şi menţinerea datelor
adecvate pentru fiecare digit pe port. Dacă multiplexarea se realizează suficient de repede (ex.
la fiecare 10ms se selectează un nou digit şi se trimit datele spre el) se va crea impresia că
toate cele 4 cifre sunt aprinse simultan.
Se doreşte afişarea numărului 1234 pe afişajul cu şapte segmente şi patru digiţi. În
acest scop trebuie identificate valorile care se transmit pe port pentru aprinderea cifrelor
dorite. Analizând Fig. 6.14 se pot identifica aceste valori care se vor regăsi şi în program.

Fig. 6.14. Afişarea valorii 1234 pe un afişaj cu 7 segmente şi 4 digiţi

După etapa de iniţializare a porturilor fiecare digit va fi selectat pe rând prin activarea
tranzistorilor de pe portul A şi se vor transmite datele dorite spre afişaj care vor fi menţinute
un timp de 10ms înainte de a se trece la afişarea pe următorul digit. În programul următor se
consideră implementată rutina de întârziere de 10ms

LIST P=18F4455 ;definire tip procesor


#include <P18F4455.INC> ;definire variabile procesor

Unit EQU b’01100110’ ;4


Zeci EQU b’01001111’ ;3
Sute EQU b’01011011’ ;2
Mii EQU b’00000110’ ;1

ORG 0x800 ;Adresa de reset

[...]

115
PORTURI DE INTRARE-IEŞIRE

;Programul principal

Initializare_port:
CLRF PORTB ;ştergere buffere
CLRF LATB
CLRF PORTA
CLRF LATA

MOVLW 0x0F ;Configurare convertor A/D


MOVWF ADCON1 ;pt. pini I/O digitali

MOVLW 07h ;Oprire comparatoare


MOVWF CMCON

MOVLW 0xF0
MOVWF TRISA ;pini RA[3:0] ieşire
CLRF TRISB ;pini RB[7:0] ieşire

Aprindere_LED:
MOVLW Unit
MOVWF LATB
BSF LATA,0 ;selectare digit unităţi
BCF LATA,1
BCF LATA,2
BCF LATA,3
CALL Delay_10ms

MOVLW Zeci
MOVWF LATB
BCF LATA,0
BSF LATA,1 ;selectare digit zeci
BCF LATA,2
BCF LATA,3
CALL Delay_10ms

MOVLW Sute
MOVWF LATB
BCF LATA,0
BCF LATA,1
BSF LATA,2 ;selectare digit sute
BCF LATA,3
CALL Delay_10ms

MOVLW Mii
MOVWF LATB
BCF LATA,0
BCF LATA,1
BCF LATA,2
BSF LATA,3 ;selectare digit mii
CALL Delay_10ms

GOTO Aprindere_LED
END

116
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Capacitatea de a fi în legătură cu lumea exterioară prin intermediul


porturilor de intrare-ieşire reprezintă funcţionalitatea cea mai importantă

Concluzii pe care o poate furniza un microcontroler. Cele cinci porturi ale


microcontrolerului sunt controlate prin intermediul a trei regiştrii speciali
care permit configurarea direcţiei pinilor, scrierea şi citirea datelor de pe
port.

1. Care sunt regiştrii care controlează funcţionarea porturilor şi ce rol


îndeplinesc aceştia?
2. Care sunt etapele iniţializării porturilor?
Întrebări de
3. În Fig. 6.2 ce rol îndeplineşte circuitul tristate (3)?
autoevaluare
4. Cum se realizează protocolul handshake?
5. Cum se realizează configurarea direcţiei pinilor?

Afişaj cu şapte segmente


Afişaj cu LED-uri ce permite afişarea cifrelor
Termeni Bistabil D
esenţiali Celulă elementară de memorie. Circuit cu două stări (0 şi 1 logic) utilizat
pentru stocarea informaţiei de un bit.
Handshake
Protocol de comunicaţie care permite realizarea unei comunicaţii fără
pierdere de date între două echipamente ne-sincrone. Nu există un tact
comun de sincronizare. Sincronizarea se realizează prin mesaje.
LATn
Registru de citire/scriere a datelor de pe port
LED
Diodă electroluminescentă
PORTn
Registru de citire/scriere a datelor de pe port. La citire va conţine starea
fizică a pinilor.
Porturi de intrare-ieşire
Circuite de interfaţă prin intermediul cărora se poate realiza schimbul de
informaţii cu dispozitive periferice externe.

117
PORTURI DE INTRARE-IEŞIRE

Protocol de comunicaţie
Un ansamblu de mesaje / semnale şi reguli de schimbare a acestor mesaje
/ semnale între sisteme
TRISn
Registru în care se configurează direcţia unui port
Tristate
Circuit cu trei stări la ieşire: 0 logic, 1 logic şi impedanţă ridicată. Aceste
circuite dispun de o intrare de activare (ENABLE). Când circuitul este
activ acesta se comporta ca un circuit logic normal. Când circuitul este
inactiv ieşirea este în stare de impedanţă ridicată (ieşirea este deconectată
de la circuit)
UCP
Unitate centrală de prelucrare.

118
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

7. TEMPORIZĂRI SOFTWARE

Introducere
Obiective
7.1 TIMPII DE EXECUŢIE AI INSTRUCŢIUNILOR
Cuprins
7.2 IMPLEMENTAREA ÎNTÂRZIERILOR
7.2.1 Temporizare de 1 microsecundă
7.2.2 Temporizare de 1 milisecundă
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

119
TEMPORIZĂRI SOFTWARE

Realizarea temporizărilor este esenţială în cadrul oricărui sistem de calcul


bazat pe microcontrolere. În contextul în care microcontrolerele
funcţionează la nivel de microsecundă, obţinerea unor temporizări chiar la
Introducere
nivel de milisecundă are mai multe posibilităţi de implementare.
Cea mai simplă modalitate de realizare a unei temporizări este prin
utilizarea instrucţiunilor, sau mai bine zis a timpului de execuţie al
acestora. În acest capitol se vor studia mecanismele prin care se pot
genera temporizări la nivelul milisecundelor sau chiar al secundelor
utilizând instrucţiuni care izolate nu necesită mai mult de 0.2
microsecunde pentru execuţie.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă principiul pe baza căruia se obţin întârzierile software;
- să poată implementa rutine de întârziere cu diferite durate;
Obiective - să poată adapta rutinele de întârziere prezentate pentru alte valori
ale frecvenţei de lucru;
- să utilizeze rutinele de întârziere în diferite aplicaţii care necesită
temporizări.

7.1 TIMPII DE EXECUŢIE AI INSTRUCŢIUNILOR

Timpul de execuţie al unei instrucţiuni este direct proporţional cu frecvenţa de lucru.


Aceeaşi instrucţiune se va executa mai repede pe sisteme care dispun de o frecvenţă de lucru
mai mare. Tactul de execuţie al instrucţiunilor şi de funcţionare al modulelor interne este
generat pe baza frecvenţei de oscilaţie produsă fie de un oscilator extern (ex. cristal de cuarţ)
conectat la pinii microcontrolerului, fie de oscilatorul intern al microcontrolerului, selectat
prin registrul OSCCON. În ambele cazuri, tactul de oscilaţie este divizat cu 4 pentru asigurarea
celor 4 microcicluri de prelucrare a instrucţiunilor (vezi Capitolul 1).[8]
Arhitectura bazată pe pipeline-ul de două nivele pentru execuţia instrucţiunilor asigură
faptul că durata unui ciclu instrucţiune este egală cu 4 tacţi de oscilaţie.
4
TC = 4TOSC =
FOSC
Majoritatea instrucţiunilor microcontrolerului se executâ într-un timp egal cu durata
unui ciclu instrucţiune TC. Există totuşi câteva excepţii care necesită un timp de execuţie mai

120
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

lung. Aceste excepţii cuprind instrucţiunile care modifică valoarea numărătorului de program
(ex. instrucţiunile de salt) sau instrucţiunile lungi (reprezentate pe 4 octeţi) care nu pot fi
extrase din memorie într-o singură fază. Pentru aceste instrucţiuni timpul de execuţie poate fi
egal cu două sau trei cicluri instrucţiune.
În Tabelul 7.1 sunt prezentate instrucţiunile al căror timp de execuţie este variabil sau
este mai mare decât TC. Durata timpilor de execuţie pentru toate instrucţiunile este cuprinsă în
tabelele prezentate în Capitolul 2.

Tabel 7.1.Timpii de execuţie ai instrucţiunilor


Instrucţiune Timp de execuţie Descriere
Instrucţiuni de mutare
MOVFF 2TC Instrucţiune lungă de 32 de biţi
LFSR 2TC Instrucţiune lungă de 32 de biţi
Instrucţiuni de comparaţie şi salt
CPFSEQ TC sau 2TC sau 3TC
CPFSGT TC sau 2TC sau 3TC
CPFSLT TC sau 2TC sau 3TC
DECFSZ TC sau 2TC sau 3TC TC – fără salt;
DCFSNZ TC sau 2TC sau 3TC 2TC – cu salt peste instrucţiune de 16 biţi
INCFSZ TC sau 2TC sau 3TC 3TC – cu salt peste instrucţiune de 32 biţi
INFSNZ TC sau 2TC sau 3TC
TSTSFZ TC sau 2TC sau 3TC
BTFSC TC sau 2TC sau 3TC
BTFSS TC sau 2TC sau 3TC
Instrucţiuni de salt
BC TC sau 2TC
BN TC sau 2TC
BNC TC sau 2TC
BNN TC sau 2TC TC – fără salt;
BNOV TC sau 2TC 2TC – cu salt
BNZ TC sau 2TC
BOV TC sau 2TC
BZ TC sau 2TC
BRA 2TC Salt necondiţionat
GOTO 2TC Instrucţiune lungă de 32 de biţi. Salt necondiţionat
Instrucţiuni de apel de subrutină
CALL 2TC Instrucţiune lungă de 32 de biţi cu salt / apel
RCALL 2TC Apel de subrutina = salt la o adresă din memorie

121
TEMPORIZĂRI SOFTWARE

Tabel 7.1.Timpii de execuţie ai instrucţiunilor (continuare)


Instrucţiune Timp de execuţie Descriere
Instrucţiuni de revenire din subrutină

RETURN 2TC Revenire din subrutină = salt la adresa de


RETFIE 2TC revenire din subrutină (se modifică PC)
RETLW 2TC
Instrucţiuni tabelare
TBLRD* 2TC C1: citire memorie, C2: scriere TABLAT
TBLWT* 2TC C1: citire TABLAT, C2: scriere memorie

Analizând Tabelul 7.1 se poate observa că instrucţiuni simple precum MOLW, BSF sau
CLRF se execută într-un timp egal cu durata unui ciclu instrucţiune TC, pe când instrucţiunile
lungi, cele de salt necondiţionat, cele de apel şi revenire din subrutină şi instrucţiunile tabelare
se execută într-un timp dublu egal cu durata a două cicluri instrucţiune 2TC. Pe de altă parte
există o serie de instrucţiuni care realizează salturi condiţionate ale căror timpi de execuţie
depind de context. Cazul unei asemenea instrucţiuni va fi analizat în exemplul următor.

Să analizăm timpul de execuţie al instrucţiunii CPFSEQ. Se consideră cele trei


cazuri posibile evidenţiate în Fig. 7.1.

Exemplu

Fig. 7.1. Timpii de execuţie ai instrucţiunii CPFSEQ

În cazul a. condiţia de salt nu este îndeplinită, iar instrucţiunea CPFSEQ se


execută într-un timp TC.
În cazul b. condiţia de salt este îndeplinită, trebuie să se realizeze saltul peste
o instrucţiune scurtă (ex. BCF), iar instrucţiunea CPFSEQ se execută într-un
timp 2TC.
În cazul c. condiţia de salt este îndeplinită, trebuie să se realizeze saltul peste

122
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

o instrucţiune lungă (ex. GOTO), iar instrucţiunea CPFSEQ se execută într-un


timp 3TC.

După cum s-a menţionat anterior, durata unui ciclu instrucţiune depinde de frecvenţa
de lucru a microcontrolerului. Fără a cunoaşte cu exactitate această frecvenţă de oscilaţie nu
putem calcula cu exactitate durata unui ciclu instrucţiune TC şi astfel nu putem şti care este
timpul necesar execuţiei instrucţiunilor.
Întrucât microcontrolerele suportă numeroase frecvenţe de lucru vom analiza două
valori frecvent întâlnite în practică: FOSC=4MHz, respective FOSC = 20MHz. Pornind de la
aceste două valori rezultă următoarea durată a unui ciclu instrucţiune:
4 4
TC = 4TOSC = = = 1μs
FOSC 4 MHz
4 4
TC = 4TOSC = = = 0.2μs
FOSC 20 MHz

În aceste condiţii, în cazul unui microcontroler care dispune de un oscilator cu


frecvenţa de oscilaţie de 20MHz, instrucţiunea CPFSEQ, analizată anterior va fi executată în
0.2μs, 0.4μs sau 0.6μs în funcţie de contextul în care aceasta este executată. Având
posibilitatea de a calcula timpul necesar execuţiei fiecărei instrucţiuni putem proiecta
subrutine sau secţiuni de cod care se vor executa într-un anumit timp, implementând astfel
întârzieri software.

7.2 IMPLEMENTAREA ÎNTÂRZIERILOR

În contextul celor prezentate anterior, în aceast paragraf se vor prezenta câteva


exemple pentru implementarea unor temporizări uzuale.

7.2.1 Temporizare de 1 microsecundă

În cazul unei frecvenţe de lucru de 4MHz, temporizarea de 1 microsecundă poate lua


forma unui apel a instrucţiunii NOP. Această instrucţiune nu realizează nici o operaţie,
execuţia ei nu modifică nici un registru, ci doar consumă timpul procesorului.
Din cauza setului de instrucţiuni disponibil o temporizare la nivel de microsecundă are
moduri multiple de implementare. Practic, în cazul FOSC=4MHz orice instrucţiune scurtă se va
executa în timp de 1μs.

123
TEMPORIZĂRI SOFTWARE

De regulă, se recomandă ca o temporizare să poată fi utilizată cât mai uşor şi să


asigure o interfaţă care să ascundă detaliile legate de implementare. Astfel, de obicei
temporizarea trebuie să ia forma unei rutine. Astfel, un exemplu de rutină care produce o
întârziere de 1 microsecundă în cazul unei frecvenţe de lucru de 20MHz este următorul:

Delay1us:
NOP ;0.2us
RETURN ;0.4us

[…]

CALL Delay1us ;0.4us

În exemplul anterior, timpul necesar execuţiei rutinei Delay1us se calculează în


felul următor:
∆(Delay1us) = ∆(CALL) + ∆(NOP) + ∆(RETURN) = 0.4μs + 0.2μs + 0.4μs = 1μs
În rutina Delay1Micro s-a utilizat instrucţiunea NOP deoarece aceasta nu afectează
nici un registru. Astfel, rutina creată poate fi utilizată în orice context de execuţie. Desigur, în
locul instrucţiunii NOP se poate utiliza orice altă instrucţiune care să se execute în 0.2μs, dacă
se iau în considerare şi efectele posibile ale instrucţiunii incluse în rutină.

Să se genereze în mod repetat pe PORTA<0> un tren de impulsuri de forma


urmatoare:

Exemplu

Fig. 7.2. Tren de impulsuri

Pentru a rezolva această cerinţă, trebuie configurat portul A, astfel încât


bitul 0 să fie de ieşire. Mai este necesară definirea unor subrutine pentru
temporizările implicate. Apelul acestor subrutine, corelat cu seterea şi
resetarea bitului de ieşire conduc la obţinerea funcţionalităţii dorite.
Următorul cod sursă cuprinde rezolvarea acestei probleme.[8]

124
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

#include “P18F4455.INC”

ORG 0x800
;salt peste suburutine la programul principal
GOTO Main

Delay1us: ;0.2us+0.4us+CALL = 1us


NOP
RETURN

Delay2us: ;1us+0.2us+0.4us+CALL = 2us


CALL Delay1us
NOP
RETURN

Delay3us: ;2us+0.2us+0.4us+CALL = 3us


CALL Delay2us
NOP
RETURN

Delay5us: ;1us+3us+0.2us+0.4us+CALL = 5us


CALL Delay1us
CALL Delay3us
NOP
RETURN

Main:
; iniţializare port
CLRF PORTA
BCF TRISA, 0

Bucla_main:
;Generarea impulsurilor
BSF PORTA, 0
CALL Delay2us
BCF PORTA, 0
CALL Delay2us
BSF PORTA, 0
CALL Delay3us
BCF PORTA, 0
CALL Delay1us
BSF PORTA, 0
CALL Delay1us
BCF PORTA, 0
CALL Delay1us
BSF PORTA, 0
CALL Delay5us
BCF PORTA, 0
CALL Delay1us
GOTO Bucla_main ;Reluarea ciclului

END

125
TEMPORIZĂRI SOFTWARE

7.2.2 Temporizare de 1 milisecundă

După cum s-a văzut până acum implementarea unei întârzieri software constă pur şi
simplu din consumarea timpului procesorului prin lipsa unor operaţii pe durata de timp dorită.
O altă modalitate de a realiza acest lucru constă în consumarea timpului cu decrementarea
unei variabile de la o valoare prestabilită spre 0, după cum se poate vedea în Fig. 7.3. Prin
alegerea unei valori adecvate pentru valoarea iniţială, se poate obţine întârzierea dorită.
Bineînţeles, această întârziere depinde de frecvenţa de lucru a microcontrolerului. Pentru acest
exemplu vom considera FOSC = 4MHz care determină un ciclu instrucţiune cu durata TC=1μs.

Fig. 7.3. Întârziere de o milisecundă obţinută prin decrementarea unui contor

Subrutina următoare conţine implementarea întârzierii cu durata de 1 milisecundă în


cazul FOSC = 4MHz.

N EQU d’249’

Delay1ms:
MOVLW N ;1us
Bucla1ms:
DECF WREG ;N*1us
NOP ;N*1us
BNZ Bucla1ms ;(N-1)*2us+1us
RETURN ;2us

[…]

CALL Delay1ms ;2us

126
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Timpul necesar execuţiei rutinei Delay1ms se calculează în felul următor:


∆(Delay1ms)= ∆(MOVLW) + N·(∆(DECF)+ ∆(NOP)) +(N-1)·∆(BNZ)cu salt + ∆(BNZ)fără salt
+ ∆(RETURN) + ∆(CALL) = 1μs+249·(1μs+1μs)+248·2μs+1μs+2μs+2μs=1000μs=1ms

Pentru a ajunge la o temporizare de 1 milisecundă în cazul FOSC = 20MHz se poate


utiliza codul următor:
N EQU d’217’

Delay1ms:
MOVLW N ;0.2us
Bucla1ms:
CALL Delay1us ;N*1us
CALL Delay1us ;N*1us
CALL Delay1us ;N*1us
CALL Delay1us ;N*1us
DECFSZ WREG,W ;(N-1)*0.2us+0.6us
GOTO Bucla1ms ;(N-1)*0.4us
NOP ;0.2us
NOP ;0.2us
NOP ;0.2us
NOP ;0.2us
RETURN ;0.4us

[…]

CALL Delay1ms ;0.4us

Durata întârzierii atinse se calculează în felul următor:


∆(Delay1ms) = ∆(MOVLW) + (N-1)·( 4·∆(Delay1us) + ∆(DECFSZ)fără salt + ∆(GOTO) ) +
4·∆(Delay1us) + ∆(DECFSZ)cu salt + 4·∆(NOP) + ∆(RETURN)+ ∆(CALL) = 0.2μs + (217 -
1)·(4·1μs + 0.2μs + 0.4μs) + 4·1μs + 0.6μs + 4·0.2μs + 0.4μs + 0.4μs = 1000μs=1ms

În implementarea subrutinei de mai sus s-a considerat definită în prealabil subrutina


Delay1us conform celor prezentate în paragraful 4.2.1.
Pornind de la rutina care implementează întârzierea de o milisecundă se pot
implementa alte subrutine pentru obţinerea unor temporizări cu durată mai mare. În funcţie de
specificul aplicaţiilor implementate, aceste temporizări pot fi mai mult sau mai puţin exacte.
Exemplul următor detaliază acest lucru.

127
TEMPORIZĂRI SOFTWARE

Se doreşte implementarea unei subrutine care realizează o temporizare cu


durata de 100ms. În mod obişnuit o asemenea temporizare s-ar putea obţine
prin apelul repetat de o sută de ori al subrutinei Delay1ms implementată
Exemplu
anterior, conform Fig. 7.4.

Fig. 7.4. Întârziere de 100ms

Subrutina următoare ar putea reprezenta o soluţie la această problemă

Contor EQU 0x00

Delay100ms:
MOVLW d’100’ ;0.2us
MOVWF Contor ;0.2us
Bucla100ms:
CALL Delay1ms ;100*1ms
DECFSZ Contor, F ;(100-1)*0.2us+0.6us
GOTO Bucla ;(100-1)*0.4us
RETURN ;0.4us

[…]

CALL Delay100ms ;0.4us

Calculând durata întârzierii obţinute prin utilizarea acestei subrutine


obţinem ∆(Delay100ms)=100061.2μs=100.0612ms. Întârzierea astfel
obţinută nu este într-u totul exactă, dar abaterea faţă de valoarea dorită este
nesemnificativă. În general, asemenea abateri nu influenţează aplicaţiile
care necesită temporizări cu un astfel de ordin de mărime (zeci, sute de
milisecunde).

128
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Una din problemele frecvent întâlnite în aplicaţiile pentru microcontrolere este


problema eliminării oscilaţiilor apărute la apăsarea sau eliberarea unui buton în vederea
detectării frontului crescător sau descrescător.
Detectarea apăsării unui buton necesită o atenţie deosebită deoarece o serie de
elemente fizice influenţează direct semnalul rezultat. Întrucât contactele unui buton (sau
releu) nu se închid perfect instantaneu la fiecare apăsare, semnalul rezultat va prezenta foarte
multe zgomote / oscilaţii imediat după apăsare, zgomote care sunt percepute de
microcontroler ca apăsări succesive ale butonului.
În Fig. 7.5 se exemplifică acest fenomen.

Fig. 7.5. Oscilaţii la apăsarea / eliberarea butoanelor

Intervalul de stabilizare al semnalului poate varia foarte mult în funcţie de tipul


butonului şi caracteristicile apăsării efectuate (ex. o apăsare lentă sau una rapidă). Tocmai din
această cauză, înainte de a trece la implementare, se recomandă determinarea acestui interval
de stabilizare cu ajutorul unui osciloscop (Fig. 7.6). De regulă butoanele uzuale au acest
interval cuprins între 200μs şi 10ms.

Fig. 7.6. Vizualizarea pe osciloscop a oscilaţiilor apărute la eliberarea unui buton

129
TEMPORIZĂRI SOFTWARE

Eliminarea oscilaţiilor din intervalul de stabilizare se face prin program relativ simplu.
Ideea de bază este de a citi periodic (eşantiona) semnalul care provine de la buton şi de a filtra
zgomotele produse. Există mai multe abordări privind rezolvarea acestei probleme. Una dintre
ele presupune utilizarea unui contor pentru a determina durata de timp în care semnalul a fost
în stare logică ‘0’. Dacă semnalul respectiv a fost ’0’ continuu o anumită durată de timp,
atunci acel semnal poate fi considerat stabil, iar butonul apăsat. Practic, la apariţia unui front
de apăsare se aşteaptă un timp ∆t în care alte fronturi nu se iau în considerare. După expirarea
acestui interval se poate considera că a avut loc o apăsare.
Exemplul următor oferă o soluţie la această problemă.

Se consideră un buton conectat la PORTD<0> al unui microcontroler cu


frecvenţa de lucru FOSC=20MHz. La apăsarea butonului, pe pinul portului se
va citi valoarea 0 logic. Se consideră intervalul de stabilizare al semnalului
Exemplu
provenit de la buton având durata ∆t=10ms. De asemenea, se mai consideră
ca fiind definite anterior: subrutina de iniţializare a portului Init_port,
subrutina de o microsecundă Delay1us şi subrutina de o milisecundă
Delay1ms.
Se cere să se determine apariţia frontului ca urmare a apăsării butonului şi
să se elimine oscilaţiile apărute.

Fig. 7.7. Eliminarea oscilaţiilor din intervalul de stabilizare

130
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

În Fig. 7.7 se prezintă algoritmul utilizat pentru eliminarea oscilaţiilor


apărute în intervalul de stabilizare a semnalului provenit de la buton ca
urmare a apăsării acestui.
Programul va sta într-o buclă de testare / eşantionare a semnalului provenit
de la buton până se va detecta o apăsare (semnalul va fi 0 logic). Dacă după
∆t=10ms butonul continuă să fie apăsat, atunci apăsarea se va considera ca
fiind validă, iar programul va continua. Dacă după ∆t=10ms butonul nu este
apăsat (semnalul este 1 logic) atunci se consideră că la prima testare au fost
detectate doar niste oscilaţii care nu trebuie interpretate ca fiind apăsări
valide ale butonului.
Programul utilizează o variablilă denumită Front utilizată pentru a marca
starea semnalului de intrare de pe port între cele două testări succesive. La
apariţia unei apăsări valide variabila Front se va schimba din 0x00 în
0xFF, în caz contrar îşi va păstra starea avută iniţial.

Front EQU 0x00


Contor10ms EQU 0x01

GOTO Main ;salt peste subrutine

[…]

Delay10ms: ;subrutina de 10ms


MOVLW d’10’
MOVWF Contor10ms
Bucla10ms:
CALL Delay1ms
DECFSZ Contor10ms,F
GOTO Bucla10ms
RETURN

[…]

Main: ;programul principal


CALL Init_port ;iniţializare porturi
CLRF Front ;Front=0x00

Test_btn: ;testare buton


BTFSS PORTD,0
GOTO Buton_apasat
GOTO Test_btn

Buton_apasat:
CALL Delay10ms ;aştept ∆t=10ms
MOVF Front, W ;salvez starea anterioară

131
TEMPORIZĂRI SOFTWARE

BTFSS PORTD,0 ;a 2-a testare a butonului


SETF Front ;apăsare validă. Front=0x00
CLRF Front ;apăsare invalidă. Front=0xFF

Test_front: ;testare front


CPFSGT front
GOTO Front_detectat
GOTO Test_btn

Front_detectat:
[…] ;acţiuni efectuate la
;detectarea unei apăsări
;valide

Una dintre cele mai accesibile metode de a reliza temporizări presupune


utilizarea timpului de execuţie al instrucţiunilor. Dacă se cunoaşte durata

Concluzii acestui timp se pot proiecta subrutine sau secţiuni de cod care
implementează întârzieri software cu diferite durate.
Întârzierile software reprezintă o soluţie de realizare a temporizărilor care
este disponibilă în cazul tuturor microcontrolerelor pentru care se
cunoaşte timpul de execuţie al instrucţiunilor.

1. Ce este o întârziere software?


2. În ce condiţii timpul de execuţie al instrucţiunii DECFSZ este TC,
sau 2TC sau 3TC?
Întrebări de
3. Care este durata unui ciclu instrucţiune în cazul utilizării unei
autoevaluare
frecvenţe de lucru de 48MHz?
4. Cum s-ar implementa o subrutină care implementează o întârziere
cu durata de 1μs în cazul utilizării unei frecvenţe de lucru de
48MHz?
5. În cazul subrutinei de 100ms implementată în acest curs, cât ar fi
abaterea obţinută dacă instrucţiunea Delay1us ar implementa de
fapt o întârziere de 1.2μs?
6. De ce apar oscilaţii la apăsarea butoanelor?
7. De ce instrucţiunea MOVFF se execută într-un timp de 2TC?

132
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Ciclu instrucţiune
Durata de timp egală cu 4TOSC a fazelor instrucţiunii
Termeni Instrucţiuni
esenţiali Comenzi codificate binar pe care le execută UCP
Întârziere software
Temporizare realizată pe baza timpului de execuţie al instrucţiunilor
Pipeline
Tehnică utilizată pentru a creşte numărul de instrucţiuni care pot fi
executate în unitatea de timp. Pipeline-ul nu reduce timpul necesar
execuţiei unei instrucţiuni, ci creşte numărul de instrucţiuni care pot fi
procesate simultan
Subrutină
Structură de organizare a programelor care ia forma unor instrucţiuni
cuprinse între o etichetă şi o instrucţiune de revenire din subrutină.
Unitate independentă de program, plasată în memorie în altă zonă decât
programul principal

133
TEMPORIZĂRI HARDWARE

8. TEMPORIZĂRI HARDWARE

Introducere
Obiective
8.1 TIMER 0
Cuprins
8.1.1 Structura internă a timerului 0
8.1.2 Configurarea timerului 0
8.2 TIMER 1
8.2.1 Structura internă a timerului 1
8.2.2 Configurarea timerului 1
8.3 TIMER 2
8.3.1 Structura internă a timerului 2
8.3.2 Configurarea timerului 2
8.4 TIMER 3
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

134
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Asigurarea unor temporizări exacte este esenţială în cadrul multor sisteme


de calcul bazate pe microcontrolere. Printre funcţiile care pot fi asociate
temporizărilor se pot aminti: măsurarea unor durate, numărarea de
Introducere
evenimente, eşantionarea unor semnale, comanda unor echipamente
externe pentru o anumită durată de timp etc.
Subrutinele care implementează întârzieri pe baza instrucţiunilor
reprezintă una din modalităţile de a realiza temporizări, dar tocmai prin
modul lor de implementare acestea ocupă timpul procesorului care ar
putea fi utilizat mai eficient în alte scopuri.
Microcontrolerul PIC18F4455 pune la dispoziţia utilizatorului 4 timere
(circuite de temporizare) denumite sugestiv Timer0, Timer1, Timer2 şi
Timer3. În ciuda numelui sugestiv timerele pot fi utilizate într-o varietate
de moduri, nu doar pe post de temporizatoare. În acest capitol se vor
prezenta structura timerelor existente precum şi modurile de lucru
asigurate de acestea.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă principiul pe funcţionare al timerelor
- să poată determina valorile de iniţializare ale timerelor pentru o
Obiective temporizare dorită
- să utilizeze timerele în diferite aplicaţii care necesită temporizări.

8.1 TIMER 0

8.1.1 Structura internă a timerului 0

Alături de porturile de intrare-ieşire, Timerul0 este printre singurele module care s-au
mai păstrat de la prima serie de microcontrolere PIC de 8 biţi produsă vreodată.
Din punct de vedere structural, Timerul0 este un numărător, a cărui valoare poate fi
scrisă şi citită, fiind stocată în doi regiştri: TMR0L şi TMR0HB. În funcţie de configurare,
timerul dispune de două moduri de lucru: numărător pe 8 biţi, sau pe 16 biţi.
Ca la orice numărător, incrementarea timerului se realizează pe baza unor impulsuri de
tact care pot proveni din două surse distincte:

135
TEMPORIZĂRI HARDWARE

- sursă internă. În acest caz impulsurile numărate reprezintă tactul de execuţie al


instrucţiunilor şi au o frecvenţă FOSC/4
- sursă externă. În acest caz, timerul va număra impulsuri externe pe pinul T0CKI
(Timer 0 Clock Input).
În cazul în care se utilizează o sursă externă de incrementare, timerul permite
selectarea frontului de incrementare, ceea ce înseamnă că se pot număra fronturile crescătoare
sau descrescătoare ale semnalului de intrare.
Circuitul de temporizare dispune de un predivizor programabil (en. presacler) care
realizează divizarea tactului de incrementare şi care este util atunci când se doreşte ca timerul
să nu se incrementeze la fiecare tact, ci doar la fiecare 2, 4, 16, ... sau 256, tacturi
recepţionate. Situaţia aceasta apare frecvent în cazul implementării unor temporizări cu durată
mai mare.
Timerul0 va genera o întrerupere la depăşirea capacităţii de numărare, atunci când
valoarea numărătorului trece de la FFh la 00h, în mod de lucru de 8 biţi, sau de la FFFFh la
0000h în mod de lucru de 16 biţi. Acestă depăşire va fi semnalată prin setarea unui bit
indicator de întrerupere, denumit TMR0IF, din registrul INTCON. Pentru a putea detecta o
nouă depăşire flag-ul de semnalizare TMR0IF trebuie şters din program.

Mod de lucru – 8 biţi

Schema bloc a timerului0 în mod de lucru de 8 biţi se prezintă în Fig. 8.1.

Fig. 8.1. Schema bloc a timerului 0 în mod de lucru de 8 biţi conform foii de catalog [15]

Analizând schema din Fig. 8.1 putem constata că elementul principal al timerului0
este circuitul de numărare de 8 biţi a cărui valoare poate fi accesată prin intermediul
registrului TMR0L. Tactul de incrementare al acestui numărător poate proveni dintr-o sursă
externă, prin intermediul pinului T0CKI sau poate fi tactul intern de execuţie al
instrucţiunilor FOSC/4. Bitul T0CS (Timer0 Clock Select) din registrul T0CON[5] este
utilizat pentru a selecta între sursa internă sau externă a tactului. În cazul sursei de

136
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

incrementare externe se poate opta, prin intermediul bitului T0SE (Timer0 Select Edge) din
registrul T0CON[4], pentru numărarea fronturilor crescătoare sau descrescătoare ale
semnalului de pe pinul T0CKI.
Indiferent de sursa tactului, poate fi selectată utilizarea predivizorului, prin punerea
bitului PSA (Prescaler Assign) pe 0. În această situaţie, timerul se va incrementa la fiecare n
impulsuri primite, selectarea valorii predivizorului fiind realizată prin biţii T0PS2:T0PS0.
Pentru a nu folosi predivizorul, bitul PSA trebuie pus pe 1.
Deoarece, în cazul utilizării impulsurilor externe, evenimentele numărate pot să-şi facă
apariţia pe pinul T0CKI în mod aleator în raport cu tactul intern, este necesară realizarea unei
sincronizări între cele două semnale pentru a asigura corectitudinea ciclurilor de scriere sau
citire ale Timerului0.
După configurarea timerului, acesta se porneşte prin setarea bitului TMR0ON din registrul
T0CON[7]. Timerul semnalează utilizatorului trecerea de la valoarea maximă la valoarea
minimă (Overflow) prin setarea flagului TMR0IF din registrul INTCON[2]. În acelaşi timp
Timerul 0 poate genera o întrerupere dacă a fost în prealabil validată linia corespunzătoare de
întrerupere. Astfel, utilizatorul nu mai este nevoit să verifice tot timpul flag-ul timerului
pentru a determina momentul în care temporizarea stabilită a expirat.

Mod de lucru – 16 biţi

Alegerea între utilizarea timerului 0 în mod de lucru de 8 biţi sau în mod de lucru de 16
biţi se realizează prin intermediul bitului T08BIT din registrul T0CON[6]. Dacă acest bit
este 1, timerul va funcţiona pe 8 biţi. În caz contrar, timerul funcţionează pe 16 biţi. Pentru a
păstra compatibilitatea cu modele anterioare de microcontrolere PIC, la resetare timerul 0 este
configurat implicit în mod de lucru de 8 biţi.
Indiferent de modul de lucru ales, principiul de funcţionare al timerului se păstrează:
timerul se incrementează la fiecare impuls primit. Se modifică doar modul de acces la
valoarea numărătorului.
În cazul funcţionării pe 8 biţi, accesul la valoarea timerului se realizează direct prin
intermediul registrului TMR0L. Accesarea valorii timerului se modifică puţin în cazul
funcţionării pe 16 biţi, deoarece toate instrucţiunile microcontrolerului permit accesul la date
cu dimensiunea de 8 biţi. În aceste condiţii, fără existenţa unor structuri ajutătoare, nu este
posibilă realizarea accesului atomic la valoarea de 16 biţi a numărătorului. Accesul atomic
permite citirea sau scrierea valorii instantanee a timerului. De exemplu, în lipsa acestuia

137
TEMPORIZĂRI HARDWARE

pentru a citi întreaga valoare de 16 biţi a timerului sunt necesare două operaţii succesive de
citire (se citeşte octetul inferior apoi cel superior) între care valorile se pot modifica.
În Fig. 8.2 se prezintă structura numărătorului care intră în componenţa timerului 0 în
mod de lucru de 16 biţi care permite accesul atomic la valoarea timerului.

Fig. 8.2. Accesul la regiştrii timerului 0 în mod de lucru de 16 biţi

Citirea şi scrierea timerului pe 16 biţi este facilitată de un registru tampon pentru


stocarea octetului superior TMR0H. Octetul superior al numărătorului (TMR0HB) este ascuns,
fiind inaccesibil în mod direct prin instrucţiuni de scriere sau citire. La citirea TMR0L,
valoarea octetului superior este transferată în registrul tampon TMR0H. Acesta poate fi scris
sau citit cu ajutorul instrucţiunilor uzuale. La scrierea registrului TMR0L, valoarea stocată în
TMR0H se va transfera în octetul superior al timerului. Prin această arhitectură, timerul
permite un acces atomic la valoarea numărătorului pe 16 biţi prin intermediul unei magistrale
de 8 biţi.
Totuşi, trebuie avut grijă ca operaţiile de scriere/citire ale valorii timerului să respecte
ordinea menţionată:
- la citire: se citeşte TMR0L apoi TMR0H;
- la scriere: se scrie TMR0H apoi TMR0L.

8.1.2 Configurarea timerului 0

Simplitatea utilizării timerului 0 este dată de faptul că toţi biţii de configurare se


găsesc într-un singur registru: T0CON. Structura acestui registru este prezentată în Fig. 8.3 şi
este urmată de descrierea biţilor.

138
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

7 0
TMR0ON T08BIT T0CS T0SE PSA T0PS2 T0PS1 T0PS0
Fig. 8.3. Registrul T0CON: Timer0 Control Register

Bit 7 TMR0ON – Bit de Pornire / Oprire Timer0


1 = Pornire Timer0
0 = Oprire Timer0
Bit 6 T08BIT – Bit selecţie numărător pe 8 / 16 biţi
1 = Timer0 este configurat ca numărător pe 8 biţi
0 = Timer0 este configurat ca numărător pe 16 biţi
Bit 5 T0CS – Bit selecţie sursă tact de incrementare
1 = impulsuri externe (tranziţii pe pinul T0CKI)
0 = impulsuri interne (tactul de execuţie al instrucţiunilor FOSC/4)
Bit 4 T0SE – Bit selecţie front de numărare pentru impulsurile externe
1 = front descrescător pe pinul T0CKI
0 = front crescător pe pinul T0CKI
Bit 3 PSA – Bit Utilizare / Dezactivare predivizor
1 = Dezactivare predivizor
0 = Utilizare predivizor
Biţii 2-0 T0PS2:T0PS0 – Biţi de selecţie a valorii de predivizare
111 = Raport de predivizare 1:256
110 = Raport de predivizare 1:128
101 = Raport de predivizare 1:64
100 = Raport de predivizare 1:32
011 = Raport de predivizare 1:16
010 = Raport de predivizare 1:8
001 = Raport de predivizare 1:4
000 = Raport de predivizare 1:2

Înainte de a realiza configurarea efectivă a Timerului0, în vederea realizării unei


temporizări, trebuie determinată valoarea de iniţializare a numărătorului corespunzătoare
temporizării dorite.
Astfel, dacă se doreşte o temporizare bazată pe tactul de execuţie al instrucţiunilor se
poate utiliza următoarea formulă:

139
TEMPORIZĂRI HARDWARE

4
Tdorita = NrIncr ⋅ Predivizor ⋅ TC = NrIncr ⋅ Pr edivizor ⋅ (8.1)
FOSC
unde:
- Tdorita este durata temporizării dorite

- NrIncr este numărul total de impulsuri care trebuie numărate pentru obţinerea
temporizării dorite
- Predivizor este valoarea predivizorului (se vor considera valorile predefinite posibile
Predivizor ∈ {1,2,4,8,16,32,64,128,256} )
4
- TC = este tactul de execuţie al instrucţiunilor. Pentru FOSC = 20MHz TC = 0.2μs
FOSC

Pentru exemplificare se va considera determinarea valorii de iniţializare a


numărătorului necesară obţinerii unei temporizări de o secundă. Se va considera cazul unui
microcontroler care dispune de un oscilator extern cu FOSC = 20MHz .

Conform relaţiei (8.1), pentru un raport de predivizare de 1:256, obţinem1:


1s = NrIncr ⋅ 256 ⋅ 0.2 ⋅ 10 −6 s (8.2)
⇒ NrIncr = 19531.25 ≅ 19531 (8.3)
Din relaţiile de mai sus rezultă că pentru obţinerea unei temporizări de o secundă,
Timerul0 va trebui să numere 19531 impulsuri cu perioada Ti = 0.2μs , va utiliza un raport de
predivizare de 1:256 şi va fi configurat ca numărător pe 16 biţi.
Pentru a putea fi semnalată expirarea temporizării prin intermediul flag-ului TMR0IF,
numărătorul va trebui iniţializat cu valoarea 65535-19531=46004. Astfel, având în vedere
faptul că numărătorul numără în sus, în momentul depăşirii capacităţii de numărare s-au
numărat impulsurile necesare pentru obţinerea temporizării dorite, care va fi semnalată prin
setarea bitului TMR0IF.
Cei doi regiştri TMR0H:TMR0L vor trebui iniţializaţi cu valorile:
(46004)10 = B3B4h
Ö B3h → TMR0H (8.4)
Ö B4h → TMR0L

În general, problema iniţializării timerului se rezumă la determinarea perechii: valoare


de iniţializare - raport de predivizare pe baza relaţiei (8.1).

1
Dacă se consideră un raport de predivizare de 1:128, rezultă NrIncr = 39062

140
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Odată determinată valoarea de iniţializare a Timerului0 se poate trece la etapa de


configurare, care presupune parcurgerea următorior paşi:
• oprirea timerului (bitul TMR0ON=0, registrul T0CON[7]) ;
• selectarea sursei de incrementare (bitul T0CS, registrul T0CON[5]):
• în cazul unei surse externe de incrementare se va selecta frontul utilizat (bitul T0SE,
registrul T0CON[4])
• selectarea utilizării predivizorului (bitul PSA, registrul T0CON[3])
• în cazul utilizării predivizorului (PSA=0) se va selecta raportul de predivizare dorit
(biţii TOPS2:TOPS0, registrul T0CON[2:0])
• selectarea modului de funcţionare (bitul T08BIT, registrul T0CON[6]);
• ştergerea flag-ului de semnalizare (bitul TMR0IF, registrul INTCON[2]);
• iniţializarea valorii timerului (regiştrii TMR0H şi TMR0L)
• pornirea timerului (bitul TMR0ON, registrul T0CON[7]).[8]

Pentru exemplificare se va considera cazul analizat anterior, care conduce la obţinerea


unei temporizări cu durata de o secundă.

CONFIGURARE_TIMER0:
BCF T0CON, TMR0ON ;Oprirea timerului
BCF T0CON, T0CS ;tact intern
BCF T0CON, PSA ;utilizare predivizor
BSF T0CON, T0PS2 ;predivizare 1:256
BSF T0CON, T0PS1
BSF T0CON, T0PS0
BCF T0CON, T08BIT ;numărător 16biţi
MOVLW 0xB3 ;valoare Timer0 46004
MOVWF TMR0H
MOVLW 0xB4
MOVWF TMR0L
BCF INTCON, TMR0IF ;Stergerea flag-ului
BSF T0CON, TMR0ON ;Pornirea timerului

BUCLA_TESTARE:
BTFSS INTCON, TMR0IF
GOTO LOOP_TESTARE
;Când se ajunge în acest punct, temporizarea s-a terminat

Bineînţeles, configurarea timerului se poate realiza şi într-un singur pas, prin


specificarea valorii octetului care va trebui înscris în registrul T0CON. Astfel, codul de mai
sus devine:

141
TEMPORIZĂRI HARDWARE

CONFIGURARE_TIMER0:
MOVLW b’00000111’ ;initializare T0CON
MOVWF T0CON
MOVLW 0xB3 ;valoare Timer0 46004
MOVWF TMR0H
MOVLW 0xB4
MOVWF TMR0L
BCF INTCON, TMR0IF ;Stergerea flag-ului
BSF T0CON, TMR0ON ;Pornirea timerului

BUCLA_TESTARE:
BTFSS INTCON, TMR0IF
GOTO LOOP_TESTARE
;Când se ajunge în acest punct, temporizarea s-a terminat

8.2 TIMER 1

8.2.1 Structura internă a timerului 1

Timerul 1 (Fig. 8.4) este construit în jurul unui numărător de 16 biţi implementat sub
forma unei perechi de regiştri de 8 biţi (TMR1HB:TMR1L), din care registrul superior
(TMR1HB) este ascuns. La fel ca şi în cazul timerului 0 accesul la octetul superior al timerului
1 se realizează prin intermediul registrului tampon TMR1H. Citirea registrului TMR1L va
determina transferul conţinutului registrului TMR1HB în registrul TMR1H. Totodată, o scriere
a registrului TMR1L va rezulta în actualizarea TMR1HB cu valoarea din TMR1H.

Fig. 8.4. Schema bloc a timerului 1 conform foii de catalog [15]

Spre deosebire însă de timerul0, accesarea atomică a regiştrilor TMR1HB:TMR1L


poate fi dezactivată cu ajutorul bitului RD16 din registrul T0CON[7], iar cei doi regiştri pot
fi accesaţi prin două operaţii succesive. Acest mod de acces este compatibil cu versiunile

142
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

anterioare ale acestui modul disponibile pe microcontrolerele din familia PIC16 şi trebuie
utilizat cu preacauţie. De exemplu, Microchip recomandă ca timerul să fie oprit atunci când se
accesează cei doi regiştri.
La depăşirea capacităţii de numărare (la trecerea de la valoarea FFFFh la 0000h) se va
seta bitul indicator TMR1IF din registrul PIR[0].

Similar timerului 0, şi acest timer pune la dispoziţia utilizatorului posibilitatea


realizării unor temporizări sau posibilitatea numărării impulsurilor (externe sau interne).
Incrementarea timerului poate avea trei surse, care pot fi alese prin intermediul biţilor
TMR1CS şi T1OSCEN din registrul T1CON[3,1]:
- sursă internă. În acest caz impulsurile numărate reprezintă tactul de execuţie al
instrucţiunilor şi au o frecvenţă FOSC/4.
- sursă externă-utilizator. În acest caz timerul va număra impulsuri externe (fronturi
crescătoare) pe pinul T13CKI (Timer 1/3 Clock Input).
- sursă externă-oscilator. În acest caz, timerul va fi incrementat de impulsurile
provenite de la un oscilator suplimentar extern asociat timerului 1. Frecvenţa
acestui oscilator poate fi de maximum 200kHz. În general se utilizează un cristal
cu frecvenţa de 32.768kHz. Prin utilizarea unui asemenea oscilator pot fi
implementate aplicaţii de temporizare de tip ceas, în care nu apar erori de ordinul
microsecundelor din divizarea tactului de incrementare. Aceste erori sunt frecvente
la implementarea ceasurilor prin utilizarea oscilatorului sistem, ce lucrează la nivel
de MHz. Schema de conectare a ocilatorului extern asociat timerului 1 se prezintă
în Fig. 8.5. Condensatorii au rolul de stabilizare a semnalului rezultat, valorile
recomandate de producător fiind de 27 şi 33 pF.

Fig. 8.5. Conectarea oscilatorului extern conform foii de catalog [15]

Indiferent de sursa impulsurilor numărate, timerul se poate incrementa direct sau la


fiecare al doilea, al patrulea sau al optulea tact, în funcţie de starea biţilor T1CKPS1 şi
T1CKPS0 din registrul T0CON[5:4].

143
TEMPORIZĂRI HARDWARE

Ieşirea predivizorului este sincronizată implicit cu tactul sistem, dar sincronizarea

poate fi dezactivată dacă bitul T1SYNC =1. Bitul de sincronizare este luat în considerare doar
în cazul utilizării unui tact extern (TMRCS=1).

O funcţionalitate ascunsă de schema bloc este aceea că timerul 1, prin intermediul


oscilatorului său conectat între pinii T1OSI şi T1OSO, poate asigura tactul intern în cazul
modurilor de lucru cu consum redus. Astfel, microcontrolerul oferă posibilitatea asigurării
tactului sistem nu numai prin oscilatorul principal (extern) ci şi prin intermediul oscilatorului
Timerului 1. De fiecare dată când oscilatorul timerului 1 reprezintă sursa pentru tactul sistem,
bitul de stare T1RUN din registrul T1CON[6] este setat.
O altă utilizare a timerului 1 vizează asocierea sa cu modulele de captură / comparare /
PWM, caz în care evenimentele provenite de la aceste module pot reseta starea regiştrilor
interni ai timerului.

8.2.2 Configurarea timerului 1

Configurarea timerului 1 se reduce la modificarea biţilor din registrul T1CON.


Structura acestui registru este prezentată în Fig. 8.6 şi este urmată de descrierea biţilor.

7 0
RD16 T1RUN T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON
Fig. 8.6. Registrul T1CON: Timer0 Control Register

Bit 7 RD16 – selectarea modului de acces la regiştrii timerului


1 = acces atomic
0 = acces succesiv prin două operaţii de 8 biţi
Bit 6 T1RUN – Bit de stare. Indică dacă tactul sistem este obţinut pe baza
oscilatorului timerului 1
1 = tactul sistem este obţinut pe baza oscilatorului timerului 1
0 = tactul sistem este obţinut din altă sursă
Biţii 5-4 T1CKPS1:T1CKPS0 – Biţi de selecţie a valorii de predivizare
11 = Raport de predivizare 1:8
10 = Raport de predivizare 1:4
01 = Raport de predivizare 1:2
00 = Raport de predivizare 1:1

144
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Bit 3 T10SCEN – Activarea/dezactivarea oscilatorului extern


1 = oscilatorul timerului 1 este activat
0 = oscilatorul timerului 1 este oprit
Bit 2 T1SYNC – Activarea/dezactivarea sincronizării impulsurilor externe cu tactul
intern
Dacă TMR1CS = 1
1 = Fără sincronizare
0 = Sincronizare
Dacă TMR1CS = 0
Bitul este ignorat. Timer1 utilizează impulsuri interne pentru incrementare.
Bit 1 TMR1CS – Bit selecţie sursă tact de incrementare
1 = impulsuri externe (front crescător pe pinul RC0/T1OSO/T13CKI)
0 = impulsuri interne (tactul de execuţie al instrucţiunilor FOSC/4)
Bit 0 TMR1ON – Bit de Pornire / Oprire Timer0
1 = Pornire Timer1
0 = Oprire Timer1

În vederea realizării unei temporizări cu o valoare dorită se poate utiliza relaţia (8.5)
pentru a determina valoarea de iniţializare a numărătorului.
Tdorita = NrIncr ⋅ Predivizor ⋅ TC (8.5)
unde:
- Tdorita este durata temporizării dorite

- NrIncr este numărul total de impulsuri care trebuie numărate pentru obţinerea
temporizării dorite
- Predivizor este valoarea predivizorului (se vor considera valorile predefinite posibile
Predivizor ∈ {1,2,4,8})
- TC este perioada impulsurilor numărate. În cazul utilizării tactul de execuţie al
instrucţiunilor ca sursă de incrementare TC=4/FOSC. Dacă se utilizează o sursă externă,
Timer1 se incrementează la fiecare front crescător al semnalului de tact extern. Dacă
acest semnal este periodic atunci, în relaţia (8.5) se poate considera TC=1/FOSCext.

145
TEMPORIZĂRI HARDWARE

Odată determinată valoarea de iniţializare a Timerului1 se poate trece la etapa de


configurare, care presupune parcurgerea următorior paşi:
• oprirea timerului (bitul TMR1ON=0, registrul T1CON[0]) ;
• selectarea sursei de incrementare (bitul TMR1CS, registrul T1CON[1]);
• în cazul unei surse externe se alege tipul acesteia (bitul T1OSCEN, registrul

T1CON[3]) şi sincronizarea (bitul T1SYNC , registrul T0CON[2]);


• selecta raportul de predivizare dorit (biţii T1CKPS1:T1CKPS0, registrul
T1CON[5:4]);
• selectarea modului de acces la regiştrii timerului (bitul RD16, registrul T1CON[7]);
• opţional – configurarea modulelor CCP
• ştergerea flag-ului de semnalizare (bitul TMR1IF, registrul PIR1[0]);
• iniţializarea valorii timerului (regiştrii TMR1H şi TMR1L);
• pornirea timerului (bitul TMR1ON, registrul T1CON[0]).[8]

Pentru exemplificarea utilizării timerului 1 şi a etapei sale de configurare se va


considera exemplul următor.

Să considerăm următoarea aplicaţie, în care se doreşte interogarea unui senzor


la fiecare 10 minute şi transmiterea datelor citite la distanţă. Având în vedere
intervalul mare de timp cuprins între două citiri succesive ale senzorului se
Exemplu
poate implementa o aplicaţie cu consum redus de energie care va apela la
punerea procesorului în mod SLEEP.
Pentru obţinerea temporizării dorite se va utiliza timerul 1 având ca sursă de
incrementare impulsurile provenite de la un oscilator extern de 32.768kHz
care va furniza baza de timp. Conform relaţiei (8.5), utilizând un raport de
predivizare de 1:4 prin incrementarea numărătorului de la 0 la valoarea
maximă pe 16 biţi (65535) se obţine o temporizare de 8 secunde. Astfel,
600/8 = 75 de intervale successive de 8 secunde vor asigura temporizarea
dorită de 10 minute.
Pentru a reduce consumul de energie al acestei aplicaţii, procesorul este pus în
mod SLEEP, fiind trezit la fiecare 8 secunde. Pentru a intra în acest mod de
lucru se utilizează instrucţiunea SLEEP. În mod SLEEP, oscilatorul principal
al microcontrolerului este oprit. Ieşirea din acest mod de funcţionare este
condiţionată de apariţia unei întreruperi. În aceste condiţii, trebuie activată

146
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

întreruperea timerului 1 prin setarea bitului TMR1IE din registrul PIE[1].


De asemenea, trebuie activate întreruperile provenite de la periferice prin
setarea bitului PEIE al registrului INTCON[6]. (vezi Capitolul 9)
Astfel, la fiecare 8 secunde procesorul va ieşi din modul SLEEP, se va şterge
bitul indicator de întrerupere TMR1IF, apoi se va incrementa un contor până
va ajunge la valoarea 75, care marchează scurgerea intervalului timp de 10
minute. În acest moment se vor citi datele de la senzor şi se vor transmite mai
departe cu ajutorul unei subrutine, al cărei cod nu are importanţă pentru acestă
aplicaţie. La revenirea din subrutină, procesorul intră din nou în modul
SLEEP şi ciclul de 10 minute se reia.

#include "p18f4455.inc"

CONTOR EQU 0x20

MAIN
movlw b’10101111’ ;configurare timer1
movwf T1CON ;oscilator ext., PS 1:4
bsf INTCON,PEIE ;întreruperi periferice
bsf PIE1,TMR1IE ;întrerupere timer1

clrf CONTOR ;şterg contor


clrf TMR1H ;şterg timer
clrf TMR1L

STAND_BY
sleep ;UCP în mod SLEEP
bcf PIR1,TMR1IF ;şterg flag întrerupere
incf CONTOR,f ;incrementez contor
movlw d’75’ ;contor=75 ? (10 min.)
cpfseq CONTOR ; da: citeşte senzor
bra STAND_BY ; nu: SLEEP

clrf CONTOR ;şterg contor


call Senzor ;citesc senzor
bra STAND_BY ;SLEEP

147
TEMPORIZĂRI HARDWARE

8.3 TIMER 2

8.3.1 Structura internă a timerului 2

Timerul 2 (Fig. 8.7) are la bază un numărător de 8 biţi care dispune de un predivizor şi
un postdivizor programabil. Timerul va număra întotdeauna impulsurile de tact interne
(FOSC/4). Spre deosebire de celelalte timere, timerul 2 oferă posibilitatea generării unei
întreruperi la atingerea unei valori prestabilite, nu la depăşirea capacităţii de numărare cum se
întâmpla în cazul timerului 0, 1 şi 3. Astfel, în structura timerului 2 există un bloc comparator
care compară permanent valoarea curentă a numărătorului (TMR2) cu valoarea stocată în
registrului PR2 (Period Register). La egalitatea celor două valori se generează un impuls care
va reseta timerul în ciclul instrucţiune următor. În funcţie de postdivizor, după ce s-au realizat
n comparări reuşite ( n = 1,16 ), se va seta bitul indicator de întrerupere TMR2IF din registrul
PIR1[1]. Dacă întreruperea timerului a fost activată (bitul TMR2IE=1) atunci în aceste
condiţii se va genera o întrerupere.

Fig. 8.7. Schema bloc a timerului 2 conform foii de catalog [15]

Din schema bloc a timerului prezentată în Fig. 8.7 se poate observa că regiştrii TMR2
şi PR2 sunt accesibili direct prin operaţii uzuale. Tactul de incrementare al registrului TMR2
este divizat prin intermediul predivizorului, a cărui valoare poate fi programată prin biţii
T2CKPS1 şi T2CKPS0 din registrul T2CON[1:0]. Registrul PR2 este încărcat cu o valoare
ce se compară cu valoarea registrului TMR2. Pentru stabilirea valorii postdivizorului se
utilizează biţii T2OUTPS3:T2OUTPS0 ai registrului T2CON[6:3]. Atingerea celor n
comparări reuşite poate fi interogată prin bitul TMR2IF al registrului PIR1[1].
Utilizarea timerului 2 nu se rezumă doar la realizarea temporzărilor. Capacitatea sa de
a semnala o egalitate între două valori prin intermediul comparatorului implementat este o
caracteristică utilizată de modulele de comunicaţie serială sincronă sau de modulul PWM.

148
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

8.3.2 Configurarea timerului 2

Paşii de configurare pentru utilizarea timerului 2 se bazează pe conţinutul registrului


de configurare T2CON. Structura acestui registru este prezentată în Fig. 8.8 şi este urmată de
descrierea biţilor.

7 0
- T2OUTPS3 T2OUTPS2 T2OUTPS1 T2OUTPS0 TMR2ON T2CKPS1 T2CKPS0
Fig. 8.8. Registrul T2CON: Timer2 Control Register

Bit 7 Neutilizat
Biţii 6-3 T2OUTPS3:T2OUTPS0 – Biţi de selecţie a valorii de postdivizare
1111 = Raport de postdivizare 1:16
1110 = Raport de postdivizare 1:15
...
0001 = Raport de postdivizare 1:2
0000 = Raport de postdivizare 1:1
Bit 2 TMR2ON – Bit de Pornire / Oprire Timer2
1 = Pornire Timer2
0 = Oprire Timer2
Biţii 1-0 T2CKPS1:T2CKPS0 – Biţi de selecţie a valorii de predivizare
1x = Predivizor 16
01 = Predivizor 4
00 = Predivizor 1

Durata temporizării realizate cu timerul 2 se poate determina pe baza relaţiei:


4
Tdorita = Predivizor ⋅ (PR 2 + 1) ⋅ Postdivizor ⋅ (8.6)
FOSC
unde:
- Tdorita este durata temporizării dorite

- Predivizor este valoarea predivizorului (se vor considera valorile predefinite posibile
Predivizor ∈ {1,4,16} )
- PR2 este valoarea de 8 biţi înscrisă în registrul PR2 utilizat pentru realizarea
comparaţiei

149
TEMPORIZĂRI HARDWARE

- Postdivizor este valoarea postdivizorului (se vor considera valorile predefinite posibile
Postdivizor ∈ {1,2,3,...,16} )
- 4/FOSC este perioada impulsurilor numărate. Tactul de execuţie al instrucţiunilor.

Etapa de configurare, a Timerului 2 presupune parcurgerea următorior paşi:


• oprirea timerului (bitul TMR2ON=0, registrul T2CON[2]) ;
• selectare predivizor (biţii T2CKPS1:T2CKPS0, registrul T2CON[1:0]);
• selectare postdivizor (biţii T2OUTPS3:T2OUTPS0, registrul T2CON[6:3]);
• încărcare registru PR2
• opţional – configurarea modulelor CCP
• ştergerea flag-ului de semnalizare (bitul TMR2IF, registrul PIR1[1]);
• pornirea timerului (bitul TMR2ON, registrul T2CON[2]).[8]

Utilizarea timerului 2 pentru realizarea unei temporizări este exemplificată în continuare.

Să considerăm o implementare a unui ceas. Pentru această aplicaţie este


necesară o înterupere care să apară de 100 de ori în fiecare secundă. Această
temporizare de 1ms se va folosi ca bază de timp în aplicaţie. Presupunând că
Exemplu
microcontrolerul este dotat cu un oscilator cu FOSC=20MHz, prin alegerea
unui raport de predivizare de 1:4, a valorii din registrul PR2 = 249 şi a
raportului de postdivizare de 1:5 se obţine temporizarea dorită de
1ms=0.2μs·4·(249+1)·5.
Codul următor cuprinde iniţializarea Timerului 2 pentru realizarea unei
temporizări cu durata de 1ms.

movlw b’00100101’ ;prediv. 1:4, postdiv. 1:5


movwf T2CON ;timer 2 pornit
movlw d’249’
movwf PR2

150
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

8.4 TIMER 3

Timerul 3 este o clonă a timerului 1 în care T3 înlocuieşte T1 în denumirea biţilor din


regiştrii SFR corespunzători şi în denumirea bitului indicator de întrerupere.

Fig. 8.9. Schema bloc a timerului 3 conform foii de catalog [15]

Există totuşi câteva diferenţe în structura registrului de control a timerului 3 (T3CON),


care sunt marcate în Fig. 8.10 şi în descrierea biţilor care o urmează. Aceste diferenţe (biţii
T3CCP2 şi T3CCP1), nu influenţează funcţionarea timerului în implementarea
temporizărilor, ele fiind necesare atunci când timerul se utilizează în asociere cu modulele
CCP (pentru detalii suplimentare vezi capitolul dedicat modulelor CCP).

7 0
RD16 T3CCP2 T3CKPS1 T3CKPS0 T3CCP1 T3SYNC TMR3CS TMR3ON
Fig. 8.10. Registrul T3CON: Timer3 Control Register

Bit 7 RD16 – selectarea modului de acces la regiştrii timerului


1 = acces atomic
0 = acces succesiv prin două operaţii de 8 biţi
Bit 6 şi 3 T3CCP2:T3CCP1 – pentru utilizarea cu modulele CCPx
1x = Timer3 utilizat ca bază de timp pentru CCP1 şi CCP2
01 = Timer1 utilizat ca bază de timp pentru CCP1, Timer3 pentru CCP2
00 = Time1 utilizat ca bază de timp pentru CCP1 şi CCP2

151
TEMPORIZĂRI HARDWARE

Biţii 5-4 T3CKPS1:T3CKPS0 – Biţi de selecţie a valorii de predivizare


11 = Raport de predivizare 1:8
10 = Raport de predivizare 1:4
01 = Raport de predivizare 1:2
00 = Raport de predivizare 1:1
Bit 2 T3SYNC – Activarea/dezactivarea sincronizării impulsurilor externe cu tactul
intern
Dacă TMR3CS = 1
1 = Fără sincronizare
0 = Sincronizare
Dacă TMR3CS = 0
Bitul este ignorat. Timer1 utilizează impulsuri interne pentru incrementare.
Bit 1 TMR3CS – Bit selecţie sursă tact de incrementare
1 = impulsuri externe (front crescător pe pinul RC0/T1OSO/T13CKI)
0 = impulsuri interne (tactul de execuţie al instrucţiunilor FOSC/4)
Bit 0 TMR3ON – Bit de Pornire / Oprire Timer3
1 = Pornire Timer3
0 = Oprire Timer3

Când timerul 3 este configurat să utilizeze o sursă externă pentru impulsurile


numărate, aceasta provine de pe pinul T13CKI, utilzat în comun şi de timerul 1.
Dacă oscilatorul timerului 1 este activat (bitul T1OSCEN=1 din registrul
T1CON[3]) atunci acesta va furniza impulsurile externe şi pentru timerul 3, dacă acesta din
urmă este configurat pentru a număra impulsuri externe. Acest lucru nu este condiţionat de
utilizarea timerului 1 pentru numărarea impulsurilor externe.

152
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Deşi microcontrolerul este dotat cu mai multe timere, în general, acestea se


utilizează pentru sarcini diferite după cum urmează:

Concluzii - Timer 0 – aplicaţii periodice, temporizări, eşantionări


- Timer 1,3 – aplicaţii cu consum redus de energie, aplicaţii care
utilizează circuitele de comparare şi captură
- Timer 2 – generarea semnalelor PWM şi în realizarea comunicaţiilor
seriale sincrone.
În cazul aplicaţiilor care necesită mai multe temporizări se recomandă
utilizarea unei singure baze de timp pentru acestea.
Este foarte importantă înţelegerea modului de utilizare şi a rolului pe care îl are
bitul indicator de întrerupere (TMRxIF) care semnalizează expirarea
temporizărilor realizate cu ajutorul timerelor:
- acest bit se setează în mod automat la depăşirea capacităţii de numărare
a timerelor (excepţie, în cazul timerului 2 bitul se setează la egalitatea
valorilor din TMR2 şi PR2)
- bitul poate fi interogat pentru a identifica momentul în care a expirat
temporizarea dorită
- bitul poate genera o întrerupere care să aibă o rutină de deservire
- bitul trebuie şters manual din program în urma fiecărei întreruperi,
pentru a putea prinde următorul eveniment (a următoarei temporizări).
Dacă bitul rămâne setat dupa prima întrerupere, nu avem de unde şti
când se produce următoarea întrerupere (Fig. 8.11).

Fig. 8.11. Efectul incrementării asupra bitului TMR0IF

În concluzie, timerele sunt circuite de temporizare implementate hardware în


structura microcontrolerului. Cu ajutorul lor pot fi implementate funcţii de
temporizare, numărare sau funcţii mai complexe prin asocierea lor cu alte
module ale microcontrolerului. Indiferent de funcţiile implementate timerele
reprezintă o componentă esenţială în structura oricărui sistem de calcul bazat
pe micrcontrolere.

153
TEMPORIZĂRI HARDWARE

1. Ce deosebiri există între temporizările software şi cele hardware?


2. Discutaţi principiul de funcţionare al Timerului 0.
3. Ce înţelegeţi prin accesul atomic la regiştrii timerului?
Întrebări de
4. Care este durata maximă a temporizării realizate cu ajutorului
autoevaluare
timerului 0, în cazul utilizării FOSC = 48MHz? Cum s-ar implementa
o întârziere cu durata de 1min în cazul acesta?
5. Ce rol are predivizorul la timere?
6. Ce rol îndeplineşte bitul TMRxIF?
7. Cum se calculează şi care este valorea de iniţializare a
TMR0H:TMR0L pentru implementarea unei temporizări cu durata
de 100ms în cazul utilizării FOSC = 48MHz?
8. Care este codul utilizat pentru iniţializarea timerului 2 în vederea
realizării unei temporizări cu durata de 10ms în cazul FOSC =
4MHz?
9 Care sunt etapele necesare pentru iniţializarea timerului 0?
10 Ce se întâmplă la apelul instrucţiunii SLEEP?

Flag
Bit indicator
Termeni Întrerupere
esenţiali Mecanism prin care un periferic poate semnaliza procesorului despre
schimbarea stării sale
Predivizor
Circuit în structura timerelor care permite incrementarea la fiecare n
fronturi ale semnalului de tact
Postdivizor
Circuit în structura timerului 2 care permite activare bitului indicator de
întrerupere la fiecare n comparaţii reuşite între PR2 şi TMR2.
PWM
Pulse Width Modulation. Modulare în laţime a impulsurilor
Tact de incrementare
Semnal pe a cărui front se incrementează valoarea unui numărător
Timer
Circuit de temporizare

154
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

9. SISTEMUL DE ÎNTRERUPERI

Introducere
Obiective
9.1 INTEROGARE ŞI ÎNTRERUPERI
Cuprins
9.2 TRATAREA ÎNTRERUPERILOR
9.2.1 Modul compatibilitate (IPEN=0)
9.2.2 Modul prioritate (IPEN=1)
9.3 UTILIZAREA ÎNTRERUPERILOR
9.3.1 Configurarea întreruperilor
9.3.2 Recomandări privind rutinele de tratare a
întreruperilor
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

155
SISTEMUL DE ÎNTRERUPERI

Până acum, ne-am obişnuit că pentru a verifica starea unui periferic


trebuie testat în mod repetat perifericul respectiv (ex. un anumit bit
indicator). Din această cauză, implementarea unor programe cu o
Introducere
complexitate ridicată poate fi problematică. Dacă programul ar putea fi
anunţat de modificarea stării perifericului atunci lucrurile s-ar simplifica şi
programul în cauză s-ar putea ocupa de alte procesări până la sosirea
evenimentului. Procesul de anunţare se realizează prin sistemul de
întreruperi.
După parcurgerea acestui capitol cursantul va trebui:
- să înţeleagă nevoia unui sistem de întreruperi
- să înţeleagă secvenţa de evenimente care se produc la apariţia unei
Obiective întreruperi
- să înţeleagă rolul celor trei biţi principali care controlează
întreruperile
- să înţeleagă sistemul de priorităţi
- să poată configura utilizarea întreruperilor pentru anumite
periferice
- să poată scrie o rutină de tratare a înteruperii respectând
recomandările de bune practici privind conţinutul acestora

9.1 INTEROGARE ŞI ÎNTRERUPERI

Există două metode care ne permit să determinăm dacă starea unui perifiric s-a
modificat: prin interogare sau prin întrerupere.
Pentru a înţelege mai bine diferenţa între cele două metode să considerăm următorul
exemplu.

Să considerăm unui sistem telefonic.


Să presupunem că există o reţea telefonică în care utilizatorul trebuie periodic,
de exemplu la fiecare 5 minute, să ridice receptorul (întrebând/interogând: E
Exemplu
cineva acolo?) pentru a afla dacă se găseşte cineva la celălalt capăt al firului.
Având în vedere intervalul de timp considerat pentru interogare (o dată la 5
minute), cel care face apelul s-ar putea plictisi şi să închidă. Acest lucru s-ar
putea evita prin creşterea ratei de interogare, de la 5 minute la 1 minut, dar în

156
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

aceste condiţii utilizatorul şi-ar petrece timpul mai mult lângă telefon şi în
funcţie de popularitatea sa ar recepţiona doar câteva apeluri într-o zi. Totuşi
99% din timp ar fi pierdut.
Un asemenea sistem telefonic, bazat pe principiul interogării, deşi este posibil
pare cel puţin frustrant. În realitate se foloseşte un sistem telefonic bazat pe
întreruperile cauzate de soneria de apel. Această variantă mai eficientă are şi
ea costurile ei, puse în evidenţă de complexitatea sistemului telefonic care este
mai pronunţată pe partea de semnalizare decât pe partea de voce. Există o altă
problemă: utilizatorul (ex. procesorul) nu are de unde şti când va primi un
apel. Bineînţeles acest lucru se va produce întotdeauna în cele mai nepotrivite
momente (ex. în mijlocul realizării unor activităţi). Astfel utilizatorul ar trebui
să renunţe la activitatea pe care o făcea şi să răspundă la telefon pentru ca la
încheierea apelului să revină înapoi la munca pe care a întrerupt-o.[6]

Marea majoritate a microcontrolerelor dispun de capacitatea de a se ocupa cu


evenimentele care produc întreruperea funcţionării lor obişnuite. În cazul microcontrolerelor
sursa acestor evenimente poate fi internă (ex. depăşirea capacităţii de numărare a unui timer)
sau externă (ex. un anumit front pe un pin al microcontrolerului).
Microcontrolerele PIC pot răspunde la cererile de întrerupere care provin de la o gamă
variată de periferice: timere, module de comunicaţie, convertor A/D etc. De exemplu, în cazul
microcontrolerului PIC18F4455 se pot identifica două categorii de surse de întreruperi:
- Externe.
o Trei linii de intrare distincte prin intermediul pinilor INT0, INT1, INT2.
Aceste linii de intrare corespund biţilor 0, 1 şi 2 ai portului B.
o Biţii [7-4] ai portului B. Orice modificare a acestor biţi de intrarea va genera o
întrerupere
- Interne.
o Cele 4 timere. În cazul timerelor 0,1,3 la depăşirea capacităţii de numărare se
poate genera o întrerupere, iar în cazul timerului 2 la realizarea a n comparări
reuşite (vezi capitolul 8)
o Modulele CCP la realizarea unei capturi sau a unei comparaţii reuşite
o Convertorul A/D la terminarea unei conversii
o Modulul de comunicaţie EUSART la recepţia sau transmisia unui caracter
o Etc.[15]

157
SISTEMUL DE ÎNTRERUPERI

Ţinând cont de caracterul aleator al acestora, de fiecare dată răspunsul procesorului la


aceste cereri de întrerupere se va realiza după cum urmează:
1. se termină execuţia instrucţiunii curente;
2. se salvează adresa de revenire. Starea numărătorului de program (PC) se salvează
în stiva adreselor de revenire. Anumite microcontrolere PIC permit şi salvarea
contextului în stiva rapidă;
3. se execută rutina de tratare a întreruperii până la întâlnirea instrucţiunii de
revenire RETFIE;
4. se reface adresa salvată şi se reia execuţia programului din locul unde a fost
întrerupt.

Astfel, întreruperea reprezintă mecanismul de suspendare a firului de execuţie la


apariţia unui eveniment. Din punct de vedere fizic evenimentul respectiv, denumit cerere de
întrerupere, va genera un semnal care va determina execuţia celor patru etape amintite
anterior.[5,6,8,10]

9.2 TRATAREA ÎNTRERUPERILOR

Felul în care sunt deservite cererile de întrerupere diferă puţin de la un procesor la


altul. În cazul familiei de microcontrolere PIC18 sunt definite două moduri de întreruperi.
Acestea sunt:

Modul compatibilitate (IPEN = 0)


Acesta este modul implicit de funcţioare al sistemului de întreruperi, fiind activat la
resetarea microcontrolerului prin punerea pe 0 a bitului IPEN (Interrupt Priority Enable) din
registrul RCON[7]. În acest mod de funcţionare fiecare sursă de întrerupere poate fi activată /
dezactivată individual, dar nu există priorităţi. La apariţia cererii de întrerupere execuţia va fi
transferată către rutina de tratare a întreruperii, dacă nu se execută deja această rutină, care are
adresa de început 0x0008 în memoria program. Această adresă poartă denumirea de vector de
întrerupere.

158
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Modul prioritate (IPEN = 1)


Prin setarea bitului IPEN din registrul RCON[7], pentru fiecare sursă de întrerupere, în
afara întreruperii INT0, se poate configura unul din cele două nivele de priorităţi: ridicată sau
scăzută.
La apariţia unei întreruperi cu prioritate ridicată, cu condiţia ca procesorul să nu
execute deja rutina de tratare a înteruperii cu prioritate ridicată, execuţia se transferă către
instrucţiunea aflată la vectorul de întrerupere ridicată de la adresa 0x0008 din memoria
program. Este aceeaşi adresă utilizată şi în cazul modului compatibilitate.
La apariţia unei întreruperi cu prioritate scăzută, cu condiţia ca procesorul să nu
execute deja o altă rutină de tratare a înteruperii (cu prioritate ridicată sau scazută), execuţia
se transferă către instrucţiunea aflată la vectorul de întrerupere scăzută de la adresa 0x0018
din memoria program.

9.2.1 Modul compatibilitate (IPEN = 0)

Acest mod de lucru al sistemului de priorităţi s-a păstrat pentru a asigura


compatibilitatea cu versiunile anterioare ale microntrolerelor PIC. Tot pentru a păstra
compatibilitate cu versiunile anterioare, sursele de întreruperi ale microcontrolerului sunt
împărţite în două grupuri logice:
- întreruperile provenite de la periferice. Acestea cuprind întreruperile provenite de la
convertorul A/D, modulele CCP, EUSART, Timer1, 2, 3 etc.
- întreruperile principale (core interrupts). Acestea cuprind un grup mai restrâns de
întreruperi, anume cele provenite de la Timerul 0 şi liniile de intrare INT0, INT1,
INT2, RB.
Utilizarea întreruperilor provenite de la periferice poate fi activată/dezactivată prin
intermediul bitului PEIE (Peripheral Interrupt Enable) din registrul INTCON[6]. Setarea
acestui bit activează acest grup de întreruperi, iar resetarea sa le dezactivează. Acest bit se
utilizează doar în cazul modului compatibilitate al sistemului de întreruperi când nu sunt
folosite priorităţile.
În modul de lucru compatibilitate controlul fiecărei întreruperi se realizează prin doi
biţi:
- xxxIF (xxx interrupt flag): un bit indicator care se setează la apariţia unui
eveniment de întrerupere
- xxxIE (xxx interrupt enable): un bit de activare/dezactivare care permite selectarea
individuală a surselor de întrerupere utilizate

159
SISTEMUL DE ÎNTRERUPERI

În cazul întreruperilor principale, cei doi biţi asociaţi fiecărei surse de întrerupere se
găsesc în regiştrii INTCON, INTCON2 şi INTCON3.
În cazul întreruperilor provenite de la periferice, flagurile de întrerupere se găsesc în
regiştrii PIR1 şi PIR2, iar biţii de activare a întreruperilor se găsesc în regiştrii PIE1 şi
PIE2.

În Fig. 9.1 se prezintă o schemă simplificată a logicii de întreruperi în cazul modului


compatibilitate.

Fig. 9.1. Logica de întreruperi în modul compatibilitate

Analizând figura de mai sus, putem urmări cursul evenimentelor în cazul în care
timerul 1 depăşeşte capacitatea sa de numărare care duce la setarea bitului indicator de
întrerupere TMR1IF din registrul PIR1[0]. Dacă bitul TMR1IE din registrul PIE1[0] este
setat atunci cererea de întrerupere va produce un 1 logic la ieşirea porţii logice SAU. Având în
vedere că timerul 1 face parte din grupul întreruperilor provenite de la periferice, dacă bitul
PEIE este 1 şi bitul GIE este tot 1 atunci cererea de întrerupere va iniţia răspunsul din Fig.
9.2. Bitul GIE (Global Interrupt Enable) din registrul INTCON[7] este bitul care permite
activarea şi dezactivarea tuturor surselor de întrerupere.

160
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 9.2. Răspunsul la cererea de întrerupere în modul compatibilitate

Modul de deservire al întreruperilor prezentat în Fig. 9.2 pune în evidenţă următoarele


etape:
1. În timpul fiecărui ciclu instrucţiune, în tactul Q4 procesorul verifică starea liniei de
întrerupere INT. Chiar dacă a apărut o cerere de întrerupere instrucţiunea activă se
execută până la capăt.
2. Dacă nu există o cerere de întrerupere se execută instrucţiunea următoare şi procesul
se repetă din nou.
3. Dacă există o cerere de întrerupere atunci următoarele trei cicluri instrucţiune sunt
utilizate pentru a transfera execuţia spre prima instrucţiune a rutinei de tratare a
întreruperii de la adresa 0x0008 din memoria program. Timpul necesar pentru acest
lucru reprezintă timpul de răspuns la o întrerupere.
4. În timpul acestei perioade de latenţă procesorul realizează următoarele:
a. se dezactivează sistemul de întreruperi prin resetarea bitului GIE. Astfel se
blochează celelalte întreruperi care ar putea apărea în timpul deservirii
întreruperii active.
b. Valoarea numărătorului de program (adresa de revenire) este salvată pe stivă.
c. Simultan se realizează salvarea regiştrilor WREG, BSR, STATUS în stiva
rapidă. Conţinutul acestor regiştri poate fi refăcut dacă instrucţiunea RETFIE
utilizează flagul FAST (vezi Capitolul 5). Stiva rapidă este comună cu cea
utilizată de subrutinele apelate rapid (CALL Subrutina, FAST) şi apariţia
întreruperii va suprascrie întotdeauna conţinutul acesteia.

161
SISTEMUL DE ÎNTRERUPERI

d. Prima instrucţiune a rutinei de tratare a înteruperii va fi întotdeauna


instrucţiunea din memoria program plasată la adresa 0x0008. Ultimul pas al
acestei secvenţe constă în încărcarea numărătorului de program cu adresa
vectorului de întrerupere. De obicei această înstrucţiune este un GOTO sau un
BRA către zona de program unde e definit corpul rutinei de tratare a înteruperii.
5. La fel ca şi în cazul subrutinelor obişnuite şi rutina de tratare a înteruperii trebuie să se
încheie cu o instrucţiune de revenire, mai exact instrucţiunea RETFIE. La execuţia
acestei instrucţiuni, numărătorul de program va fi refăcut cu adresa salvată în stivă,
bitul GIE va fi din nou setat, iar dacă apelul instrucţiunii RETFIE utilizează flagul
FAST se va reface şi contextul salvat în stiva rapidă.[6]

9.2.2 Modul prioritate (IPEN = 1)

În acest mod de funcţioare al sistemului de întreruperi se pot seta individual, pentru


fiecare sursă de întreruperi, două nivele de priorităţi: prioritate ridicată şi prioritate scăzută. În
Fig. 9.1 s-a putut observa cum fiecare sursă de întreruperi îşi poate seta flagul de întrerupere
care intră într-o poartă logică ŞI împreună cu bitul de activare/dezactivare corespunzător. În
cazul modului prioritate, logica din Fig. 9.1 este dublată cu un set de porţi logice ŞI cu trei
intrări care activează linia de întrerupere ridicată (INT_H) şi un set de porţi logice ŞI cu trei
intrări care activează linia de întrerupere scăzută (INT_L). A treia intrare a acestor porţi este
reprezentată de bitul
- xxxIP (xxx Interrupt Priority): bit de prioritate. 1 = prioritate ridicată, 0 = prioritate
scăzută

În cazul porţilor ŞI care activează linia de prioritate ridicată bitul xxxIP intră direct,
iar în cazul porţilor ŞI care activează linia de prioritate scăzută bitul xxxIP intră inversat.
Bitul de prioritate pentru întreruperile principale poate fi accesat prin intermediul regiştrilor
INTCON2 şi INTCON3, excepţie face întrerupere INT0 de pe pinul RB0 care are întotdeauna
prioritate ridicată. În cazul întreruperilor provenite de la periferice biţii de prioritate pot fi
accesaţi prin intermediul regiştrilor IPR1 şi IPR2.
În Fig. 9.3 se prezintă o schemă simplificată a logicii de întreruperi în cazul modului
prioritate.

162
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 9.3. Logica de întreruperi în modul prioritate

Pentru exemplificare să analizăm cazul întreruperii timerului 1. La depăşirea


capacităţii sale de numărare bitul TMR1IF este setat. Dacă această întrerupere a fost activată
prin setarea bitului TMR1IE atunci se poate genera o cerere de întrerupere validă. În funcţie
de starea bitului TMR1IP din registrul IPR1[0] se poate activa fie linia corespunzătoare
întreruperii de nivel ridicat (TMR1IP=1) fie linia corespunzătoare întreruperii de nivel scăzut
(TMR1IP=0).
Toate prioriţile de un anumit nivel pot fi activate sau dezactivate în grup prin setarea
sau resetarea biţilor GIEH (pentru priorităţi ridicate) şi GIEL (pentru priorităţi scăzute). Bitul
GIEH din registrul INTCON[7] este multiplexat cu bitul GIE utilizat în modul

163
SISTEMUL DE ÎNTRERUPERI

compatibilitate. De asemenea, bitul GIEL din registrul INTCON[6] este multiplexat cu bitul
PEIE. În Tabelul 9.1 se prezintă modul de utilizare al acestor biţi.

Tabel 9.1. Biţi de configurare ai sistemului de întreruperi


Mod de lucru IPEN GIEH GIEL GIE PEIE Descriere
0 0/1 Toate întreruperile sunt dezactivate
Întreruperile provenind de la
Compatibilitate 0 x x 1 0
periferice sunt dezactivate
1 1 Toate întreruperile sunt activate
1 1 Toate întreruperile sunt activate
Întreruperile cu prioritate ridicată
Prioritate 1 1 0 x x
sunt activate
0 0/1 Toate întreruperile sunt dezactivate

Comparând diagrama de activitate din Fig. 9.2 cu cea din Fig. 9.4 se poate observă că
răspunsul procesorului la apariţia unei întreruperi activate este similar cu cel din funcţionarea
în modul compatibilitate. Totuşi, două difierenţe majore pot fi identificate:
1. Întreruperile de prioritate ridicată, având vectorul de întrerupere la adresa
0x0008, pot întrerupe întreruperile de prioritate scăzută în curs de deservire.
Nici o întrerupere de prioritate ridicată în curs de deservire nu poate fi
întreruptă.
2. Întreruperile de prioritate ridicată au vectorul de întrerupere la adresa
0x0018 în memoria program.

Fig. 9.4. Răspunsul la cererea de întrerupere în modul prioritate

164
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Ambele tipuri de întrerupere determină salvarea numărătorului de program în stivă. În


acest fel rutina de tratare a întreruperii de prioritate scăzută poate fi reluată dacă în timp ce
aceasta este deservită apare o întrerupere de prioritate ridicată. Deoarece contextul este salvat
în singura stivă rapidă disponibilă, pentru evitarea inconsistenţei datelor după refacerea
contextului se recomandă realizarea unei salvări manuale a contextului în memoria RAM la
nişte locaţii special alese pentru acest scop.

Indiferent de modul de funcţionare al sistemului de întreruperi semnalul nemascat de


ieşire poate fi utilizat pentru a trezi procesorul din modul SLEEP.
De asemenea, în toate cazurile de funcţionare, apariţia unui eveniment va conduce la
setarea automată a bitului indicator de întrerupere (xxxIF). Acest lucru se va întâmpla chiar
dacă întreruperea respectivă a fost dezactivată (xxxIE=0). În majoritatea cazurilor, bitul
xxxIF odată setat va rămâne pe 1 până va fi şters din program. Din această cauză este foarte
important ca înainte a ieşirii din rutina de tratare a întreruperii să se şteargă bitul indicator de
întrerupere. Dacă nu se realizează acest lucru, rutina de tratare a întreruperi va fi reluată din
nou imediat după revenirea din execuţia anterioară şi acest lucru se va produce la infinit.

9.3 UTILIZAREA ÎNTRERUPERILOR

9.3.1 Configurarea întreruperilor

De regulă, paşii care trebuie urmaţi pentru configurarea întreruperilor sunt următorii:
- activarea/dezactivarea priorităţilor (bitul IPEN, registrul RCON[7]);
- activarea/dezactivarea întreruperilor provenite de la periferice (bitul PEIE, registrul
INTCON[6]);
- dacă bitul IPEN = 1, setarea priorităţii pentru sursa de întrerupere utilizată (bitul
xxxIP);
- ştergerea indicatorului corespunzător sursei de întrerupere configurate (bitul xxxIF);
- activarea întreruperii corespunzătoare sursei configurate (bitul xxxIE);
- setarea bitului global de întrerupere (bitul GIE, registrul INTCON[6], în modul
compatbilitate sau biţii GIEH şi GIEL, registrul INTCON[7,6] în modul
prioritate).[8]

165
SISTEMUL DE ÎNTRERUPERI

9.3.2 Recomandări privind rutinele de tratare a întreruperilor

Indiferent de numărul surselor de întrerupere utilizate de o aplicaţie există doar una


sau două rutine de tratare a întreruperilor, în funcţie de modul de funcţionare ales. În aceste
condiţii, rutina de tratare trebuie să identifice evenimentul care a dus la execuţia ei. Acest
lucru se face prin testarea succesivă a biţilor indicatori de întrerupere (xxxIF) pentru toate
sursele de întrerupere activate în aplicaţie. De asemenea, rutina de tratare a întreruperii trebuie
să ţină cont şi de aspectele referitoare la salvarea contextului şi resetarea bitului indicator de
întrerupere, amintite în paragraful 9.2.2. Astfel, rutina de întrerupere trebuie să execute
următoarele sarcini:
- salvarea contextului (regiştrii WREG, BSR şi STATUS). În funcţie de aplicaţie, trebuie
analizată oportunitatea utilizării stivei rapide;
- testarea sursei de întrerupere (testarea validării condiţiei xxxIF=1) pentru
întreruperile activate;
- tratarea întreruperii pentru fiecare sursă apărută;
- ştergerea biţilor indicatori de întrerupere (xxxIF=0);
- refacerea contextului (regiştrii STATUS, BSR şi WREG);
- revenirea din rutina de tratare a întreruperii (instrucţiunea RETFIE).

Pe lângă sarcinile amintite mai sus se recomandă ca rutinele de tratare a întreruperilor


să fie scurte şi să nu conţină procesări. De obicei, se practică salvarea evenimentului într-o
variabilă care să fie utilizată în bucla principală. În general, când apare o întrerupere se preiau
date, care se adună în programul principal unde se prelucrează. O altă recomandare vizează
interacţiunea cu un singur periferic în cadrul rutinelor de tratare a întreruperilor. În cazul în
care aplicaţia utilizează doar două surse de întrerupere se recomandă utilizarea celor două
nivele de prioritate în deservirea lor.

Pentru a exemplifica modul de configurare şi implementare a întreruperilor se


va utiliza secvenţa următoare de program în cadrul căreia s-a considerat
generarea unei întreruperi corespunzătoare Timerului 0 (având flag-ul
Exemplu
TMR0IF):

166
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

#include “P18F4455.INC”

ORG 0x00

GOTO MAIN ;salt la programul principal

; 0x008 dacă nu se utilizează BOOT-LOADER


; 0x808 dacă se utilizează BOOT-LOADER
ORG 0x008

; Salt la rutina de tratare a întreruperii


GOTO ISR

[…]

ISR:
BTFSS INTCON, TMR0IF ;testare sursa întrerupere
RETFIE
[…] ;tratare întrerupere
BCF INTCON, TMR0IF ;Resetarea flagului
RETFIE ;Revenire din rutină
MAIN:
BCF INTCON, TMR0IF ;Resetare flag Timer 0
BCF RCON, IPEN ;Dezactivare priorităţi
BSF INTCON, TMR0IE ;Activare întrerupere Timer 0
BSF INTCON, GIE ;Activarea întreruperilor

[…]

END

Secvenţa următoare de program exemplifică utilizarea vectorilor de


întrerupere cu mai multe priorităţi.

#include “P18F4455.INC”

ORG 0x00
GOTO MAIN

ORG 0x08 ;vector întrerupere ridcată


GOTO ISR_HIGH

ORG 0x018 ;vector întrerupere scăzută


GOTO ISR_LOW

ISR_HIGH: ;rutina de tratare a întreruperii


[…] ;cu prioritate ridicată
RETFIE

167
SISTEMUL DE ÎNTRERUPERI

ISR_LOW: ;rutina de tratare a întreruperii


[…] ;cu prioritate scăzută
RETFIE

MAIN: ;programul prinicpal


[…]
END

Sistemul de întreruperi este acea parte din structura microcontrolerului


care permite detecţia unor evenimente externe sau interne şi declanşarea

Concluzii unor acţiuni pentru tratarea lor. Astfel de evenimente pot fi: depăşirea
capacităţii de numărare a unui timer, terminarea unei conversii analog
digitale etc. Întreruperile permit microcontrolerului să reacţioneze rapid la
aceste evenimente, să se sincronizeze cu ele şi să le trateze în timp util. O
alternativă la sistemul de întreruperi ar fi testarea periodică prin program
(prin interogare) a tuturor indicatorilor de stare şi a semnalelor de intrare.
Această soluţie este ineficientă în cazul în care numărul de elemente care
trebuie testate este mare.
Pe lângă sistemul de întreruperi moştenit de la predecesorii săi,
microcontrolerul PIC18F4455 utilizează un sistem de priorităţi pentru a
stabili ordinea de deservire a cererilor concurente de întrerupere. Pentru
cele două nivele de priorităţi disponibile (prioritate ridicată şi prioritate
scăzută) se poate defini câte o rutină de tratare a întreruperii. Adresele de
inceput ale acestor rutine poartă denumirea de vectori de întrerupere şi au
nişte valori bine stabilite (0x0008 şi 0x0018).
În funcţie de cerintele aplicaţiei anumite surse de întrerupere sau anumite
grupuri de întreruperi pot fi invalidate.
La activarea unui bit indicator de întrerupere se testează dacă întreruperea
resepectivă este activă şi dacă nu sunt în curs de deservire alte întreruperi
mai prioritare; în caz afirmativ are loc întreruperea temporară a secvenţei
curente de execuţie, se salvează pe stivă adresa instrucţiunii urmatoare şi
se face salt la rutina de tratare a întreruperii. După executia rutinei de
întrerupere se revine la secvenţa întreruptă prin încarcarea în numărătorul
de program a adresei salvate pe stivă.

168
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1. Ce se întâmplă la apariţia unei întreruperi?


2. Discutaţi implementarea sistemului de priorităţi al întreruperilor?
3. Care sunt cei trei biţi care controlează funcţionarea întreruperilor?
Întrebări de
4. De ce este importantă salvarea contextului şi cum se realizează
autoevaluare
acest lucru în cadrul sistemului de întreruperi?
5. Discutaţi diferenţa între interogare şi întrerupere.
6. Care sunt etapele iniţializării întreruperilor?

Cerere de întrerupere
Semnal dat de un periferic care indică un eveniment
Termeni CCP
esenţiali Modul de comparare-captură-PWM
EUSART
Enhanced Universal Synchronous Asynchronous Receiver Transmitter.
Modul de comunicaţie serială
Flag
Bit indicator
Interogare
Testarea periodică prin program a biţilor indicatori de stare pentru a afla
despre apariţia unui eveniment
Întrerupere
Mecanismul de suspendare a firului de execuţie la apariţia unui eveniment
şi de execuţie a unei rutine de tratare a întreruperii
Rutină de tratare a întreruperii
Secvenţă de cod care se execută la apariţia unei întreruperi
SLEEP
Mod de funcţionare cu consum redus caracterizat prin oprirea
oscilatorului principal al microcontrolerului.
UCP
Unitate Centrală de Prelucrare
Vector de întrerupere
Adresa primei instrucţiuni a rutinei de tratare a întreruperii
Timer
Circuit de temporizare

169
CONVERTORUL ANALOG-DIGITAL

10. CONVERTORUL ANALOG-DIGITAL

Introducere
Obiective
10.1 PRINCIPIUL DE FUNCŢIONARE AL CONVERTORULUI
Cuprins
ANALOG-DIGITAL
10.2 CONFIGURAREA MODULULUI DE CONVERSIE A/D
10.2.1 Rolul şi structura regiştrilor de control
10.2.2 Etapa de configurare
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

170
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Microcontrolerele au fost concepute pentru a interacţiona cu mediul


exterior, care, în esenţa lui, este alcătuit din semnale analogice (sunet,
căldură, iluminare etc). Astfel, comunicarea dintre microcontroler şi
Introducere
lumea exterioară nu se poate realiza doar prin intermediul unor canale cu
două nivele de tensiune (porturile de intrare-ieşire digitale). Există
numeroase situaţii în care date de natură analogică, preluate de la diverse
dispozitive sau senzori, necesită o prelucrare digitală. Într-un asemenea
context se utilizează convertoarele analog-digitale (A/D) care transformă
nivelele de tensiune analogice în echivalentul lor digital (secvenţe de biţi)
care poate fi utilizat cu uşurinţă în prelucrările ulterioare.
Majoritatea microcontrolerelor PIC au în dotare convertoare analog-
digitale multicanal, iar în acest capitol ne vom opri asupra aspectelor
specifice utilizării acestor module.
După parcurgerea acestui capitol cursantul va trebui:
- să înţeleagă principiul de realizare al conversiilor analog-digitale
- să înţeleagă diferenţa între eşantionare şi conversie
Obiective - să poată configura modulul de conversie analog-digitală al
microcontrolerului PIC18F4455
- să poată citi date analogice din program prin interogare sau
întrerupere.

10.1 PRINCIPIUL DE FUNCŢIONARE AL CONVERTORULUI A/D

Microcontrolerul PIC18F4455 este dotat cu un convertor analog-digital cu aproximări


succesive, cuprins în cadrul unui modul intern legat la magistrala de adrese şi de date.
Modulul de conversie dispune de 13 canale de intrare multiplexate cu pinii
microcontrolerului, iar rezoluţia convertorului este de 10 biţi.
Structura unui convertor analog-digital cu aproximări succesive (Fig. 10.1) cuprinde,
în general, următoarele blocuri:
1. Un circuit de eşantionare-memorare utilizat pentru achiziţionarea şi menţinerea
constantă pe durata conversiei a tensiunii analogice Vin.
2. Un comparator de tensiune. Acesta compară tensiunea de intrare Vin cu ieşirea
furnizată de convertorul digital-analogic şi trimite rezultatul către un registru de
aproximări succesive (RAS)

171
CONVERTORUL ANALOG-DIGITAL

3. Un registru de aproximări succesive (RAS) care va furniza convertorului digital-


analogic aproximări digitale ale tensiunii de intrare Vin
4. Un convertor digital-analogic care furnizează către comparator un semnal analogic
echivalent codului binar provenit de la registrul de aproximări succesive.[13]

Fig. 10.1. Convertor analog-digital cu aproximări succesive

Principiul de funcţionare al unui asemenea convertor analog-digital se desfăşoară după


cum urmează. Registrul de aproximări sucesive este iniţializat astfel încât bitul cel mai
semnificativ (MSB) să aibă valoarea 1, ceilalţi biţi fiind 0. Codul rezultat se va converti în
tensiune (Vref/2) şi se va compara cu Vin. Dacă tensiunea analogică produsă de convertorul
digital analogic este mai mică decât Vin atunci bitul (MSB) rămâne setat. În caz contrar acest
bit va fi resetat. Acelaşi proces se repetă pentru fiecare bit în parte, până la testarea fiecărui bit
al registrului RAS. Codul astfel rezultat reprezintă aproximarea digitală a semanlului de
analogic de intrare.
Procesul de conversie analog-digitală prin aproximări succesive este pus în evidenţă în
Fig. 10.2 pentru cazul unei rezoluţii de 4 biţi.[13]

Fig. 10.2. Principiul aproximărilor succesive pentru un RAS de 4 biţi

172
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

După cum s-a putut observa până acum, obţinerea rezultatului conversiei este un
proces secvenţial a cărui durată depinde de numărul de biţi necesar pentru reprezentarea
digitală, dar şi de frecvenţa de lucru. Timpul alocat conversiei unui bit se notează cu TAD, iar
pentru realizarea unei conversii complete de 10 biţi este necesar un timp egal cu 11·TAD.
Pentru a obţine rezultate corecte, pe durata timpului de conversie tensiunea Vin trebuie să
rămână constantă. De acest lucru se ocupă circuitul de eşantionare-memorare (Fig. 10.3)
prezent în structura modulului de conversie.

Fig. 10.3. Versiunea simplificată a unui circuit de eşantionare-memorare

Circuitul de eşantionare-memorare menţine constantă tensiunea de intrare Vin cu


ajutorul unui condensator, care necesită un timp de încărcare. Acest timp de încărcare
intervine în proporţie semnificativă şi caracterizează timpul de achiziţie TAQ al tensiunii care
urmează a fi convertită cu ajutorul convertorului A/D. În Fig. 10.4 se evidenţiază timpii care
intervin în procesul de conversie analog-digitală.

Fig. 10.4. Timpii care intervin în procesul de conversie A/D

Astfel, înaintea realizării conversiei propriu-zise, convertorul analog-digital trebuie


lăsat într-o stare de achiziţie a semnalului de intrare un timp minim:

173
CONVERTORUL ANALOG-DIGITAL

TAQ = TAMP + TC + TCOFF (10.1)


unde:
- TAQ reprezintă timpul de achiziţie
- TAMP reprezintă timpul de stabilizare a amplificatorului intern / întrerupătorului
comandat
- TC reprezintă timpul de încărcare al condensatorului
- TCOFF reprezintă un coeficient datorat temperaturii de lucru
Conform specificaţiilor din foaia de catalog, TAMP = 0.2μs, TC=1.2μs, iar pentru
temperaturi mai mari de 25°C TCOFF minim este 1.2μs crescând cu temperatura (se poate
adăuga la acest coeficient câte 0.02μs pentru fiecare °C peste temperature de 25°C). În aceste
condiţii timpul de achiziţie minim la temperaturi normale de lucru este TAQ = 2.4μs.
Pe lângă timpul de achiziţie şi timpul de conversie se recomandă aşteptarea unui timp
egal cu 3·TAD până la realizarea următoarei achiziţii.

10.2 CONFIGURAREA MODULULUI DE CONVERSIE A/D

10.2.1 Rolul şi structura regiştrilor de control

Modulul poate fi configurat prin simpla modificare a unor regiştri speciali, iar citirea
datelor se rezumă la citirea a doi regiştri (ADRESH:ADRESL) care vor conţine rezultatul
conversiei. Modulul de conversie A/D dispune de 3 regiştri de configurare (ADCON0,
ADCON1, ADCON2), a căror structură se prezintă în continuare.
Cu toate că în structura microcontrolerului există un singur convertor A/D, prin
utilizarea unui multiplexor analogic se pot selecta din program, cu ajutorul biţilor
CHS3:CHS0 din registrul ADCON0[5:2], pe rând, până la 13 canale de intrare analogice
distincte. Conversia este declanşată prin setarea bitului GO / DONE din registrul ADCON0[1],
care îndeplineşte şi rolul unui bit de stare care indică prin resetarea sa automată terminarea
conversiei şi disponibilitatea rezultatului de 10 biţi în regiştrii ADRESH:ADRESL. De
asemenea, modulul de conversie analog digitală poate genera o întrerupere, terminarea
conversiei fiind semnalizată şi prin setarea bitului indicator de întrerupere ADIF din registrul
PIR1.

174
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

După cum s-a văzut şi în cazul altor module componente ale microcontrolerului, şi
convertorul A/D dispune de un bit de validare ADON în registrul ADCON0[0] care are rolul
de a activa (ADON = 1) sau dezactiva (ADON = 0) modulul de conversie.
În Fig. 10.5 se prezintă schema bloc simplificată a modulului de conversie A/D, iar în
Fig. 10.6 se prezintă structura registrului ADCON0 urmată de descrierea biţilor disponibili.

Fig. 10.5. Schema bloc simplificată a modulului de conversie A/D

7 0
- - CHS3 CHS2 CHS1 CHS0 GO / DONE ADON
Fig. 10.6. Registrul ADCON0: A/D Control Register 0

Biţii 7-6 Neutilizaţi


Biţii 5-2 CHS3:CHS0 – Biţi de selecţie ai canalului de intrare A/D utilizat la conversie
0000 = Canal 0 (pin AN0)
0001 = Canal 1 (pin AN1)
...
1100 = Canal 12 (pin AN12)
1101 = Neimplementaţi
111x = Neimplementaţi
Bit 1 GO/DONE – Bit status conversie A/D

când ADON = 1 (convertor A/D activat)


1 = start conversie / conversie A/D în desfăşurare
0 = conversie A/D finalizată
Bit 0 ADON –Activare / Dezactivare convertor A/D
1 = activare convertor A/D
0 = dezactivare convertor A/D

175
CONVERTORUL ANALOG-DIGITAL

După cum s-a amintit şi în capitolul dedicat porturilor, canalele de intrare analogice
sunt multiplexate cu porturile de intrare-ieşire digitale. Astfel, pinul corespunzător canalului
selectat ca intrare în convertor trebuie să fie configurat ca pin de intrare (prin registrul TRIS
corespunzător) şi ca intrare analogică (prin biţii PCFG3:PCFG0 ai registrului
ADCON1[3:0]).
Canalele analogice 2 (AN2) şi 3 (AN3) îndeplinesc un dublu rol, prin faptul că pot fi
utilizate (opţional) pentru a specifica tensiuni de referinţă externe pentru realizarea conversiei
A/D. De regulă, tensiunile de referinţă corespund tensiunilor de alimentare ale
microcontrolerului (Vdd şi Vss), dar există situaţii când referinţele externe oferă o alternativă
mai puţin zgomotoasă, mai exactă, dar şi perspectiva unei precizii mai ridicate când semnalul
de intrare are o variaţie mult mai mică decât plaja de alimentare de 0-5V. Dacă se optează
pentru referinţe externe, atunci VREFH ar trebui să fie cuprins între Vdd/2 şi Vdd+0.6V, iar
VREFL între Vdd-3V şi Vss-0.3V. Indiferent de situaţie, diferenţa între tensiunile de referinţă
utilizate VREFH-VREFL ar trebui să fie nu mai puţin de 3V pentru Vdd≥3V şi 1.8V pentru
Vdd<3V.
În Fig. 10.7 se prezintă structura registrului ADCON1 urmată de descrierea biţilor
disponibili.

7 0
- - VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
Fig. 10.7. Registrul ADCON1: A/D Control Register 1

Biţii 7-6 Neutilizaţi


Biţii 5-4 VCFG1:VCFG0 – Biţi de configurare pentru tensiunile de referinţă
00 : VREF+ = Vdd = 5V, VREF- = Vss = 0V
01 : VREF+ = extern (pin AN3), VREF- = Vss = 0V
10 : VREF+ = Vdd = 5V, VREF- = extern (pin AN2)
11 : VREF+ = extern (pin AN3), VREF- = extern (pin AN2)
Biţii 3-0 PCFG3:PCFG0 – Biţi de configurare a funcţionalităţii porturilor
PCFG3:
AN12 AN11 AN10 AN9 AN8 AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0
PCFG0
0000 A A A A A A A A A A A A A
0001 A A A A A A A A A A A A A
0010 A A A A A A A A A A A A A
0011 D A A A A A A A A A A A A
0100 D D A A A A A A A A A A A
0101 D D D A A A A A A A A A A
0110 D D D D A A A A A A A A A
0111 D D D D D A A A A A A A A

176
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

1000 D D D D D D A A A A A A A
1001 D D D D D D D A A A A A A
1010 D D D D D D D D A A A A A
1011 D D D D D D D D D A A A A
1100 D D D D D D D D D D A A A
1101 D D D D D D D D D D D A A
1110 D D D D D D D D D D D D A
1111 D D D D D D D D D D D D D
A = intrare analogică D = intrare / ieşire digitală

Configurarea convertorului A/D poate fi văzută ca un proces în două etape: o


configurare iniţială în care se alege canalul de intrare, tensiunile de referiţă şi o configurare a
conversiei care presupune alegerea tactului de conversiei, stabilirea timpilor de achiziţie şi a
modului realizare a conversiei.
Registrul de control ADCON2 are rolul de a selecta sursa tactului de conversie A/D, de
a alege durata întârzierii necesare înainte conversiei şi modul în care rezultatul de 10 biţi se va
regăsi în regiştrii ADRESH:ADRESL.
Pentru a putea realiza procesul secvenţial necesar conversiei, ilustrat în Fig. 10.2,
modulul de conversie A/D necesită un semnal de tact. Pentru a realiza conversii A/D corecte,
se recomandă ca perioada acestui semnal de tact (TAD) să fie cât mai scurtă posibil, dar mai
mare decât TAD=0.7μs.
În mod obişnuit, tactul de conversie se obţine prin divizarea frecvenţei de lucru a
microcontrolerului. Prin intermediul biţilor ADCS2:ADCS0 din registrul ADCON2[2:0] se
pot obţine rapoarte de divizare de 2 până la 64. Alegerea acestui raport de divizare se face
astfel încât să se asigure condiţia (TAD)min> 0.7μs. În Tabelul 10.1 se prezintă fercvenţele
maxime de lucru corespunzătoare diferitelor rapoarte de divizare necesare pentru obţinerea
tactului de conversie.
Tabel 10.1. Alegerea tactului de conversie în funcţie de frecvenţa de lucru
ADCS2:ADCS0 Tact de conversie TAD Frecvenţa maximă de lucru FOSC
000 2·TOSC 2.86 MHz
100 4·TOSC 5.71 MHz
001 8·TOSC 11.43 MHz
101 16·TOSC 22.86 MHz
010 32·TOSC 45.71 MHz
110 64·TOSC 48.0 MHz
111 RC (osc. intern1) TAD≈4ms 1.00 MHz

1
Aceste cazuri sunt prevăzute pentru funcţionarea în regim SLEEP (cu consum redus de energie), tactul de
conversie provenind de la oscilatorul intern.

177
CONVERTORUL ANALOG-DIGITAL

Pentru a permite funcţioarea în condiţii cu consum redus de energie, de exemplu


atunci când se utilizează oscilatorul de 32.768kHz, microcontrolerul este prevăzut cu un
oscilator RC intern. Având în vedere că acest oscilator furnizează un tact independent de
tactul sistem, se pot realiza conversii A/D în timp ce microcontrolerul este în modul SLEEP.
În acestă situaţie întreruperea apărută ca urmare a finalizării unei conversii A/D poate fi
utilizată pentru a trezi procesorul. Realizarea conversiilor A/D în timp ce tactul sistem este
dezactivat reprezintă o alegere logică deoarece în acest fel se asigură un mediu de lucru cu
zgomot digital mai redus. Dacă se optează pentru utilizarea oscilatorului RC intern pentru
obţinerea tactului de conversie în cazul unui micrcontroler cu o frecvenţă de lucru mai mare
de 1MHz, Microchip recomandă utilizarea modului SLEEP pe durata conversiei, deoarece
lipsa de sincronizare dintre cele două surse de tact creşte zgomotul indus în circuitul analogic.

S-a amintit în paragraful anterior că este necesar un timp TAQ pentru stabilizarea
tensiunii de intrare în circuitul de eşantionare memorare. În acest context, modulul de
conversie A/D oferă posibilitatea ca respectarea timpului de achiziţie TAQ să fie lăsată la
latitudinea utilizatorului prin introducerea unei întârzieri sau să se producă automat.
În primul caz (Fig. 10.8-a), după alegerea canalului de intrare dorit, utilizatorul trebuie
să asigure scurgerea timpului minim de achiziţie (2.4μs÷3μs la 25°C) înainte de declanşarea
unei conversii A/D prin setarea bitului GO.
În cea de-a doua situaţie (Fig. 10.8-b), după setarea bitului GO se va aştepta un timp
cuprins între 2TAD şi 20TAD (în funcţie de configurare) înainte de a începe conversia
propriuzisă care va dura 11TAD. După calcularea ultimului bit (LSB) în TAD11, bitul GO este
şters şi bitul indicator de întrerupere ADIF este setat pentru a indica sfârşitul conversiei şi
disponibilitatea rezultatului în regiştrii ADRESH:ADRESL.
Indiferent de modul ales pentru implementarea achiziţiei, înaintea declanşării unei noi
conversii este necesară aşteptarea unui timp de descărcare (vezi Fig. 10.4) de aproximativ
3TAD.
Cele două situaţii, exemplificate în Fig. 10.8, pot fi configurate prin intermediul biţilor
ACQT2:ACQT0 din registrul ADCON2[5:3]. Condiţia impusă pentru alegerea unei variante
de configurare este aceea că trebuie să se asigure un timp minim de achiziţie mai mare de
2.4μs÷3μs.

178
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 10.8. Asigurarea timpului de achiziţie


a) manual; b) automat

Rezultatul conversiei A/D este reprezentat pe 10 biţi, în consecinţă acesta necesită doi
regiştri pentru a fi stocat. Deoarece capacitatea totală a celor doi regiştri ADRESH:ADRESL
este de 16 biţi, rezultatul conversiei poate fi aliniat la stânga sau la dreapta. În Fig. 10.9 se
prezintă modul de aliniere al rezultatului în funţie de starea bitului ADFM din registrul
ADCON2[7].

9 8 7 0
Rez. conv.
0 0 0 0 0 0 A/D MSb
Rezultat conversie A/D octetul inferior

ADRESH ADRESL
a)
9 2 1 0
Rez. conv.
Rezultat conversie A/D octetul superior
A/D LSb 0 0 0 0 0 0
ADRESH ADRESL
b)
Fig. 10.9. Rezultatul conversiei A/D
a) aliniere la dreapta ADFM = 1 b) aliniere la stânga ADFM = 0

Există aplicaţii în care 8 biţi de date sunt suficienţi pentru a reprezenta rezultatul
conversiei. În aceste cazuri se recomandă alinierea rezultatului la stânga (ADFM=0), utilizarea
datelor din registrul ADRESH şi ignorarea celor doi biţi mai nesemnificativi din registrul

179
CONVERTORUL ANALOG-DIGITAL

ADRESL. Când este necesar un rezultat al conversiei pe 10 biţi se recomandă alinierea


rezultatului la dreapta (ADFM=1), biţii ADRESH[7:2] fiind toţi zero.
Cunoscând codul de 10 biţi obţinut în urma conversiei A/D se poate determina
valoarea efectivă a tensiunii analogice de intrare pe baza formulei următoare:
VREF + − VREF −
Vin = × (rezultatConversie ) (10.2)
1024

În Fig. 10.10 se prezintă structura registrului ADCON2 urmată de descrierea biţilor


disponibili.

7 0
ADFM - ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
Fig. 10.10. Registrul ADCON2: A/D Control Register 2

Bit 7 ADFM – Formatare rezultat conversie A/D


1 = aliniere rezultat la dreapta
0 = aliniere rezultat la stânga (vezi Figura 9.6)
Bit 6 Neimplementat
Biţii 5-3 ACQT2:ACQT0 – Configurare timp de achiziţie
111 : TAQ = 20·TAD
110 : TAQ = 16·TAD
101 : TAQ = 12·TAD
100 : TAQ = 8·TAD
011 : TAQ = 6·TAD
010 : TAQ = 4·TAD
001 : TAQ = 2·TAD
000 : TAQ = 0·TAD (Achiziţie manuală. TAQ trebuie asigurat prin program)
Biţii 2-0 ADCS2:ADCS0 – Configurare tact de conversie
111 : TAD = RC(oscilator intern)≈4ms
110 : TAD = 64·TOSC
101 : TAD = 16·TOSC
100 : TAD = 4·TOSC
011 : TAD = RC(oscilator intern)≈4ms
010 : TAD = 32·TOSC
001 : TAD = 8·TOSC
000 : TAD = 2·TOSC

180
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

10.2.2 Etapa de configurare

Pentru iniţializarea modulului de conversie A/D utilizatorul trebuie să asigure


răspunsul la următoarele întrebări:
1. Cum activez modulul?
2. Am nevoie de tensiuni de referinţă externe?
3. Ce canale voi folosi?
4. Cum asigur tactul de conversie?
5. Cum asigur timpul de achiziţie?
6. Cum citesc rezultatul?

În acest context, etapa de configurare a modulului de conversie A/D în vederea


realizării unei conversii presupune parcurgerea următorilor paşi:
• configurarea pinilor ANx utilizaţi ca pini de intrare, prin setarea biţilor corespunzători
în regiştrii TRIS;
• configurare pini analogici utilizaţi (biţii PCFG3:PCFG0, registrul ADCON1[3:0]);
• configurare tensiuni de referinţă (biţii VCFG1:VCFG0, registrul ADCON1[5:4]);
• selectare canal de intrare utilizat pentru achiziţie şi conversie (biţii CHS3:CHS0,
registrul ADCON0[5:2]);
• configurare timp de achiziţie (biţii ACQT2:ACQT0, registrul ADCON2[5:3]);
• configurare tact de conversie (biţii ADCS2:ADCS0, registrul ADCON2[2:0]);
• formatare rezultat conversie (bitul ADFM, registrul ADCON2[7]);
• pornire modul de conversie (bitul ADON, registrul ADCON0[0]);
• aşteptarea expirării timpului de achiziţie (în cazul funcţionării în mod manual
ACQT2:ACQT0=000)
• start conversie (bitul GO/ DONE , registrul ADCON0[1])2;
• aşteptarea terminării conversiei. Terminarea conversiei este indicată de resetarea
bitului GO/ DONE şi de setarea flagului indicator de întrerupere ADIF din registrul
PIR1[6];
• citirea rezultatului (regiştrii ADRESH:ADRESL);
• ştergerea flagului indicator de întrerupere (bitul ADIF, registrul PIR1[6]);

2
ATENŢIE se recomandă ca bitul GO/ DONE să nu fie setat în aceeaşi instrucţiune în care se porneşte modulul
de conversie A/D

181
CONVERTORUL ANALOG-DIGITAL

• înainte ca următoarea achiziţie să înceapă se recomandă o aşteptare minimă de 3TAD,


necesară descărcării condensatorului din circuitul de eşantionare-memorare.[8]

În continuare se prezintă codul corespunzător configurării modulului de


conversie A/D în vederea realizării unei achiziţii automate, pentru cazul unui
microcontroler cu o frecvenţă de lucru de 20MHz care recepţionează pe canalul
Exemplu
0 un semnal analogic cuprins între 0÷5V.

CONFIGURARE_CONVERTOR_AD:
BSF TRISA, TRISA0 ;pin RA0/AN0 de intrare
MOVLW b’00001110’ ;pin AN0 intrare analogică
MOVWF ADCON1 ;tens. de referiţă interne
BCF ADCON0,CHS3 ;selectare canal 0
BCF ADCON0,CHS2
BCF ADCON0,CHS1
BCF ADCON0,CHS0
MOVLW b’00010101’ ;aliniat stânga, TAQ=4TAD
MOVWF ADCON2 ;TAD = 16TOSC
BCF PIR1,ADIF ;şterg flag întrerupere
BSF ADCON0,ADON ;pornire modul
BSF ADCON0,GO ;start conversie

LOOP_TESTARE:
BTFSS PIR1, ADIF ;sau BTFSC ADCON0, GO
GOTO LOOP_TESTARE

;Când se ajunge în acest punct, conversia s-a terminat


;se citeşte rezultatul
MOVF ADRESH, W ;citire date

În loc de utilizarea interogării pentru testarea sfârşitului de conversie se poate genera o


întrerupere. În cazul în care conversia se realizează în modul SLEEP, atunci această
întrerupere poate fi utilizată pentru a trezi UCP. După cum s-a amintit în paragraful anterior,
modulul de conversie A/D poate funcţiona în modul SLEEP deoarece dispune de un oscilator
propriu care permite generarea tactului de conversie, chiar dacă tactul sistem este dezactivat.
Această soluţie vine cu avantajele şi dezavantjele ei. Ca principal avanataj se poate menţiona
faptul că prin oprirea oscilatorului principal se asigură un mediu de conversie lipsit de
zgomote. Pe de altă parte, conversia va dura mai mult timp, iar ieşirea din modul SLEEP este
şi ea îndelungată.
Oscilatorul intern RC poate fi utilizat pentru generarea tactului de conversie şi fără a
pune sistemul în modul SLEEP. Totuşi, deoarece nu există o sincronizare între oscilatorul
intern şi oscilatorul sistem, zgomotele introduse de semnalul de tact fac problematică
utilizarea modulului pentru frecvenţe de lucru mai mari de FOSC>1MHz.

182
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

În acest exemplu se pune în evidenţă realizarea conversiei A/D în modul


SLEEP. Se consideră cazul configurării modulului de conversie A/D în
vederea realizării unei achiziţii pentru cazul unui microcontroler cu o
Exemplu
frecvenţă de lucru de 20MHz care recepţionează pe canalul 0 un semnal
analogic cuprins între 0÷5V.
Pe lângă etapele de iniţilizare amintite şi în exemplul anterior, utilizarea
modului SLEEP presupune:
- Selectarea oscilatorului intern ca sursă a tactului de conversie
(ADCS2:ADCS0 = x11)
- Ştergerea bitului indicator de întrerupere ADIF pentru a evita intrarea
imediată în întrerupere
- Activarea întreruperii provenite de la modulul de conversie A/D
(ADIE=1) şi activarea întreruperilor provenite de la periferice (PEIE
= 1) pentru a permite ieşirea din SLEEP
- Bitul GIE trebuie pus pe 0 pentru a evita execuţia automată a unei
rutine de tratare a întreruperii la ieşirea din SLEEP
- Setarea bitului GO pentru pornirea conversiei A/D, trebuie urmată
imediat de instrucţiunea SLEEP
- La ieşirea din modul SLEEP rezultatul conversiei va fi disponibil în
regiştrii ADRESH:ADRESL.

CONFIGURARE_CONVERTOR_AD:
BSF TRISA, TRISA0 ;pin RA0/AN0 de intrare
MOVLW b’00001110’ ;pin AN0 intrare analogică
MOVWF ADCON1 ;tens. de referiţă interne
BCF ADCON0,CHS3 ;selectare canal 0
BCF ADCON0,CHS2
BCF ADCON0,CHS1
BCF ADCON0,CHS0
MOVLW b’00010011’ ;aliniat stânga, TAQ=4TAD
MOVWF ADCON2 ;TAD de la RC
BCF PIR1,ADIF ;şterg flag întrerupere
BSF INTCON, PEIE ;activare într. periferice
BSF PIE1,ADIE ;activare într. conv A/D
BCF INTCON, GIE ; GIE = 0
BSF ADCON0,ADON ;pornire modul
BSF ADCON0,GO ;start conversie

SLEEP ;conversie in mod SLEEP

;Când se ajunge în acest punct, conversia s-a terminat


;se citeşte rezultatul
MOVF ADRESH, W ;citire date

183
CONVERTORUL ANALOG-DIGITAL

Modulul de conversie A/D permite microcontrolerului să interacţioneze


cu lumea exterioară şi prin intermediul semnalelor analogice. Spre

Concluzii deosebire de utilizarea porturilor digitale, în cazul convertorului A/D


accesul la datele analogice nu se realizează instantaneu. În utilizarea
acestui modul trebuie să se ţină cont de restricţiile de timp impuse de
achiziţia semnalului analogic şi de conversia sa înainte de a putea accesa
rezultatul.

1. Ce înţelegeţi prin alinierea rezultatului conversiei A/D?


2. Care este principiul de funcţionare al unui convertor A/D cu
aproximări succesive?
Întrebări de
3. Ce rol îndeplineşte timpul de achiziţie TAQ şi care sunt variantele de
autoevaluare
implementare care asigură acest timp?
4. Explicaţi funcţionarea convertorului A/D în modul SLEEP.
5. Care sunt restricţiile privind nivelul tensiunilor de referinţă externe?

Convertor Analog-Digital
Circuit care are la intrare o mărime analogică (curent, tensiune) şi
Termeni furnizează la ieşire un număr (reprezentat binar) care constituie o
esenţiali aproximare (mai mult sau mai puţin exactă) a valorii analogice a
semnalului de intrare
LSB
En. Least Significant Bit. Bitul cel mai nesemnificativ. Într-un octet
acesta este bitul 0.
MSB
En. Most Significant Bit. Bitul cel mai semnificativ. Într-un octet acesta
este bitul 7.
Timp de achiziţie
Timpul necesar pentru circuitul de eşantionare să încarce condensatorul de
menţinere la nivelul tensiunii analogice de intrare. Timpul necesar
stabilizării tensiunii de intrare în vederea realizării conversiei.
Timp de conversie
Timpul necesar convertorului A/D să realizeze conversia semnalului

184
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

analogic eşantionat în echivalentul digital


RAS
Registru de aproximări succesive
Rezoluţie
Numărul de valori discrete pe care convertorul poate să le furnizeze la
ieşirea sa în intervalul de masura.
SLEEP
Mod de funcţionare cu consum redus caracterizat prin oprirea
oscilatorului principal al microcontrolerului.

185
MODULUL CCP

11. MODULUL CCP

Introducere
Obiective
11.1 PRELIMINARII
Cuprins
11.2 CAPTURA
11.2.1 Funcţionarea modulului CCP în modul de lucru
Captură
11.2.2 Configurarea capturii
11.3 COMPARARE
11.3.1 Funcţionarea modulului CCP în modul de lucru
Comparare
11.3.2 Configurarea comparării
11.4 PWM
11.5 REGISTRUL CCPxCON
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

186
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Timpul intervine în mod esenţial în majoritatea sistemelor care


interacţionează cu lumea reală. Printre aplicaţiile uzuale în care intervine
timpul se pot aminti: măsurarea duratei între anumite evenimente sau
Introducere
generarea unor impulsuri cu durate bine definite. Microcontrolerele PIC
au în dotarea lor module CCP (Comparare/Captură/PWM) care se
utilizează în asociere cu diferite timere care asigură baza de timp pentru
implementarea acestor funcţionalităţi. Majoritatea microcontrolerelor din
familia PIC18 dispun de două asemenea module CCP1 şi CCP2. Cele
două module sunt aproape identice, existând situaţii în care ambele
folosesc aceeaşi bază de timp, dar fiecărui modul îi corespunde un pin de
intrare/ieşire (CPP1 şi CPP2) distinct.
În acest context, în acest capitol se va face referire la un singur modul
generic CCPx, unde x={1,2}.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă principiul de funcţionare al modulelor CCP în mod de
lucru Captură;
Obiective - să înţeleagă principiul de funcţionare al modulelor CCP în mod de
lucru Comparare;
- să înţeleagă principiul de funcţionare al modulelor CCP în mod de
lucru PWM;
- să poată realiza măsurarea parametrilor unor semnale de intrare;
- să poată genera semnale de ieşire cu anumite caracteristici;
- să poată configura modulele CCP şi timerele implicate în vederea
realizării unor aplicaţii specifice

11.1 PRELIMINARII

În funcţie de configurare modulele CCP pot fi utilizate în trei moduri de lucru.


• În modul de lucru Captură, un eveniment extern apărut pe pinul corespunzător
determină copierea valorii Timerului1 sau a Timerului3 în regiştrii de date
CCP. Acest mod de funcţionare poate fi utilizat penru a măsura durata
anumitor evenimente

187
MODULUL CCP

• În modul de lucru Comparare, când valoarea Timerului 1 sau 3 devine egală


cu valoarea din regiştrii de date CCP se generează un eveniment pe pinul
asociat sau Timerul 1 sau 3 este resetat. Acest mod de funcţionare poate fi
utilizat pentru a genera semnale de ieşire cu parametri de timp foarte riguroşi
• În modul de lucru PWM, modulul CCP utilizat împreună cu Timerul2 poate
genera semnale modulate în lăţime cu perioadă şi factor de umplere
configurabil din program.

Fiecare modul CCP dispune de un registru de control CCPxCON utilizat pentru a


alege modul de lucru şi o pereche de regiştri de date CCPRxH:CCPRxL. Indiferent de modul
de funcţionare ales, pinii corespunzători CPPx trebuie configuraţi ca intrare sau ieşire în
regiştrii TRIS asociaţi.
În toate cazurile de funcţionare care implică utilizarea Timerelor 1 şi 3, modulele CCP
necesită impulsuri de tact sincronizate. În consecinţă, pentru a asigura o funcţionare corectă,
biţii T1SYNC sau T3SYNC din regiştrii de control al acestor timere trebuie resetaţi.

11.2 CAPTURA

11.2.1 Funcţionarea modulului CCP în modul de lucru Captură

Pentru a ilustra utilitatea modului de lucru captură să considerăm următorul exemplu.


Se analizează modul în care se poate determina perioada unui semnal
dreptunghiular conectat la un pin de intrare al microcontrolerului.

Exemplu

Fig. 11.1. Semnal dreptunghiular conectat la pinul unui microcontroler

O soluţie la această problemă presupune interogarea continuă a pinului de


intrare în vederea detectării fronturilor şi măsurarea timpului scurs între două
fronturi (de ex. crescătoare) cu ajutorul unui timer. Acest principiu este
prezentat, într-o variantă mult simplificată, în diagrama de activitate din Fig.
11.2.

188
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Fig. 11.2. Determinarea perioadei

După cum se poate observa, citirea portului ocupă cel mai mult timp al
programului.

O alternativă la soluţia prezentată în exemplul anterior o reprezintă utilizarea


modulului CCP în modul de lucru Captură. Reluând principiul de funcţionare al modului de
lucru Captură menţionăm că la apariţia unui eveniment pe pinul CPPx, se copiază valoarea
Timerului 1 sau 3 din regiştrii TMR1, respectiv TMR3, în regiştrii de date ai modulului CCP
CCPRxH:CCPRxL. În acelaşi timp, bitul indicator de întrerupere CCPxIF se setează şi dacă
bitul corespunzător CCPxIE este setat se poate genera o întrerupere.
În Fig. 11.3 se prezintă schema bloc a modulului CCP1 în modul de lucru Captură.

Fig. 11.3. Schema bloc a modulului CCP1 în mod de lucru Captură conform foii de catalog [15]

Evenimentele disponibile la care poate răspunde modulul de Captură pot fi selectate


prin intermediul biţilor CCPxM3:0 din registrul CCPxCON[3:0] şi sunt următoarele:
- front descrescător pe pinul CPPx (CCPxM3:0=0100)
- front crescător pe pinul CPPx (CCPxM3:0=0101)
- al 4-lea front crescător pe pinul CPPx (CCPxM3:0=0110)
- al 16-lea front crescător pe pinul CPPx (CCPxM3:0=0111)

189
MODULUL CCP

La apariţia unuia din evenimentele menţionate mai sus, se poate realiza citirea valorii
stocate în regiştrii de date CCPR1H:CCPR1L fie prin intermediul rutinei de tratare a
întreruperii, fie ca urmare a interogării bitului CCPxIF.
Reluând exemplul de la începutul paragrafului, dacă timerul utilizat pentru a furniza
baza de timp este resetat după fiecare captură, atunci datele disponibile în regiştrii
CCPR1H:CCP1RL caracterizează timpul scurs de la ultimul eveniment (Fig. 11.4-a). O
variantă alternativă presupune incrementarea continuă a valorii timerului, perioada semnalului
fiind diferenţa între două valori capturate succesive(Fig. 11.4-b). Având în vedere că modulul
CCP poate fi configurat prin program, se poate determina factorul de umplere al unui semnal
prin modificarea evenimentului de captură şi realizarea diferenţei între două valori capturate
succesive (Fig. 11.4-c). Astfel, prin simpla schimbare a stării bitului CCPxM0 se poate opta
pentru frontul crescător sau descrescător pentru a genera captura.
Dacă se optează pentru utilizarea ambelor module de captură disponibile, acestea pot
fi configurate pentru a utiliza aceeaşi bază de timp (acelaşi timer) şi acelaşi semnal de intrare.
Pentru determinarea perioadei ambele module vor fi configurate pentru a detecta acelaşi front
(de ex. crescător) şi se va calcula diferenţa între valorile capturate. Pentru determinarea
factorului de umplere cele două module CCP vor fi configurate pentru detecta fronturi diferite
şi se va calcula diferenţa între valorile capturate.

Fig. 11.4. Determinarea parametrilor unui semnal cu ajutorul modulului de captură

190
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

11.2.2 Configurarea capturii

Etapa de configurare a modulului de captură presupune parcurgerea următorilor paşi:


• configurarea pinului CCPx ca pin de intrare, prin setarea bitului corespunzător în
registrul TRIS1
• oprirea Timerului1 şi/sau a Timerului3 (bitul TMR1ON, registrul T1CON[0],
respectiv bitul TMR3ON, registrul T3CON[0])
• selectarea timerului care se utilizează cu modulul CCP configurat (biţii
T3CCP2:T3CCP1, registrul T3CON[6,3])
• configurarea Timerului1 şi/sau a Timerului3 (registrul T1CON şi/sau T3CON)
• dacă e cazul: iniţializarea valorii Timerului1 şi/sau a Timerului3 (regiştrii
TMR1H:TMR1L şi/sau TMR3H:TMR3L)
• configurarea regimului de lucru pentru captură a modulului CCP utilizat (biţii
CCPxM3:CCPxM0, registrul CCPxCON[3:0])
• pornirea Timerului1 şi/sau a Timerului3 (bitul TMR1ON, registrul T1CON[0],
respectiv bitul TMR3ON, registrul T3CON[0])
• aşteptarea realizării capturii. Captura este marcată de setarea flagului indicator de
întrerupere CCPxIF din registrul PIRx;
• citirea rezultatului (regiştrii CCPRxH:CCPRxL);
• ştergerea flagului indicator de întrerupere (bitul CCPxIF, registrul PIRx);
• dacă e cazul: iniţializarea unor noi valori pentru Timerul1 şi/sau pentru Timerul3
(regiştrii TMR1H:TMR1L şi/sau TMR3H:TMR3L)

După cum s-a observat, etapa de configurare a modulului de captură vizează în


principal trei regiştri de control:
- registrul de control al modulului CCPx: CCPxCON (detalii în paragraful 11.5)
- registrul de control al Timerului3 : T3CON
- registrul de control al Timerului1: T1CON
Pentru structura regiştrilor de control ai timerelor se poate consulta Cap. 8 –
Temporizări hardware, iniţializarea acestora fiind tratată pe larg acolo.
În general, iniţializarea valorilor regiştrilor TMR1H:TMR1L şi/sau TMR3H:TMR3L se
rezumă la simpla lor resetare în vederea realizării unor noi capturi.

1
Pinii CCP1 şi CCP2, asociaţi celor două module CCP sunt multiplexaţi cu pinii RC2, respectiv RC1 şi trebuie
configuraţi ca pini de ieşire cu ajutorul registrului TRISC

191
MODULUL CCP

Pentru alegerea timerului utilizat în asociere cu modulele CCP, în registrul T3CON


(Fig. 11.5) există prevăzuţi doi biţi de configurare: T3CCP2 şi T3CCP1 (biţii 3 şi 6) care
îndeplinesc următorul rol:

7 0
RD16 T3CCP2 T3CKPS1 T3CKPS0 T3CCP1 T3SYNC TMR3CS TMR3ON
Fig. 11.5. Registrul T3CON: Timer3 Control Register

Biţii 6,3 T3CCP2:T3CCP1 – Biţi selecţie utilizare Timer1 şi Timer3 impreună cu


modulele CCP1 şi CCP2
1x = Timerul3 se utilizează împreună cu ambele module CCP
01 = Timerul3 se utilizează împreună cu modulul CCP2
Timerul1 se utilizează împreună cu modulul CCP1
00 = Timerul1 se utilizează împreună cu ambele module CCP

În continuare se prezintă codul corespunzător configurării şi utilizării modulului


de captură. Se consideră cazul utilizării modulului CCP1 cu baza de timp
furnizată de Timerul1.
Exemplu

CONFIGURARE_CAPTURA:
BSF TRISC, TRISC2 ;pin CCP1 de intrare
BCF T3CON, T3CCP2 ;utilizare Timer1 cu CCP1
BCF T3CON, T3CCP1
MOVLW b’10100001’ ;configurare şi pornire
MOVWF T1CON ;Timer1
BCF CCP1CON,CCP1M3 ;captura la fiecare fr. cr.
BSF CCP1CON,CCP1M2
BCF CCP1CON,CCP1M1
BCF CCP1CON,CCP1M0

LOOP_TESTARE:
BTFSS PIR1, CCP1IF
GOTO LOOP_TESTARE
;Când se ajunge în acest punct, captura s-a terminat
;se citeşte rezultatul din CCPR1H:CCPR1L
;se restează flagul de întrerupere

Se recomandă configurarea timerelor astfel încât acestea să nu-şi depăşească


capacitatea de numărare pe durata măsurării parametrilor semnalelor de intrare. De asemenea,
trebuie acordată o atenţie deosebită citirii datelor rezultate în urma capturii. Citirea trebuie să
se realizeze între două evenimente, deoarece modulul de captură şi timerul asociat
funcţionează continuu, iar valoarea din regiştrii CCPRx poate fi suprascrisă ca urmare a
apariţiei unui eveniment de captură.

192
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

11.3 COMPARARE

11.3.1 Funcţionarea modulului CCP în modul de lucru Comparare

În modul de lucru comparare, valoarea stocată în regiştrii CCPRxH:CCPRxL este tot


timpul comparată cu valoarea Timerului1 din regiştrii TMR1H:TMR1L sau a Timerului3 din
regiştrii TMR3H:TMR3L. La detectarea unei egalităţi între cele două valori de 16 biţi se
setează bitul indicator de întrerupere CCPxIF, iar dacă bitul corespunzător CCPxIE este setat
se poate genera o întrerupere. De asemenea, în funcţie de configurarea realizată prin biţii
CCPxM3:0 din registrul CCPxCON[3:0], se generează unul din evenimentele următoare:
- se schimbă starea pinului CCPx: (CCPxM3:0=0010)
- se setează starea pinului CCPx: (CCPxM3:0=1000)
- se resetează starea pinului CCPx: (CCPxM3:0=1001)
- pinul CCPx rămâne nemodificat putând fi utilizat ca un pin de intrare – ieşire
obişnuit, dar se generează o întrerupere software ca urmare a setării bitului
CCPxIF: (CCPxM3:0=1010)
- se generează un eveniment special care poate reseta valoarea timerului asociat.
În cazul modulului CCP2 se poate declanşa o conversie A/D2. De asemenea,
pinul CCPx rămâne nemodificat putând fi utilizat ca un pin de intrare – ieşire
obişnuit: (CCPxM3:0=1011)
Primele trei moduri de funcţionare (0010, 1000, 1001) ale modulului de comparare
presupun inţializarea direcţiei pinului CCPx ca ieşire în regitrul TRIS corespunzător.
În Fig. 11.6 se prezintă schema bloc a modulului CCP1 în modul de lucru Comparare.

Fig. 11.6. Schema bloc a modulului CCP1 în mod de lucru Comparare conform foii de catalog [15]

2
Aceasta este singura diferenşă funcţională între CCP1 şi CCP2

193
MODULUL CCP

11.3.2 Configurarea comparării

Etapa de configurare a modulului CCP în mod de lucru comparare presupune


parcurgerea următorilor paşi:
• configurarea pinului CCPx ca pin de ieşire, prin resetarea bitului corespunzător în
registrul TRIS, dacă se utilizează unul din cele trei moduri de funcţionare care
generează eveniment pe pin.
• oprirea Timerului1 şi/sau a Timerului3 (bitul TMR1ON, registrul T1CON[0],
respectiv bitul TMR3ON, registrul T3CON[0])
• selectarea timerului care se utilizează cu modulul CCP configurat (biţii
T3CCP2:T3CCP1, registrul T3CON[6,3])
• configurarea Timerului1 şi/sau a Timerului3 (registrul T1CON şi/sau T3CON)
• iniţializarea regiştrilor CCPRxH:CCPRxL
• configurarea regimului de lucru pentru comparare a modulului CCP utilizat (biţii
CCPxM3:CCPxM0, registrul CCPxCON[3:0])
• pornirea Timerului1 şi/sau a Timerului3 (bitul TMR1ON, registrul T1CON[0],
respectiv bitul TMR3ON, registrul T3CON[0])
• aşteptarea realizării unei comparaţii reuşite marcată de setarea flagului indicator de
întrerupere CCPxIF din registrul PIRx;
• ştergerea flagului indicator de întrerupere (bitul CCPxIF, registrul PIRx);

Etapa de configurare de mai sus poate fi completată cu configurarea sistemului de


întreruperi sau cu iniţializarea valorii regiştrilor TMR1/3, dacă aplicaţia realizată necesită
acest lucru.

Se consideră cazul unei aplicaţii în care se doreşte configurarea Timerului1


pentru a genera o întrerupere la fiecare jumătate de secundă cu ajutorul
modulului CCP în regim de lucru Comparare. Se consideră un sistem cu o
Exemplu
frecvenţă de lucru FOSC =4MHz.
Pentru a realiza acest lucru Timerul1 trebuie configurat în aşa fel încât depăşirea
capacităţii sale de numărare să se producă după un timp mai mare de 500ms
apoi se va scurta ciclul de numărare la valoarea dorită prin utilizarea modulului
de comparare. Prin alegerea unei surse interne a impulsurilor numărate de
Timerului1 şi al unui predivizor de 1:8 se poate obţine o temporizare maximă de

194
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

0.524s. Pentru a scurta ciclul de numărare al Timerului1, regiştrii de date ai


modulului CCP1 se vor încărca cu valoarea 62500 (62500 x 1µs x 8 = 500ms)
care corespunde reprezentării hexa F424h.
De fiecare dată când Timerul1 va ajunge la această valoare se va reseta automat
şi se va produce o întrerupere dacă bitul CCP1IE este setat, întreruperile
provenite de la periferice sunt activate (PEIE = 1) şi bitul global de activare a
întreruperilor este şi el setat (GIE =1).
Codul de iniţializare este următorul:
MOVLW 0x24 ;iniţializare CCPR1 cu 0xF424
MOVWF CCPR1L
MOVLW 0xF4
MOVWF CCPR1H
BCF T3CON, T3CCP2 ;utilizare Timer1 cu CCP1
BCF T3CON, T3CCP1
MOVLW b’10110001’ ;configurare şi pornire Timer1
MOVWF T1CON ;predivizor 1:8, tact intern
BSF CCP1CON,CCP1M3 ;comparare cu generare eveniment
BCF CCP1CON,CCP1M2 ;special de resetare a Timer1
BSF CCP1CON,CCP1M1
BSF CCP1CON,CCP1M0
BCF PIR1, CCP1IF ;ştergere flag întrerupere
BSF PIE1, CCP1IE ;activare întrerupere la comparare
BSF INTCON, PEIE ;activare întreruperi periferice
BSF INTCON, GIE ;activare toate întreruperile

Odată realizată iniţializarea de mai sus sistemul va fi întrerupt la fiecare 500ms.


Rutina de tratare a întreruperii trebuie să asigure resetarea flagului de
întrerupere CCP1IF. Deoarece pinul CCP1 nu este implicat în modul de lucru
1011 ales pentru comparare, acesta poate fi utilizat ca un pin de intrare-ieşire
obişnuit.

11.4 PWM

O gamă largă de aplicaţii ale sistemelor de calcul bazate pe microcontrolere presupune


comanda unor echipamente de forţă: încălzire, iluminat, motoare. O soluţie eficientă şi ieftină
o reprezintă utilizarea semnalelor PWM şi unor comutatoare de forţă (tiristoare, tranzistori de
putere) pentru a realiza comanda echipamentelor.
Un exemplu de asemenea semnale se prezintă în Fig.11.7. Amplitudinea medie a
acestui semnal va fi 5V x FU, unde FU este factorul de umplere al semnalului şi reprezintă
intervalul de timp dintr-o perioadă (T) cât semnalul este în starea ’1’. Dacă FU se modifică
între 0 şi 100%, amplitudinea medie a semnalului se va modifica proporţional cu acesta.
Această tehnică poartă denumirea de modulare în lăţime a impulsurilor.
195
MODULUL CCP

Fig.11.7. Modularea în lăţime a impulsurilor.


Semnal PWM cu factor de umplere de 10% (a), 50% (b), 90% (c)

În cazul microcontrolerelor PIC18, generarea semnalelor PWM este implementată cu


ajutorul Timerului2 şi a unui comparator digital. În regiştrii de configurare sunt stocate două
valori: o valoare pentru factorul de umplere şi o valoare pentru perioadă. La fiecare
incrementare a timerului, comparatorul verifică dacă s-a ajuns la una din cele două valori
setate. În caz afirmativ, se modifică starea semnalului de ieşire generat.
Principiul de funcţionare este ilustrat în Fig. 11.8.

Fig.11.8. Principiul de funcţionare al modulului CCP în regim de lucru PWM

Selectarea regimului de lucru PWM se realizează prin punerea biţilor CCPxM3:0 din
registrul CCPxCON[3:0] în starea 11xx.
Configurarea care trebuie realizată în vederea generării unui semnal PWM presupune
determinarea valorilor de iniţializare pentru perioada semnalului şi factorul de umplere al
semnalului.

Perioada semnalului PWM se stabileşte prin intermediul valorii înscrise în


registrul PR2.

Calcularea valorii corespunzătoare perioadei dorite se face utilizând formula


următoare:
196
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

T = [(PR2)+1]·4·TOSC ·Predivizor (11.1)


unde:
- T este perioada semnalului PWM
- PR2 este valorea pe 8 biţi care va trebui înscrisă în registrul PR2
- 4·TOSC este tactul de execuţie al instrucţiunilor.
- Predivizor este valoarea predivizorului tactului de incrementare a Timerului2
(Predivizor∈{1,4,16})specificată prin biţii T2CON[1:0]3.

Factorul de umplere se stabileşte prin intermediul unei valori de 10 biţi care se


introduce în CCPRxL:CCPxCON<5:4>.

Registrul CCPxCON conţine cei mai nesemnificativi doi biţi (DCxB1:DCxB0), iar
CCPRxL conţine octetul superior

Factorul de umplere se poate calcula după formula:


FU = (CCPRxL:CCPxCON<5:4>)·TOSC ·Predivizor (11.2)
unde:
- FU este factorul de umplere al semnalului PWM
- CCPRxL:CCPxCON<5:4> este valoarea de configurare de 10 biţi
1
- TOSC = este tactul oscilatorului
FOSC

- Predivizor este valoarea predivizorului tactului de incrementare a Timerului2

Se analizează modul de calcul al parametrilor de configurare în vederea


generării unui semnal PWM cu perioada TPWM = 100μs, factor de umplere FU =
50μs, implementat cu ajutorul unei frecvenţe de lucru FOSC = 20MHz şi cu un
Exemplu
predivizor al timerului Predivizor=16.
Utilizând formula (11.1) obţinem:
T ⋅ FOSC 100μs ⋅ 20MHz
PR 2 = −1 = − 1 = 30.25 ≅ 30 (11.3)
4 ⋅ Predivizor 4 ⋅ 16
Utilizând formula (11.2) obţinem:

3
Pentru regimul de lucru PWM, biţii de interes din registrul T2CON sunt doar cei legaţi de activarea /
dezactivarea timerului 2, şi cei legaţi de algerea predivizorului. Postdivizorul nu va fi utilizat. Pentru detalii
privind structura registrului T2CON se poate consulta Cap. 8 – Temporizări hardware.

197
MODULUL CCP

FU ⋅ FOSC
(CCPRxL : CCPxCON 5 : 4 ) = =
Predivizor
(11.4)
50μs ⋅ 20MHz
= = 62.5 ≈ 63
16
Astfel, perioada semnalului PWM va fi configurată prin înscrierea în registrul
PR2 a valorii 30 (=1Eh), iar factorul de umplere al semnalului PWM va fi
configurat prin înscrierea valorii 63 în perechea CCPRxL:CCPxCON<5:4>.
Întrucât reprezentarea binară pe zece biţi a valorii 63 este (0000111111)2,
rezultă că DCxB1=1, DCxB0=1, iar CCPRxL=0Fh.

Odată determinate valorile de configurare pentru perioada şi factorul de umplere a


semnalului PWM se poate trece la etapa de iniţializare, care presupune parcurgerea
următorilor paşi:
• configurarea pinului CCPx ca pin de ieşire, prin ştergerea bitului corespunzător în
registrul TRIS
• oprirea Timerului2 (bitul TMR2ON, registrul T2CON[2])
• configurarea perioadei semnalului PWM prin înscrierea valorii determinate în registrul
PR2
• configurarea factorului de umplere al semnalului PWM prin înscrierea valorii
determinate în perechea CCPRxL:CCPxCON[5:4]
• configurarea predivizorului (biţii T2CKPS1:T2CKPS0, registrul T2CON[1:0])
• pornirea Timerului2 (bitul TMR2ON, registrul T2CON[2])
• configurarea regimului de lucru PWM pentru modulul CCP utilizat (biţii
CCPxM3:CCPxM0, registrul CCPxCON[3:0])

Pentru a exemplifica etapa de iniţializare se va considera cazul analizat anterior,


având parametrii de configurare determinaţi prin relaţiile (11.3) şi (11.4).

Exemplu
CONFIGURARE_PWM:
BCF TRISC, TRISC2 ; pin CCP1 de ieşire
BCF T2CON, TMR2ON ; oprire Timer2
MOVLW 0x1E ; configurare T
MOVWF PR2
MOVLW 0x0F ; configurare FU
MOVWF CCPR1L
BSF CCP1CON, DC1B1
BSF CCP1CON, DC1B0
BSF T2CON, T2CKPS1 ; predivizor 16
BSF T2CON, T2CKPS0
BSF T2CON, TMR2ON ; pornire Timer2

198
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
BSF CCP1CON, CCP1M3 ; configurare mod PWM
BSF CCP1CON, CCP1M2
BSF CCP1CON, CCP1M1
BSF CCP1CON, CCP1M0

Una din aplicaţiile în care se utilizează în mod frecvent semnalele PWM se referă la
comanda servomotoarelor. Acestea sunt servomecanisme, care au în structura lor un motor de
curent continuu cuplat cu un senzor de poziţie în cadrul unei bucle de reglare automată
controlată de un regulator intern (de obicei un circuit integrat dedicat). Comanda
servomotoarelor presupune aplicarea unui semnal PWM cu anumite caracteristici pe intrarea4
sa de comandă. În acest fel se transmite către bucla de reglare din structura servomotorului un
semnal de referinţă care conduce la poziţionarea axului motorului la un anumit unghi.
Principiul de comandă al servomotoarelor este pus în evidenţă în Fig. 11.9.

Fig.11.9. Principiul de comandă al servomotoarelor cu ajutorul semnalelor PWM

Astfel, pentru comanda servomotoarelor se folosesc semnale PWM cu perioada


TPWM=20 ms. Poziţia unghiulară a axului motorului este determinată de durata impulsurilor
aplicate (factorul de umplere) pe intrarea de comandă. De exemplu, un impuls de 1.5 ms va
determina poziţionarea motorului la un unghi de 90°. Această poziţie unghiulară corespunde
poziţiei neutre a servomotorului în care cursa sa în ambele direcţii este aceeaşi. Având în
vedere diferitele variante constructive de servomotoare existente şi limitările care pot fi
impuse mişcării de rotaţie ale acestora, este bine de ştiut că fiecare servomotor va avea o
poziţie neutră5 a axului care corespunde unui semnal de comandă PWM cu TPWM=20ms şi

4
În general servomotoarele dispun de trei intrări, două se utilizează pentru alimentare şi cea de-a treia pentru
comandă.
5
Această poziţie unghiulară corespunde unui unghi de 90° dacă limitele de rotaţie ale motorului sunt cuprinse
între 0° şi 180°, sau unei alte poziţii (aflate la mijlocul intervalului) dacă mişcarea de rotaţie a motorului este
limitată între alte unghiuri.

199
MODULUL CCP

FU=1.5ms. Durata minimă şi cea maximă a impulsurilor de comandă care determină rotirea
servomotorului la poziţie unghiulară validă poate să difere de la un producător la altul, dar în
general durata minimă a impulsurilor este de 1 ms, iar cea maximă de 2 ms. Pentru aceste
două valori ale impulsului de comandă axul motorului se va poziţiona la cele două capete ale
intervalului în care este limitată mişcarea de rotaţie a motorului.
Din păcate implementarea comenzii pentru servomotoare cu ajutorul modulului PWM,
în cazul unor frecvenţe de lucru ale microcontrolerului ordinul MHz, devine imposibilă având
în vedere valorile de configurare care rezultă prin utilizarea relaţiilor (11.1) şi (11.2). O
soluţie la această problemă ar putea fi reducerea frecvenţei de lucru sau realizarea semnalelor
PWM necesare prin alte mecanisme (de ex. Timere, CCP în mod de lucru Comparare etc.). De
altfel, pentru toate funcţionalităţile oferite prin cele trei moduri de lucru ale modulelor CCP se
pot găsi soluţii de implementare alternative, care nu necesită în mod neapărat existenţa CCP
în structura microcontrolerului.

11.5 REGISTRUL CCPxCON

Selectarea regimului de lucru pentru cele două module CCP se face prin intermediul
regiştrilor de control CCPxCON. Deoarece factorul de umplere, în modul de lucru PWM se
specifică prin intermediul a 10 biţi, regiştrii CCPxCON conţin cei mai nesemnificativi doi biţi
care intervin în configurarea factorului de umplere dorit.
În Fig. 11.9 se prezintă structura regiştrilor CCPxCON, urmată de descrierea biţilor.

7 0
- - DCxB1 DCxB0 CCPxM3 CCPxM2 CCPxM1 CCPxM0
Fig. 11.9. Regiştrii CCPxCON: CCPx Control Register

Biţii 7-6 Neimplementaţi


Biţii 5-4 DCxB1:DCxB0 – Utilizaţi la specificarea factorului de umplere al semnalului
PWM produs de modulul CCPx
Biţii 3-0 CCPxM3:CCPxM0 – Selectarea regimului de lucru pentru modulul CCPx
0000 = Modul CCPx dezactivat
0001 = Rezervat
0010 = Regim de lucru Comparare. Schimbarea stării pinului CCPx
0011 = Rezervat
0100 = Regim de lucru Captură. Captură la fiecare front descrescător

200
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

0101 = Regim de lucru Captură. Captură la fiecare front crescător


0110 = Regim de lucru Captură. Captură la fiecare al 4-lea front crescător
0111 = Regim de lucru Captură. Captură la fiecare al 16-lea front crescător
1000 = Regim de lucru Comparare. Setare pin CCPx
1001 = Regim de lucru Comparare. Resetare pin CCPx
1010 = Regim de lucru Comparare. Generare întrerupere soft
1011 = Regim de lucru Comparare. Generare eveniment special (reset timer,
declanşare conversie A/D pentru modulul CCP2)
11xx = Regim de lucru PWM

Modulele CCP utilizate în asociere cu Timerele 1, 2 şi 3 asigură, în


funcţie de configurare, capturarea stării Timerului 1/3 la apariţia unui

Concluzii eveniment extern (front pe pin), compararea continuă a stării Timerului


1/3 cu o valoare prestabilită şi generarea unui eveniment la realizarea
egalităţii şi generarea unor impulsuri modulate în lăţime.
Aceste funcţionalităţi permit măsurarea parametrilor anumitor semnale,
implementarea unor evenimente temporizate (ex. eşantionări), controlul
unor circuite analogice din domeniul digital etc.

1. Care este principiul de funcţionare al modulului CCP în mod de


lucru captură?
2. Care este principiul de funcţionare al modulului CCP în mod de
Întrebări de
lucru comparare?
autoevaluare
3. Modulele CCP în modurile de lucru captură şi comparare
funcţionează în asociere cu Timerul1 sau Timerul3. Cum se
selectează timerul utilizat?
4. Cum se poate determina perioada unui semnal dreptunghiular de
intrare cu ajutorul modulului captură?
5. Cum se poate genera un semnal dreptunghiular cu factor de umplere
de 50% cu ajutorul modulului comparare?
6. Cum se poate modifica factorul de umplere al unui semnal PWM
generat cu ajutorul modulului CCP în mod de lucru PWM?

201
MODULUL CCP

Captură
Mod de lucru în care apariţia unui eveniment extern determină salvarea
Termeni valorii timerului în regiştrii de date CCP
esenţiali CCP
Modul de Captură / Compare / PWM
Comparare
Mod de lucru în care atingerea egalităţii valorii timerului cu o valoare
prestabilită determină generarea unui eveniment
Comparator digital
Circuit care permite realizarea unei comparaţii între două valori binare
Factor de umplere
Intervalul de timp dintr-o perioadă cât semnalul este în starea ’1’
Predivizor
Circuit în structura timerelor care permite incrementarea la fiecare n
fronturi ale semnalului de tact
PWM
En. Pulse Width Modulation. Modularea în lăţime a impulsurilor. Tehnică
ce permite controlul circuitelor analogice din domeniul digital.
Timer
Circuit de temporizare

202
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

12.COMUNICAŢII SERIALE

Introducere
Obiective
12.1 PRELIMINARII
Cuprins
12.2 COMUNICAŢII SERIALE SINCRONE DE TIP SPI
IMPLEMENTATE PRIN SOFT
12.2.1 Transmisia
12.2.2 Recepţia
12.3 COMUNICAŢII SERIALE REALIZATE CU AJUTORUL
MODULULUI EUSART
12.3.1 Transmisia serială asincronă
12.3.2 Recepţia serială asincronă
12.3.3 Generarea tactului de comunicaţie
12.3.4 Detectarea automată a tactului de comunicaţie
12.3.5 Structura regiştrilor asociaţi modulului
EUSART
12.3.6 Configurarea comunicaţiei seriale asincrone
12.3.7 Implementarea comunicaţiilor seriale
asincrone cu adresare
12.3.8 Interfaţarea portului serial
12.3.9 Realizarea comunicaţiilor seriale sincrone cu
ajutorul modulului EUSART
Concluzii
Întrebări de autoevaluare
Termeni esenţiali

203
COMUNICAŢII SERIALE

Transmisia paralelă a datelor se realizează rapid şi cu un minim de


complicaţii din punct de vedere al efortului de programare, dar există
situaţii când utilizarea acesteia este nepotrivită, fie datorită costului
Introducere
liniilor de comunicaţii multiple, a indisponibilităţii acestora la
echipamentele hardware care trebuie interfaţate, sau pur şi simplu datorită
distanţelor fizice existente între echipamente. În aceste situaţii, datele pot
fi transmise bit cu bit şi asamblate la destinaţie sub forma paralelă iniţială.
Acest capitol cuprinde prezentarea unor tehnici specifice de realizare a
comunicaţiilor seriale.

După parcurgerea acestui capitol cursantul va trebui:


- să înţeleagă diferenţa între comunicaţiile seriale sincrone şi
asincrone
- să cunoască variantele de implementare ale comunicaţiilor seriale
Obiective disponibile în cazul microcontrolerelor PIC18
- să fie capabil să interfaţeze echipamente seriale utilizând
protocolul de comunicaţie SPI implementat prin program
- să poată utiliza modulul EUSART din structura microcontrolerului
PIC18 în vederea realizării unor comunicaţii seriale
- să înţeleagă rolul circuitului MAX232 în implementarea unei
comunicaţii de tip RS232

12.1 PRELIMINARII

Pentru a înţelege rolul comunicaţiilor seriale să analizăm următorul exemplu din viaţa
cotidiană.
Să considerăm cazul Smart Card-urilor.
Fiecare asemenea card (card de debit / credit, card de sănătate etc.) are
încorporat în structura sa un microcontroler, în general de 8 biţi, ale cărui
Exemplu
contacte pot fi identificate pe una din feţele cardului. Restricţiile impuse de
costul şi utilizarea acestor carduri au condus la simplificarea structurii
microcontrolerului, minimizarea numărului de componente disponibile pe
card, pentru creşterea fiabilităţii, şi mutarea componentelor adiţionale

204
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

microcontrolerului în automatele de citire, care asigură semnalele necesare


funcţionării atunci când cardul este plasat în cititor.
Structura standard a acestor cipuri (Smart Card-uri) pe care le avem fiecare în
posesie este prezentată în Fig. 12.1.

Fig.12.1. Pinii unui Smart Card

După cum se poate observa, contactele disponible asigură două linii de


alimentare (5V, GND), o linie pentru semnalul de Reset, una pentru cel de
Tact şi o linie suplimentară care permite citirea şi scrierea datelor bit cu bit.

12.2 COMUNICAŢII SERIALE SINCRONE DE TIP SPI IMPLEMENTATE PRIN


SOFT

12.2.1 Transmisia

Să considerăm comanda cu microcontrolerul a unui afişaj format din 3 digiţi x 7


segmente realizată cu ajutorul regiştrilor de deplasare 74HCT164 (Fig. 12.2).
Aceştia sunt regiştri de deplasare de 8 biţi cu încărcare serială, datele fiind disponibile
simultan la ieşire1. Datele se deplasează de la Q0 spre Q7 la fiecare front crescător al
semnalului de tact. Datele intră în Q0 prin cele două intrări ale circuitului legate intern la o
poartă logică ŞI. Prin legarea în cascadă a mai multor regiştri (Q7 legat la Q0 următor) se
poate extinde capacitatea de stocare a acestora (trei asemenea regiştri vor asigura necesarul
pentru comanda celor trei digiţi de şapte segmente). Regiştrii de deplasare mai sunt dotaţi cu o
intrare de resetare activă pe zero logic care le şterge conţinutul. În exemplul analizat această
intrare va fi legată permanent la un nivel logic unu.[16]

1
SIPO = Serial In Parallel Out

205
COMUNICAŢII SERIALE

Fig.12.2. Interfaţarea serială a unui afişaj de 3 digiţi x 7 segmente

Pentru interfaţarea acestor circuite se vor folosi doar doi pini ai microcontrolerului pe
care îi vom nota în continuare cu SDO (Serial Data Output) şi SCK (Serial Clock). Pe pinul
SDO se vor trimite datele bit cu bit, începând cu bitul cel mai semnificativ, către circuitul de
afişare, iar pe pinul SCK se va asigura tactul necesar deplasării datelor în regiştri.
Schimbarea valorii afişate pe cei trei digiţi presupune încărcarea a 24 de biţi în
regiştrii de deplasare.
Pentru a serializa acest proces se va proiecta o subrutină şi ulterior o funcţie C care
asigură punerea fiecărui bit al unui registru de date din memorie2 pe pinul RA0/SDO,
începând cu bitul cel mai semnificativ. În acelaşi timp pe pinul RA1/SCK se va asigura tactul
necesar pentru transmiterea datelor. Acest lucru se rezumă la implementarea unei subrutine
sau a unei funcţii C care parcurge următoarele etape:
1. se pune SCK pe 0 logic
2. CONTOR = 8
3. WHILE CONTOR>0 DO:
a. copiază MSB al registrului de date pe pinul SDO
b. deplasează la stânga conţinutul registrului de date
c. generează un impuls pe pinul SCK
d. decrementează CONTOR [6]

Subrutina SPI_WRITE implementează etapele menţionate anterior. Registrul care va


conţine datele va avea numele simbolic DATA_OUT şi va trebui încărcat în prealabil cu
valoarea dorită. De asemenea, pinii RA0 şi RA1 utilizaţi pentru semnalele SDO şi SCK trebuie
iniţializaţi ca pini de ieşire.

2
Acest registru va conţine codul pe şapte segmente corespunzător cifrei dorite

206
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
SPI_WRITE
bcf LATA, 1 ;pas 1 SCK = 0
movlw 8 ;pas 2 CONTOR = 8
movwf CONTOR
test ;pas 3 (a) & (b)
bcf LATA,0 ;SDO = 0
btfsc DATA_OUT,7 ;salt daca MSB = 0
bsf LATA,0 ;daca MSB ≠0 atunci SDO = 1
rlncf DATA_OUT,F ;deplasare date la stanga

bsf LATA,1 ;pas 3 (c) generare impuls SCK=1 apoi SCK=0


bcf LATA,1

decfsz CONTOR,F ;pas 3 (d): CONTOR--


bra test ;repeta pana la transmiterea LSB
return

O posibilă implementare în C a acestei rutine este funcţia void


spi_write(unsigned char data)

#define SDO LATAbits.LATA0


#define SCK LATAbits.LATA1

void spi_write(unsigned char data)


{
int i;
SCK = 0;
for(i=0; i<8; i++) //8 iteratii
{
if(data&0x80) //testeaza MSB
SDO = 1;
else
SDO=0;
SCK = 1; //impuls
SCK = 0;
data=data<<1; //deplasare
}
}

Afişarea cifrelor pe cei trei digiţi folosind circuitul din Fig. 12.2 şi transmisia serială
amintită ridică o singură problemă, aceea că pe durata deplasării celor 24 de biţi, datele de
intrare pe afişajele cu şapte segmente nu sunt valide. Bineînţeles, în exemplul considerat,
ochiul uman nu va sesiza modificările iluminării segmentelor care sunt de ordinul
microsecundelor.
Implementarea din Fig. 12.2 se poate îmbunătăţi prin utilizarea unor circuite
optimizate pentru comunicaţia serială. Acestea au în dotare, pe lângă regiştrii de deplasare
câte un buffer cu rol de menţinere a datelor. De exemplu, circuitul 74HC595 are în structura
sa un buffer de 8 biţi cu încărcare şi descărcare paralelă3 intercalat între registrul de deplasare
şi lumea exterioară. O comandă externă, pe un pin al circuitului, transferă conţinutul
registrului de deplasare spre ieşirile paralele
3
PIPO – Parallel In Parallel Out

207
COMUNICAŢII SERIALE

12.2.2 Recepţia

Recepţia serială se poate realiza într-o manieră similară transmisiei seriale. Să


considerăm cazul unei aplicaţii care trebuie să monitorizeze 24 de senzori, grupaţi câte opt.
Fiecare grup de senzori este conectat la un registru de deplasare 74HCT165 cu
încărcare paralelă şi descărcare serială4.[17] Legarea în cascadă a trei asemenea regiştri
asigură extinderea capacităţii de stocare la necesarul de 24 de biţi. Datele disponibile în aceşti
regiştri pot fi deplasate şi citite bit cu bit de pe un pin al microcontrolerului (de exemplu RA2)
pe care îl vom nota în continuare cu SDI (Serial Data In). După 8 deplasări datele pot fi
asamblate sub forma unui octet care poate fi testat / mascat pentru a determina starea
senzorilor. Deplasarea este asigurată prin tactul pe care trebuie să-l genereze microcontrolerul
pe un pin (de exemplu RA3) pe care îl vom nota în continuare cu SCK (Serial Clock). În Fig.
12.3 se prezintă schema electrică de conectare a acestor circuite, utilizată în vederea efectuării
unei recepţii seriale.

Fig.12.3. Interfaţarea serială pentru 24 de senzori

După cum se poate vedea, există posibilitatea ca recepţia serială să utilizeze acelaşi
pin pentru semnalul de tact ca şi transmisia serială. Astfel, semnalul SCK poate fi legat la
pinul RA1 al microcontrolerului.
Interfaţa serială care citeşte bit cu bit datele de intrare şi le asamblează sub forma unui
octet, disponibil într-un registru din memorie, poate lua forma subrutinei SPI_READ. Această
subrutină este perechea subrutinei SPI_WRITE din paragraful anterior, iar implementarea ei
trebuie să asigure parcurgerea următoarelor etape:
1. se pune SCK pe 0 logic
2. CONTOR = 8

4
PISO – Parallel In Serial Out

208
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

3. WHILE CONTOR>0 DO:


a. generează un impuls pe pinul SCK
b. deplasează la stânga conţinutul registrului de date
c. copiază starea pinului SDI în LSB al registrului de date
d. decrementează CONTOR [6]

Subrutina SPI_READ implementează etapele menţionate anterior. Registrul care va


conţine datele de intrare va avea numele simbolic DATA_IN. Conţinutul acestui registru se va
deplasa la stânga după fiecare bit copiat pe poziţia 0, care a fost precedat de un impuls de tact.
După opt impulsuri de tact, octetul va fi complet asamblat şi va fi disponibil în registrul
DATA_IN. De asemenea, pinul RA2, utilizat pentru semnalul SDI, va trebui iniţializat ca pin
de intrare, iar pinul RA1, utilizat pentru semnalul SCK, trebuie iniţializat ca pin de ieşire.

SPI_READ
bcf LATA, 1 ;pas 1 SCK = 0
movlw 8 ;pas 2 CONTOR = 8
movwf CONTOR
umple ;umple registrul de date
bsf LATA,1 ;pas 3 (a) generare impuls SCK=1 apoi SCK=0
bcf LATA,0
bcf STATUS, C ;sterg bit Carry (acesta va fi LSB daca SDI=0)
rlcf DATA_IN,F ;pas 3 (b) deplasare date la stanga
btfsc PORTA,RA2 ;salt daca SDI = 0
bsf DATA_IN,0 ;pas 3 (c) daca SDI ≠ 0 atunci LSB = 1
decfsz CONTOR,F ;pas 3 (d): CONTOR--
bra umple ;repeta pana la recepţia ultimului bit
return

O posibilă implementare în C a acestei rutine este funcţia unsgined char


spi_read()

#define SDI PORTAbits.RA2


#define SCK LATAbits.LATA1

unsigned char spi_read()


{
int i;
unsgined char data;
SCK = 0;
for(i=0; i<8; i++) //8 iteratii
{
SCK = 1; //impuls
SCK = 0;
data = data<<1; //deplasare la stanga
if(SDI) //testeaza SDI
data = data | 0x01; //setare bit 0 daca SDI=1
else
data = data & 0xFE; //resetare bit 0 daca SDI=0
}
return data;
}

209
COMUNICAŢII SERIALE

Cele două subrutine (SPI_WRITE şi SPI_READ) prezentate până acum pot fi


combinate într-o singură subrutină care asigură simultan atât scrierea cât şi citirea serială. O
asemenea implementare ar asigura o comunicaţie serială de tip full-duplex. Spre deosebire, în
cazul comunicaţiilor half-duplex datele pot fi transmise într-o singură direcţie în acelaşi timp.
Astfel, comunicaţia full-duplex ar necesita trei pini ai microcontrolerului (SCK, SDI, SDO),
iar comunicaţia de tip half-duplex ar putea utiliza doar doi pini (SCK şi SD) pinul de date, în
acest caz, putând fi configurat alternativ ca pin de intrare (SD = SDI) sau pin de ieşire (SD
= SDO).

Protocolul serial descris prin exemplele anterioare poartă denumirea de SPI (Serial
Peripheral Interface) şi a devenit standardizat în cazul multor producători de microcontrolere.
În cazul familiei PIC18, protocolul SPI este implementat hardware sub forma unui modul
special, denumit MSSP, (en. Master Synchronous Serial Port = Port serial pentru comunicaţii
master sincrone) care poate funcţiona în două regimuri de lucru: SPI sau I2C. Existenţa unui
asemenea protocol a permis dezvoltarea unei game largi de echipamente periferice (memorii
EEPROM seriale, convertoare A/D, module de comunicaţii radio etc.) care pot fi interfaţate
direct cu microcontrolerul fără a necesita regiştri de deplasare adiţionali sau implementarea
unor rutine soft (de genul celor prezentate până acum) pentru realizarea comunicaţiei.

12.3 COMUNICAŢII SERIALE REALIZATE CU AJUTORUL MODULULUI EUSART

În afara modulului MSSP, microcontrolerul PIC18F4455 are în dotare un modul


suplimentar care permite realizarea comunicaţiilor seriale. Este vorba despre modulul
EUSART (Enhanced Universal Synchronous Asynchronous Receiver Transmitter) care oferă
trei tipuri de comunicaţie serială:
- comunicaţie asincronă serială (full-duplex)
- comunicaţie sincronă serială (half-duplex) de tip master-sincron
- comunicaţie sincronă serială (half-duplex) de tip slave-sincron
Indiferent de tipul comunicaţiei seriale realizate, biţii de date sunt transmişi şi
recepţionaţi unul după altul, fiind transformaţi în date paralele în cadrul modulului EUSART.
Caracteristica principală a protocolului serial sincron discutat în capitolul anterior este aceea
că nodul master (în acel caz microcontrolerul) transmitea şi tactul de sincronizare care
permitea diferitelor echipamente slave să recepţioneze sau să transmită date. Spre deosebire
de modul master-sincron există posibilitatea ca microcontrolerul să fie echipamentul care

210
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

recepţionează tactul de sincronizare, în acest caz fiind vorba despre o comunicaţie de tip
slave-sincron. Indiferent că vorbim despre comunicaţie de tip master-sincron sau slave-
sincrom, transmisia sau recepţionarea de date nu este condiţionată de generarea tactului de
sincronizare. Astfel, de exemplu, un nod slave poate realiza atât transmisia cât şi recepţia,
într-o singură direcţie la un moment dat, chiar dacă nu este el sursa tactului de sincroniazare.
O alternativă la aceste tipuri de comunicaţie porneşte de la premisa că echipamentele
implicate în schimbul de date funcţionează la aceeaşi frecvenţă de eşantionare. Astfel, nu mai
există tact de sincronizare, comunicaţia serială fiind una de tip asincron în care părţile trebuie
să se pună de acord în privinţa vitezei de comunicare. Aceste viteze sunt standardizate, având
următoarele valori: 110,300,1200,2400,4800,9600,19200,38400,57600,115200bps. Pentru a
se putea asambla corect datele din fluxul serial de biţi se utilizează o informaţie cadru care
permite specificarea începutului şi sfârşitului unui octet. Astfel, datele transmise fizic pe linie
au formatul din Fig. 12.4. Bitul de start semnalează destinaţiei că urmează a se transmite alţi 8
/ 9 biţi de date (configurabil). După recepţionarea biţilor de date, bitul de stop permite
transferul datelor recepţionate în alţi regiştri pentru o prelucrare internă ulterioară.

Fig.12.4. Formatul datelor seriale

Arhitectura modulului EUSART are la bază doi regiştri de deplasare, unul pentru
transmisie şi celălalt pentru recepţie. Aceştia sunt completaţi de bufferele de date asociate şi
regiştrii de stare. Pentru a activa modulul EUSART trebuie setat bitul SPEN (Serial Port
Enable) din registrul RCSTA[7].
Pinii utilizaţi de modulul EUSART sunt multiplexaţi cu pinii portului C. Astfel, pentru
a configura pinii RC6/TX/CK şi RC7/RX/DT/SDO în vederea realizării unor comunicaţii
seriale asincrone (TX, RX) sau sincrone (CK, DT), aceşti pini trebuie configuraţi în prealabil ca
pini de intrare. Modulul EUSART va reconfigura, în mod automat, direcţia acestor pini în
funcţie de nevoi. În Fig. 12.5 se prezintă denumirea utilizată pentru aceşti pini şi direcţia lor în
cazul celor trei tipuri de comunicaţie serială ce pot fi implementate cu ajutorul modulului
EUSART:
- comunicaţii seriale asincrone full-duplex (Fig. 12.5-a). Comunicaţia se poate realiza
simultan în ambele direcţii.

211
COMUNICAŢII SERIALE

- comunicaţii seriale sincrone de tip master-sincron half-duplex (Fig. 12.5-b).


Microcontrolerul generează tactul de comunicaţie. Comunicaţia se poate realiza într-o
singură direcţie la un moment dat.
- comunicaţii seriale sincrone de tip slave-sincron half-duplex (Fig. 12.5-c).
Microcontrolerul recepţionează tactul de comunicaţie. Comunicaţia se poate realiza
într-o singură direcţie la un moment dat.[7,8]

Fig.12.5. Comunicaţii seriale implementate de modulul EUSART

12.3.1 Transmisia serială asincronă

Structura blocului de transmisie se prezintă în Fig. 12.6.

Fig. 12.6. Blocul de transmisie serială conform foii de catalog [15]

Logica de transmisie se activează prin setarea bitului TXEN (Transmit Enable) din
registrul TXSTA[5]. Pentru a trimite un caracter acesta trebuie mutat în registrul TXREG
(Transmit Register) de unde va fi transferat către registrul de deplasare TSR (Transmit Shift

212
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Register)5. Dacă se doreşte realizarea unei comunicaţii pe 9 biţi se poate opta pentru acest
format de date prin intermediul bitului TX9 din registrul TXSTA[6]. Al nouălea bit de date
va fi bitul TX9D din registrul TXSTA[0] şi va trebui iniţializat înainte de a scrie octetul de
date în registrul TXREG. Datele din registrul TXREG vor fi transferate în registrul de deplasare
TSR numai după ce acesta din urmă va fi gol (adică când nu mai sunt date în curs de
transmitere).
Starea registrului de deplasare este indicată de bitul TRMT din registrul TXSTA[1],
iar golirea registrului TXREG va fi semnalizată prin setarea bitului indicator de întrerupere
TXIF din registrul PIR1[4]. Dacă se doreşte generarea unei întreruperi, atunci trebuie setat
şi bitul de validare corespunzător TXIE din registrul PIE1[4] (vezi Cap.9 – Sistemul de
întreruperi). Indiferent dacă întreruperea a fost validată sau nu, bitul TXIF va fi setat în mod
automat după realizarea transferului de date din TXREG în TSR, dar spre deosebire de biţii de
indicatori de întrerupere utilizaţi de alte periferice, bitul TXIF nu poate fi resetat manual din
program. Acesta va fi resetat automat după încărcarea unor noi date în registrul TXREG6.
Utilizatorul are la dispoziţie două variante pentru a determina dacă poate transmite
date noi. Fie interoghează bitul indicator de întrerupere TXIF (o testare care urmează imediat
după încărcarea datelor în TXREG poate conduce la rezultate neconcludente din cauza celor
două cicluri instrucţiune necesare pentru resetarea bitului TXIF), fie testează bitul TRMT
pentru a determina dacă datele au fost transmise fizic pe linie. Dacă se optează pentru
utilizarea întreruperii la transmisie aplicaţia poate asigura un flux de date continuu.

12.3.2. Recepţia serială asincronă

Structura blocului de transmisie se prezintă în Fig. 12.7.


Logica de recepţie serială se activează prin setarea bitului CREN din registrul
RCSTA[4]. Astfel, la detecţia bitului unui bit de start pe pinul RX următorii 8 biţi de date
vor fi stocaţi şi deplasaţi pe rând în registrul de deplasare RSR (Reception Shift Register).
Acest lucru se produce independent de funcţionarea părţii de transmisie. Când datele
recepţionate sunt complete (au sosit cei 8 biţi) acestea sunt transferate în mod automat către
registrul de recepţie RCREG de unde pot fi citite. Bitul indicator de întrerupere RCIF din
registrul PIR1[5] este setat automat de fiecare dată când sunt date disponibile pentru citire.

5
TSR este un registru intern care nu poate fi accesat din program
6
De fapt se va reseta după două cicluri instrucţiune de la încărcarea datelor în TXREG

213
COMUNICAŢII SERIALE

Dacă întreruperea de recepţie este activată prin setarea bitului RCIE din registrul PIE1[5]
şi sistemul de întreruperi este configurat cu atare (biţii GIE, PEIE) atunci se poate genera o
întrerupere la recepţia datelor. Citirea datelor disponibile în registrul RCREG determină
şteregerea automată a bitul indicator de întrerupere RCIF. Dacă după citire sunt date
disponibile în registrul RSR, acestea vor fi transferate automat în registrul RCREG şi se va
seta din nou bitul RCIF.

Fig. 12.7. Blocul de recepţie serială conform foii de catalog [15]

Dacă în acest timp se recepţionează un al treilea caracter, iar cei doi regiştri implicaţi
în recepţie sunt plini se va genera un semnal de eroare de suprascriere (en. Overflow error)
marcat prin setarea bitului de stare OERR din registrul RCSTA[1], iar datele vor fi pierdute.
Totuşi, registrul RCREG poate fi citit de două ori pentru a extrage cele două caractere
recepţionate. Pentru a reseta bitul de eroare OERR, logica de recepţie serială trebuie
dezactivată apoi activată din nou prin intermediul bitului CREN. Până nu se realizează acest
lucru nu se vor mai recepţiona alte date.
Eroarea de încadrare (Framing Error) marcată prin setarea bitului FERR din registrul
RCSTA[2] apare în situaţia în care blocul de recepţie a detectat un bit de start, iar după cei 8
biţi de date obţinuţi în urma deplasărilor efectuate în RSR nu se detectează nici un bit de
stop.
Ca şi în cazul recepţiei seriale se poate opta pentru recepţia celui de-al nouălea bit de
date. Acest lucru se face prin setarea bitului RX9 din registrul RCSTA[6], al nouălea bit de
date fiind disponbil în RX9D din registrul RCSTA[0].

214
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

În mod normal, acest bit de date suplimentar poate fi utilizat pentru implementarea
unui mecanism de adresare (vezi Cap. 12.3.7) sau a unui algoritm de testare a parităţii7.

12.3.3 Generarea tactului de comunicaţie

Înainte de a configura recepţia sau transmisia serială trebuie să ne oprim atenţia asupra
vitezei de comunicare. Această etapă este cu atât mai importantă cu cât în cazul
comunicaţiilor asincrone viteza de comunicare trebuie să coincidă în ambele părţi.
Această viteză de comunicare se stabileşte prin configurarea generatorului de tact (en.
BRG = Baud Rate Generator) al modulului de comunicare serială. În acest sens se va
determina o valoare numerică n, a divizorului de frecvenţă, care va genera viteza de
comunicare dorită. Valoarea determinată poate fi una de 8 biţi, caz în care se va înscrie în
registrul SPBRG sau una de 16 biţi, caz în care se va înscrie în perechea SPBRGH:SPBRG.
Bitul BRG16 din registrul BAUDCON[3] este cel care controlează specificarea divizorului pe
8 sau 16 biţi. Alegerea utilizării unui BRG pe 8 sau 16 biţi depinde de eroarea maximă
tolerată dintre viteza dorită şi cea obţinută prin calcule. De regulă, bitul BRG16 este cuplat cu
un alt bit, BRGH din registrul TXSTA[2] pentru asigurarea unei erori mai mici pentru tactul
rezultat sau pentru atingerea unor viteze mici la frecvenţe de lucru mari.
În Tabelul 12.1 sunt centralizate formulele de calcul pentru vitezele de comunicare.

Tabel 2.1. Formule de calcul pentru viteza de comunicaţie [8,15]


Biţi de configurare
BRG / Mod EUSART Formula de calcul
SYNC BRG16 BRGH
FOSC
0 0 0 8 biţi/Comunicaţie asincronă
64 ⋅ (n + 1)
0 0 1 8 biţi/Comunicaţie asincronă FOSC
0 1 0 16 biţi/Comunicaţie asincronă 16 ⋅ (n + 1)

0 1 1 16 biţi/Comunicaţie asincronă
FOSC
1 0 X 8 biţi/Comunicaţie sincronă
4 ⋅ (n + 1)
1 1 X 16 biţi/Comunicaţie sincronă

7
Microcontrolerul nu are posibilitatea de a interpreta paritatea. Acest lucru trebuie făcut din program.

215
COMUNICAŢII SERIALE

Pentru a exemplifica modul calcul al valorii de iniţializare, să considerăm


cazul unei viteze dorite de comunicaţie de 9600bps în cazul unei frecvenţe de
lucru de 20MHz.
Exemplu
Dacă se utilizează un BRG pe 8 biţi (BRG16=0, BRGH=0) atunci pe baza
formulei din tabel se obţine:
FOSC
n= − 1 = 31.55 ≈ 31 (12.1)
64 ⋅ 9600

Deoarece valoarea obţinută pentru n nu este un număr întreg, apare o difernţă


între valoarea reală a vitezei de comunicaţie şi valoarea dorită.
Astfel, pentru n=31 se obţine viteza calculată BAUDC =9765bps. În aceste
condiţii, conform relaţiei (12.2) există o eroare de ε=1.7% între viteza dorită
(BAUDD) şi cea care se obţine prin configurarea modulului BRG cu valoarea
n=31.
BAUDC − BAUDD
ε= = 1.7% (12.2)
BAUDD

Dacă se optează pentru un BRG pe 16 biţi (BRG16=1, BRGH=0) atunci pe


baza formulei din tabel se obţine:
FOSC
n= − 1 = 129.2 ≈ 129 (12.3)
16 ⋅ 9600
care asigură o viteză reală BAUDC =9615bps şi implicit o eroare ε=0.15%
faţă de viteza dorită.
În general, atunci când este posibil se recomandă testarea tuturor celor trei
formule din tabelul 2.1 pentru a determina acea valoare de iniţializare care
asigură eroarea minimă. Se consideră valori adecvate pentru iniţilizare cele
care asigură o eroare mai mică de 2%.

12.3.4 Detectarea automată a tactului de comunicaţie

Modulul EUSART permite detectarea automată a tactului de comunicaţie prin


măsurarea timpului de recepţionare a biţilor din primului octet primit. Pentru a utiliza acest
mecanism, utlizatorul trebuie să seteze biţii WUE (en. Wake Up Enable) şi ABDEN (en. Auto
Baud Detect Enable) din registrul BAUDCON[1:0] .

216
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

După setarea bitului ABDEN, se şterge automat conţinutul BRG şi începe căutarea unui bit de
start. Pentru a putea calcula viteza de comunicare trebuie să se recepţioneze un octet cu
valoarea 55h8 (în ASCII caracterul ‘U’).
După recepţionarea celor 8 biţi de date, valoarea medie calculată pentru BRG este
depusă în perechea de regiştri SPBRGH:SPBRG, iar bitul ABDEN este şters automat. Din
păcate, nu toate combinaţiile de frecvenţă de lucru şi frecvenţă de comunicare pot fi detectate
cu succes de microcontroler. Din acest motiv, utlizarea detecţiei automate trebuie folosită cu
grijă, doar după o testare a plajei de viteze care pot fi detectate.[8]

12.3.5 Structura regiştrilor asociaţi modulului EUSART

Funcţionarea modulului EUSART este controlată prin intermediul a trei regiştri:


- TXSTA – Transmit Status and Control
- RCSTA – Receive Status and Control
- BAUDCON – Baud Rate Control

Regiştrii de control TXSTA (Fig. 12.8) şi RCSTA (Fig. 12.9) permit configurarea
transmisiei şi recepţiei seriale şi cuprind totodată în structura lor o serie de biţi indicatori ai
stării comunicaţiei.

7 0
CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
Fig. 12.8. Registrul TXSTA: Transmit Status and Control

Bit 7 CSRC – Bit de selecţie a tactului de comunicaţie


Neutilizat la comunicaţia asincronă
1 = master-sincron
0 = slave-sincron
Bit 6 TX9 – Bit de activare a transmisiei pe 9 biţi
1 = selectare transmisie pe 9 biţi
0 = selectare transmisie pe 8 biţi
Bit 5 TXEN – Bit de activare / dezactivare transmisie
1 = activare transmisie
0 = dezactivare transmisie

8
Se va calcula timpul scurs între doi biţi cu aceeaşi stare h’55’=b’01010101’

217
COMUNICAŢII SERIALE

Bit 4 SYNC – Bit de selecţie a tipului de comunicaţie serială


1 = comunicaţie serială sincronă
0 = comunicaţie serială asincronă
Bit 3 SENDB – Bit transmisie caracter “break”
1 = transmisie caracter “break” pornită
0 = transmisie caracter “break” terminată
Neutilizat în cazul comunicaţiilor sincrone
Bit 2 BRGH – Bit de selecţie pentru viteza de transmisie
1 = viteză mare de transmisie
0 = viteză mică de transmisie
Bit 1 TRMT – Bit indicator stare al registrului TSR
1 = registrul de serializare pentru datele transmise este gol
0 = registrul de serializare pentru datele transmise este plin
Bit 0 TX9D – Al 9-lea bit de date
Acest bit poate fi folosit fie pentru implementarea unui mecanism de verificare
a parităţii sau ca bit indicator de adresă în cazul comunicaţiilor seriale cu
adresare sau pur şi simplu ca un bit de date obişnuit.

7 0
SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
Fig. 12.9. Registrul RCSTA: Receive Status and Control

Bit 7 SPEN – Bit de activare / dezactivare transmisie a portului serial


1 = port serial pornit
0 = port serial oprit
Bit 6 RX9 – Bit de activare a recepţiei pe 9 biţi
1 = selectare recepţie pe 9 biţi
0 = selectare recepţie pe 8 biţi
Bit 5 SREN – Bit de activare recepţie singulară
Neutilizat la comunicaţia serială asincronă şi slave-sincronă
În mod de lucru master-sincron
1 = activare recepţie singulară
0 = dezactivare recepţie singulară
Bit 4 CREN – Bit de activare / dezactivare recepţie
1 = activare recepţie
0 = dezactivare recepţie

218
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Bit 3 ADDEN – Bit de activare a detectării adresei


Pentru mod asincron cu 9 biţi de date (RX9=1)
1 = activare detecţie adresă
0 = dezactivare detecţie adresă
Pentru mod asincron cu 8 biţi de date (RX9=0)
Neutilizat
Bit 2 FERR – Bit indicator eroare de încadrare
1 = a fost detectată o eroare de încadrare
0 = nu a fost detectată o eroare de încadrare
Bit 1 OERR – Bit indicator eroare de suprapunere
1 = a fost detectată o eroare de suprapunere
0 = nu a fost detectată o eroare de încadrare
Bit 0 RX9D – Al 9-lea bit de date

Viteza de comunicare se stabileşte prin configurarea registrului de control BAUDCON


al generatorului de rată de transfer şi prin specificarea a doi octeţi stocaţi în regiştrii
SPBRGH:SPBRG. În Fig. 12.10 se prezintă structura registrului BAUDCON.

7 0
ABDOVF RCIDL RXDTP TXCKP BRG16 - WUE ABDEN
Fig. 12.10. Registrul BAUDCON: Baud Rate Control

Bit 7 ABDOVF – Auto-Baud Acquisition Rollover Status bit


Bit 6 RCIDL – Bit indicator al operaţiei de recepţie
1 = nu se recepţionează date
0 = recepţie date în desfăşurare
Bit 5 RXDTP – Bit de selecţie a polarităţii datelor recepţionate
1 = Polaritatea semnalului de pe pinul RX/CK este inversată
0 = Polaritatea semnalului de pe pinul RX/CK nu este inversată
Bit 4 TXCKP – Bit de selecţie a polarităţii datelor recepţionate
1 = Polaritatea semnalului de pe pinul TX/CK este inversată
0 = Polaritatea semnalului de pe pinul TX/CK nu este inversată
Bit 3 BRG16 – Bit de selecţie a generatorului de rată de transfer pe 8 sau 16biţi
1 = Generator de rată de trasfer pe 16 biţi – se utilizează SPBRGH şi SPBRG
0 = Generator de rată de trasfer pe 8 biţi – se utilizează doar SPBRG, valoarea

219
COMUNICAŢII SERIALE

din SPBRGH este ignorată.


Bit 2 Neimplementat
Bit 1 WUE – Wake-up Enable bit
Neutilizat în comunicaţiile sincrone
Bit 0 ABDEN – Auto-Baud Detect Enable bit
Neutilizat în comunicaţiile sincrone

12.3.6. Configurarea comunicaţiei seriale asincrone

Transmisia

Paşii care tebuie urmaţi pentru configurarea modulului de transmisie în vederea


realizării unei comunicaţii seriale asincrone sunt următorii:
• configurarea pinilor RC6/TX/CK şi RC7/RX/DT pentru funcţionare serială prin
setarea biţior TRISC[6,7];
• iniţializarea vitezei de transmisie dorite (regiştrii SPBRGH:SPBRG, bitul BRG16
din registrul BAUDCON[3], bitul BRGH din registrul TXSTA[2])
• activarea comunicaţiei seriale asincrone (bitul SYNC, registrul TXSTA[4]);
• activarea modulului EUSART (bitul SPEN, registrul RCSTA[7]);
• dacă e cazul: inversarea polarităţii semnalului de transmisie (bitul TXCKP,
registrul BAUDCON[4]);
• dacă e cazul: configurarea sistemului de întreruperi
• dacă e cazul: configurarea transmisiei pe 9 biţi (bitul TX9, registrul
TXSTA[6]);
• activarea modulului de transmisie (bitul TXEN, registrul TXSTA[5]);
• dacă s-a selectat transmisa pe 9 biţi, bitul 9 trebuie stocat în TX9D (registrul
TXSTA[0]);
• stocarea datelor în registrul TXREG, pas care porneşte procesul de transmisie;
• testarea flag-ului indicator de întrerupere TXIF=1 (registrul PIR1[4]) în
vederea realizării unei noi transmisii, numai după cel puţin doi cicli instrucţiune
de la pasul anterior;
sau
• testarea bitului TRMT=1 (registrul TXSTA) pentru a determina dacă datele au fost
transmise fizic.
220
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

Recepţia

Paşii care tebuie urmaţi pentru configurarea modulului de recepţie în vederea


realizării unei comunicaţii seriale asincrone sunt următorii:
• configurarea pinilor RC6/TX/CK şi RC7/RX/DT pentru funcţionare serială prin
setarea biţior TRISC[6,7];
• iniţializarea vitezei de transmisie dorite (regiştrii SPBRGH:SPBRG, bitul BRG16
din registrul BAUDCON[3], bitul BRGH din registrul TXSTA[2])
• activarea comunicaţiei seriale asincrone (bitul SYNC, registrul TXSTA[4]);
• activarea modulului EUSART (bitul SPEN, registrul RCSTA[7]);
• dacă e cazul: inversarea polarităţii semnalului de recepţie (bitul RXDTP, registrul
BAUDCON[3]);
• dacă e cazul: configurarea sistemului de întreruperi
• dacă e cazul: configurarea recepţiei pe 9 biţi (bitul RX9, registrul RCSTA[6]);
• activarea modulului de recepţie (bitul CREN, registrul RCSTA[4]);
• la recepţionarea datelor, flag-ul indicator al întreruperii de recepţie este setat
RCIF=1 (registrul PIR1[5]);
• dacă s-a selectat recepţia pe 9 biţi, bitul 9 este RX9D (registrul RCSTA);
• datele recepţionate sunt disponibile în registrul RCREG;
• erorile sunt semnalate de biţii FERR şi OERR (registrul RCSTA[2,1]);
• dacă a avut loc o eroare, biţii de eroare se şterg prin ştergerea bitului CREN,
(registrul RCSTA[4]);

În continuare se va exemplifica modalitatea de utilizare a modului EUSART în


vederea transmisiei şi a recepţionării de date. Se va realiza transmisia şi recepţia
serială asincronă cu viteza de transfer de 9600bps a unui caracter (8 biţi de date).
Exemplu
În cazul unui microcontroler cu o frecvenţă de lucru FOSC=20MHz.

; iniţializare
; configurare pini
BSF TRISC, 6
BSF TRISC, 7
; configurare viteza de transmisie 9600bps9
BSF TXSTA, BRGH ; BRGH=1
BCF BAUDCON, BRG16 ; BRG16=0
MOVLW d'129' ; SPBRG=129 ;
MOVWF SPBRG

9
Vezi rel. (12.3)

221
COMUNICAŢII SERIALE
; activare comunicaţie serială asincronă
BCF TXSTA, SYNC ; SYNC=0
; activare modul EUSART
BSF RCSTA, SPEN ; SPEN=1
; date cu polaritate neinversată
BCF BAUDCON, RXDTP
BCF BAUDCON, TXCKP

; pornire transmisie şi recepţie


BSF TXSTA, TXEN ; pornire transmisie
BSF RCSTA, CREN ; pornire recepţie

...
; transmisia
MOVLW ’A’ ;se transmite caracterul ‘A’
MOVWF TXREG
TEST_TX
BTFSS TXSTA, TRMT ;test sfârşit de transmisie
GOTO TEST_TX ;transmisie în desfăşurare
; când se ajunge în acest punct transmisia s-a realizat

...
; recepţia
TEST_RX
BTFSS PIR1, RCIF ;test recepţie
GOTO TEST_RX
; când se ajunge în acest punct s-au primit date
BCF PIR1, RCIF ;ştergere flag
MOVF RCREG, W ;copiere date în WREG
...

12.3.7. Implementarea comunicaţiilor seriale asincrone cu adresare

Modulul EUSART oferă posibilitatea de a filtra în mod automat recepţia anumitor


mesaje transmise serial. Astfel, octeţii care se recepţionează pot fi încadraţi în două categorii:
adrese, respectiv date. Diferenţa între cele două categorii de octeţi este făcută de al nouălea bit
de date, care poate fi utilizat pentru a indica faptul că cei opt biţi de date reprezintă fie adresa
unui nod, fie date efective care trebuie comunicate în reţea.
În contextul unei anumite configurări a modulului EUSART, care va fi tratată în
continuare, pot fi procesate doar pachetele care codifică o adresă. Această funcţionalitate este
utilizată de obicei la implementarea unor comunicaţii seriale asincrone cu mai mulţi
participanţi, pentru identificarea cărora este necesară o adresă. Schema de principiu a unei
asemenea reţele de comunicaţie este prezentată în Fig.12.11. Echipamentele care realizează
recepţia vor ignora toate pachetele recepţionate care au al nouălea bit pus pe zero şi vor
procesa doar acele pachete care au al nouălea bit setat şi care conţin adrese. Când
echipamentul care realizează recepţia îşi decodifică propria adresă în mesajul recepţionat
poate trece la modul de funcţionare/recepţie obişnuit pentru a recepţiona pachetele de date
222
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

care urmează după adresă. Cei opt biţi de date care se trasnsmit serial utilizaţi în mesajele care
conţin adrese permit adresarea unui număr de până la 255 noduri slave, o adresă fiind
rezervată pentru transmiterea unor mesaje de tip broadcast.[7]

Fig. 12.11. Reţea de microcontrolere bazată pe comunicaţii seriale asincrone cu adresare

Pentru a facilita implementarea unor comunicaţii de acest fel, modulul EUSART poate
fi configurat pentru a seta bitul indicator de întrerupere RCIF doar atunci când al nouălea bit
de date recepţionat este 1 (RX9D = 1). Acest lucru se realizează prin setarea bitului ADDEN
(en. Address Detect Enable) din registrul RCSTA[3] şi bineînţeles activarea recepţiei pe 9
biţi (RX9=1).
În acest context orice recepţie a unui pachet având bitul 9 pus pe 0 va fi ignorată, iar
datele nu vor fi copiate în registrul de recepţie RCREG. La recepţia unui pachet care are bitul 9
setat, datele vor fi copiate din registrul de deplasare RSR în registrul de recepţie RCREG, iar
bitul RCIF va fi setat. Nodul slave va putea citi datele disponibile în RCREG, resetând astfel
şi bitul RCIF, iar dacă îşi va decodifica adresa va putea reseta bitul ADDEN şi toate pachetele
ulterioare vor putea fi citite în mod obişnuit. În acelaşi timp, nodul slave poate continua să
monitorizeze al nouălea bit RX9D, iar masterul poate termina conversaţia prin trimiterea unui
pachet de date care va avea bitul nouă setat.

Să presupunem că avem o reţea de microcontrolere de tipul celei din Fig.12.11,


iar nodul master doreşte să transmită un mesaj format dintr-un singur caracter
(de ex. ‘A’) nodului slave cu adresa 3.
Exemplu
Pentru implementarea mecanismului de adresare, iniţial toate microcontrolerele
vor avea setaţi biţii ADDEN, respectiv RX9.
Nodul master va trimite în reţea un mesaj cu structura din Fig.12.12, în care al
nouălea bit de date (TX9D) este setat, iar următorii opt biţi de date reprezintă
adresa nodului destinaţie.
8 7 0
1 Adresa microcontroler 3
Fig. 12.12. Structura mesajului de adresare

223
COMUNICAŢII SERIALE

Toate nodurile vor recepţiona acest mesaj. În cazul fiecărui nod în parte mesajul
va fi copiat în registrul RCREG şi se va produce setarea bitului indicator de
întrerupere RCIF. Fiecare nod în parte va citi mesajul primit şi îl va compara cu
adresa proprie. Adresa va coincide doar în cazul nodului cu adresa 3. Acesta va
reseta bitul ADDEN. Toate celelalte noduri, care nu şi-au decodificat adresa vor
păstra setat bitul ADDEN.
După transmiterea mesajului de adresare, nodul master va formula un mesaj care
va conţine datele dorite. Al nouălea bit de date va fi în acest caz TX9D=0. Acest
mesaj are forma din Fig. 12.13.

8 7 0
0 Caracterul ‘A’
Fig. 12.13. Structura mesajului de date

Noul mesaj va fi recepţionat doar de nodul cu adresa 3, fiind ignorat de celelalte


noduri, deoarece acesta este singurul nod care nu are bitul ADDEN setat. La
setarea bitului indicator de întrerupere RCIF, nodul 3 va putea citi datele şi va
putea de asemenea citi şi al nouălea bit (RX9D).
Prin interogarea acestui bit nodul cu adresa 3 va putea determina momentul în
care nodul master decide să transmită un nou mesaj de adresare, care va fi
marcat de MSB = 1 (TX9D=1). În acest moment, nodul 3 va putea reveni la
starea avută iniţial prin setarea bitului ADDEN, aşteptând un nou mesaj care să îi
fie destinat.

12.3.8 Interfaţarea portului serial

De-a lungul timpului s-au dezvoltat numeroase standarde de comunicaţie create iniţial
pentru diferite cerinţe hardware care nu aveau nici o legătură cu microcontrolerele PIC.
Specificaţiile electrice ale portului serial sunt conţinute în standardul EIA (Electronics
Industry Association) RS232C. Acest standard a fost introdus în anul 1969, în era
modemurilor şi a liniilor telefonice şi definea interfaţa standard care permite realizarea unor
comunicaţii seriale între Echipamentele Terminale pentru Date – DTE (de exemplu PC-urile)
şi Echipamentele de Comunicaţii Date – DCE (de obicei modemuri).

224
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

În standardul amintit se specifică o mulţime de parametri care caracterizează


comunicaţia serială din punct de vedere al vitezelor de transmisie, al nivelului semnalelor
utilizate etc. Totodată sunt introduse şi o serie de linii de control suplimentare utilizate în
cazul protocoalelor seriale implementate între diferite echipamente.
Printre altele, standardul RS-232 specifică o distanţă maximă de comunicare de 15m
obţinută prin utilizarea unor nivele de tensiune cuprinse între –3V şi –15V pentru ‘1’ logic şi
între +3V şi +15V pentru ‘0’ logic. În mod tipic, tensiunile cel mai des utilizate sunt ±12V, iar
echipamentul de recepţie trebuie să poată face distincţia între nivele de tensiune de ±3V. (Fig
12.14)

Fig. 12.14. Comunicaţii RS232

În timp, utilizarea comunicaţiilor de tip RS232 s-a extins şi în afara domeniul pentru
care a fost dezvoltat iniţial standardul (interconectarea DTE-DCE). În consecinţă, realizarea
interfaţării dintre sistemele de calcul bazate pe microcontrolere PIC şi echipamentele care
respectă acest standard presupune anumite costuri privind complexitatea hardware şi cea
software a sistemului. De exemplu, conectarea unui microsistem bazat pe PIC la un PC prin
intermediul portului serial RS-232-C, presupune conformarea cu acest standard, iar acest
lucru nu se poate realiza direct, decât în prezenţa unui circuit adiţional (MAX232).
Astfel, în Fig. 12.15 se prezintă modul de realizare a conexiunii între un
microcontroler PIC şi portul serial al unui PC sau orice alt echipament dotat cu port serial
asincron RS232.
După cum se poate vedea din Fig. 12.15, dar şi din specificaţiile standardului amintite
anterior, nu se poate realiza legătura directă între microcontroler şi portul serial RS232 al PC-
ului. În acest context, se utilizează un circuit MAX232 care adaptează nivelele de tensiune de
pe pinii microcontrolerului (0V – 0 logic / 5V – 1 logic) la nivelele de tensiune de +12V
(pentru 0 logic), respectiv -12V (pentru 1 logic) cerute de standardul RS232.[20] Dacă
protocolul de comunicaţie nu necesită linii de control suplimentare, cum se întâmplă în cazul
multor aplicaţii, PC-ul poate fi “convins” că discută cu un echipament de tip DCE. Acest
lucru se realizează, prin conectarea pinului RTS cu pinul CTS şi prin conectarea pinilor DTR,

225
COMUNICAŢII SERIALE

DSR şi CD împreună. (en. Loopback = conexiune în buclă). Pe de altă parte, circuitul


MAX232 dispune de câte două buffere pentru transmisie şi două pentru recepţie care pot fi
utilizate pentru implementarea unor linii de control suplimentare dacă protocolul serial o cere.

Fig. 12.15. Comunicaţie RS232 între un microcontroler şi un PC

12.3.9 Realizarea comunicaţiilor seriale sincrone cu ajutorul modulului


EUSART

Master-sincron

Modul master-sincron (mod half-duplex) presupune că echipamentul configurat astfel


va genera un semnal de tact de sincronizare a transmisiei/recepţiei. Acest mod se utilizează de
regulă în comunicarea cu echipamentele care nu sunt capabile să genereze un tact propriu
intern: memorii, convertoare, senzori, etc. Utilizarea EUSART în mod de lucru sincron se
realizează prin setarea bitului SYNC din registrul TXSTA[4].
Alegerea modului de lucru master-sincron se realizează prin setarea suplimentară a
bitului CSRC din registru TXSTA[7]. În acest mod comunicaţia realizată este de tip half-
duplex şi se produce doar îmtr-o singură direcţie la un moment dat. Astfel transmiterea şi
recepţionarea simultană nu este posibilă. În acest caz, pinii TX şi RX joacă alte roluri:
- TX devine CK: pinul pe care se transmite tactul de comunicare;
- RX devine DT: pinul pe care se transmit/recepţionează datele, sau altfel spus, linia de
date.
Pentru a recepţiona sau transmite date în mod master-sincron, se utilizează aceleaşi
setări ca şi în cazul comunicaţiilor asincrone, diferenţa constând în setarea celor doi biţi SYNC

226
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

şi CSRC. Totuşi, trebuie acordată o atenţie deosebită la alternarea recepţionării cu


transmiterea.
După configurarea modului master-sincron, utilizarea modulului EUSART devine
identică cu cea din modul de lucru asincron. Se folosesc aceiaşi regiştri pentru transmitere şi
recepţionare; aceieaşi biţi de semnalizare a terminării transmisiei/recepţiei.[8]

Slave-sincron

Modul slave-sincron (mod half-duplex) presupune că tactul este generat de un alt


echipament pe pinul TX/CK, iar pinul RX/DT este linia de date. Utilizarea modulului
EUSART în mod sincron se realizează, ca şi în cazul anterior, prin setarea bitului SYNC din
registrul TXSTA[4], iar alegerea modului slave-sincron implică ştergerea bitului CSRC din
registrul TXSTA[7].
În afară de biţii SYNC şi CSRC, configurarea transmisiei/recepţiei se realizează în mod
identic cu cazul asincron. Acest lucru este valabil atât pentru manipularea datelor recepţionate
cât şi a biţilor de semnalizare. Fiind o comunicaţie half-duplex, şi în acest caz trebuie avut
grijă la selectarea alternativă a transmisiei sau a recepţiei.[8]

Comunicaţiile digitale sunt disponibile sub două forme: comunicaţii


paralele şi seriale. În cazul comunicaţiilor seriale datele sunt transferate

Concluzii bit cu bit pe un singur canal de comunicaţie. În comunicaţiile paralele,


datele care formează un caracter sunt trimise simultan pe mai multe linii.
Optarea pentru o soluţie de comunicaţie sau alta este în general o
problemă de hardware, care vizează mai exact lipsa sau disponibilitatea
unui număr suficient de linii de comunicaţie.
Comunicaţiile seriale asigură suportul interconectării de numeroase
echipamente cu microcontrolerul (memorii, senzori, afişaje LCD, alte
microcontrolere, PC-uri etc.). Deşi subiectul comunicaţiilor şi
protocoalelor seriale este unul foarte vast, acest capitol s-a oprit doar
asupra câtorva implementări posibile cu ajutorul microcontrolerelor
PIC18. Astfel, s-au prezentat: comunicaţiile seriale sincrone de tip SPI
realizate prin program, respectiv comunicaţiile seriale asincrone şi
sincrone realizate cu ajutorul modulului EUSART.

227
COMUNICAŢII SERIALE

1. Scrieti o funcţie C care implementează o comunicaţie de tip SPI


bidirecţională.
2. La ce pot fi utilizate comunicaţiile seriale cu 9 biţi de date?
Întrebări de
3. Care este principiul de funcţionare al regiştrilor de deplasare
autoevaluare
74HCT164 şi 74HCT165?
4. Cum se realizează detectarea automată a vitezei de comunicaţie?
5. Discutaţi modul de implementare al unei comunicaţii seriale cu
adresare.
6. Scrieţi codul C echivalent pentru exemplul de la paragraful 12.3.6.

Baud rate
Viteza de transmisie măsurată în biţi pe secundă
Termeni Bit de paritate
esenţiali Bit opţional, care se transmite după cei 8 biţi de date utilizat pentru
verificarea erorilor de comunicaţie. Dacă se optează pentru paritate pară,
nodul care transmite setează sau şterge bitul de paritate astfel încât suma
biţilor de 1 ai caracterului transmis să fie pară. În cazul parităţii impare,
bitul se specifică astfel încât suma biţilor de 1 să fie impară. La recepţie se
poate testa paritatea pentru a vedea dacă pe durata transmisiei s-a alterat
vreun bit de date.
Bit de start
Bit cu valoare logică 0 care indică faptul că în fluxul serial urmează biţi
de date.
Bit de stop
Bit cu valoarea logică 1 inserat în fluxul serial care face parte din
informaţia cadru care însoţeşte un octet de date. Are rolul de a asigura
receptorului timp suficient pentru a se pregăti pentru următorul pachet de
date.
BRG
en. Baud Rate Generator. Bloc în structura modulului EUSART care
generează tactul pentru comunicaţia serială
Comunicaţie serială asincronă
Comunicaţie full-duplex în care echipamentele implicate în schimbul de
date funcţionează la aceeaşi frecvenţă de eşantionare. Astfel, părţile

228
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455

trebuie să se pună de acord în privinţa vitezei de comunicare.


Comunicaţie serială sincronă
Comunicaţie half-duplex în care datele sunt sincronizate cu un semnal de
tact care se transmite separat pe o linie
Eroare de încadrare
Eroare care apare la recepţia serială atunci când se detectează un bit de
start, iar după cei 8 biţi de date nu se detectează nici un bit de stop.
Eroare de suprascriere
Eroare care apare la recepţia serială atunci când datele nu sunt citite
suficient de repede
EUSART
En. Enhanced Universal Synchronous Asynchronous Receiver
Transmitter. Modul care permite realizarea comunicaţiilor seriale sincrone
şi asincrone
Full duplex
Comunicaţie care se poate realize simultan în ambele sensuri
Half duplex
Comunicaţie care se poate realiza în ambele sensuri, dar într-un singur
sens la un moment dat
MSSP
En. Master Synchronous Serial Port = Port serial pentru comunicaţii
master sincrone. Modul în structura microcontrolerului PIC18 care
permite implementarea de comunicaţii master sincrone.
Nod master
Nod care generează tactul pentru comunicaţie seriale sincrone
Nod slave
Nod care recepţionează tactul din comunicaţie seriale sincrone
PISO
En. Parallel In Serial Out. Registru de deplasare cu încărcare paralelă şi
descărcare serială a datelor
RS-232-C
Standard care reglementează comunicaţiile seriale între un DTE şi un
DCE
SIPO
En. Serial In Parallel Out. Registru de deplasare cu încărcare serială şi

229
COMUNICAŢII SERIALE

descărcare paralelă a datelor


Smart Card
Card care are încorporat în structura sa un circuit integrat sau un
microcontroler
SPI
En. Serial Peripheral Interface. Protocol serial sincron full duplex. În
general utilizează trei fire notate după cum urmează SCK, SDO, SDI

230
Facultatea de Inginerie și
Tehnologia Informației

Curs 1 – Arhitectura generală

SISTEME CU MICROPROCESOARE

Șef lucr. dr. ing. Duka Adrian-Vasile

Pentru uz intern
Este interzisă copierea și distribuirea neautorizată a acestui material.
Introducere

Bibliografie, cerinţe etc.:


1. Duka A., Genge B., Haller P., “Sisteme cu microprocesoare. Microcontrolerul
PIC18F4455”, Ed. UPM 2013
• Suport de curs
• carte în format electronic (CD)
• pdf disponibil pe http://ecampus.upm.ro / Microsoft Teams

Este interzisă copierea și distribuirea neautorizată a acestui material.


Introducere

Bibliografie, cerinţe etc.:


2. Genge B., Haller P., “Proiectarea sistemelor dedicate si incorporate cu
microcontrolerul PIC”, Ed. UPM 2008
• Carte tipărită
• format electronic disponibil pe
http://cs.engineering.upm.ro/Aquila/stud/Profesor/Haller

Este interzisă copierea și distribuirea neautorizată a acestui material.


Introducere

Bibliografie, cerinţe etc.:


3. Duka A., Jovrea T.,”Sisteme cu microprocesoare. Microcontrolerul PIC18F4455.
Îndrumător de laborator”, UPM 2010
• Îndrumător de laborator
• Material tipărit
• pdf disponibil pe http://ecampus.upm.ro / Microsoft Teams

Este interzisă copierea și distribuirea neautorizată a acestui material.


Introducere

Bibliografie, cerinţe etc.:


4. Microchip – PIC18F2455/2550/4455/4550 Data Sheet, Microchip
Technology Inc., 2006.
• foaie de catalog în format electronic
• pdf disponibil pe google.com, microchip.com, http://ecampus.upm.ro /
Microsoft Teams

Este interzisă copierea și distribuirea neautorizată a acestui material.


Introducere
Bibliografie, cerinţe etc.:
Software
Mediu de dezvoltare
Microchip MPLAB IDE v8.92 – ultima versiune din 06/2013
sau
Microchip MPLAB X IDE v5.30 – ultima versiune din 10/2019
Compilator C
MPLAB C Compiler for PIC18 (MCC18 v3.45)

+ Drivere placă de dezvoltare, HyperTerminal, PDFSUSB, simulator circuite


etc.

Este interzisă copierea și distribuirea neautorizată a acestui material.


Introducere

Bibliografie, cerinţe etc.:


Hardware
Placă de dezvoltare cu microcontroler
PIC18F4455 şi accesorii (baghetă cu LED-uri,
LED-uri RGB, speaker, cabluri pentru
comunicaţii, potenţiometre etc.)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Introducere

Bibliografie, cerinţe etc.:


Alte resurse:
• Diverse scheme electronice
• google
• Tutoriale video disponibile platforma ecampus sau Microsoft Teams.

Este interzisă copierea și distribuirea neautorizată a acestui material.


Introducere

Bibliografie, cerinţe etc.:


IMPORTANT: NOTA FINALĂ !!!
• Pondere 1/3: nota pe lucrările de laborator (min. 5 )
• Pondere 1/3: nota pe proiect individual (min. 5)
• Pondere 1/3: nota pe examen de tip test grilă
• Toate lucrările de laborator sunt obligatorii şi vor fi evaluate săptămânal

Este interzisă copierea și distribuirea neautorizată a acestui material.


De ce sist. cu microprocesoare?

“I think there is a world market for maybe five


computers.”
Thomas Watson, Chairman of IBM, 1943

“There is no reason anyone would want a computer


in their home.”
Ken Olson, President of Digital Equipment Corporation, 1977

Peste 6 miliarde de microprocesoare sunt produse anual, din


care sub 2% sunt utilizate în PC-uri

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective
1.1 ARHITECTURA VON NEUMANN
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective
1.1 ARHITECTURA VON NEUMANN
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
Concluzii

12/7
Este interzisă copierea și distribuirea neautorizată a acestui material.
Obiective

La finalul acestui capitol cursantul trebuie să


cunoască diferenţa între:
Arhitectura von Neumann şi Harvard
Microcontrolere şi microprocesoare

Este interzisă copierea și distribuirea neautorizată a acestui material.


Obiective

La finalul acestui capitol cursantul trebuie să


cunoască:
Structura generală a sistemelor de calcul
Componentele sistemelor de calcul şi rolul acestora
Modul de execuţie al instrucţiunilor
Conceptul de pipeline
rolul regiştrilor WREG şi STATUS

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective
1.1 ARHITECTURA VON NEUMANN
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Unitatea centrală de prelucrare (UCP)


 Execută instrucţiunile stocate în memorie
 Supervizează şi comandă celelalte componente ale sistemului

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Unitatea centrală de prelucrare (UCP) - componente


 Unitate de control
 Unitate aritmetică şi logică
 Regiştri interni

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Magistralele
 căile de comunicaţie ale sistemului de calcul
 colecţie de fire pe care informaţia circulă paralel

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Magistralele
 Magistrala de date
 Magistrala de adrese
 Magistrala de control

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Magistralele
Exemplu: Capacitatea de adresare a unui microsistem este de
4kB. Câte linii de adresă va avea magistrala de adrese a
acestui sistem?

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Magistralele
Exemplu: Capacitatea de adresare a unui microsistem este de
4kB. Câte linii de adresă va avea magistrala de adrese a
acestui sistem?

4kB = 4x210B=212B => 12 linii de adresă

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Memoria
 spaţiu de stocare
 datele şi instrucţiunile se găsesc în acelaşi spaţiu de memorie
 locaţie (adresă) vs. conţinut

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Echipamentele de intrare ieşire


 interfaţa dintre sistemul de calcul şi mediul înconjurător

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura von Neumann

Avantaje
 simplitatea arhitecturii
 flexibilitatea sistemului
Dezavantaj
Accesul la datele din memorie nu se poate produce în acelaşi timp
cu extragerea instrucţiunii din memorie  scade viteza de lucru

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective
1.1 ARHITECTURA VON NEUMANN
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura Harvard

Datele şi instrucţiunile sunt stocate în spaţii de memorie


distincte accesate prin magistrale proprii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Arhitectura Harvard

Avantaj
 datele şi instrucţiunile pot fi accesate în acelaşi timp
Dezavantaj
 creşte complexitatea arhitecturii interne

Este interzisă copierea și distribuirea neautorizată a acestui material.


von Neumann vs. Harvard

 memorie unică

 memorii separate

Comparaţie între arhitecturile von Neumann şi Harvard

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective
1.1 ARHITECTURA VON NEUMANN
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Microprocesor sau microcontroler

Microprocesor = UCP

Microcontroler = sistem de calcul încapsulat

De ce microcontrolere?
Exemplu: cum s-ar realiza citirea periodică la fiecare 5ms
a unui senzor conectat pe un bit al unui port?

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC

Exemplu: sistem de control al unei sere


 Se monitorizează umiditatea solului
 Se comandă un sistem de irigaţie (5 s. ON, 5 s. OFF)
până la restabilirea umidităţii
 Se măsoară nivelul apei dintr-un rezervor
 Se semnalizează sonor golirea rezervorului

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC

Exemplu: sistem de control al unei sere

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC

Structura generală

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective
1.1 ARHITECTURA VON NEUMANN
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

 PIC = Programmable Intelligent Computer


 Produs al companiei Microchip Technology
 www.microchip.com
 Mediul de dezvoltare MPLAB IDE (gratuit)
 Posibilitate de a dezvolta aplicaţiile în limbaj de
asamblare sau în limbaj C

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

Caracteristici PIC18
 instrucţiuni pe 16 biţi
 magistrală internă de 8 biţi
 RISC = Reduced Instruction Set Computer
 arhitectură Harvard
 memorie program de tip flash
 memorie de date adresabilă liniar
 protocoale de comunicaţii diverse etc.

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

Execuţia instrucţiunilor  2 faze


 Faza de extragere – 4 tacţi
 Faza de execuţie – 4 tacţi
 decodificare instrucţiune – Q1
 extragere operanzi – Q2
 efectuarea operaţiei – Q3
 scrierea rezultatului – Q4

Arhitectura Harvard permite suprapunerea celor 2 faze


 pipeline pe 2 nivele

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

Execuţia instrucţiunilor

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

Execuţia instrucţiunilor

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

Unitatea de control – schema bloc simplificată

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

Unitatea aritmetică şi logică (UAL)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura internă a uC din fam. PIC18F

Operaţiile aritmetice şi logice pot genera o serie de indicatori


ce vor fi stocaţi în registrul de stare STATUS

- - - N OV Z DC C

Registrul STATUS

C – Carry Z – Zero
OV – Overflow DC – Digit Carry
N – Negative

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective
1.1 ARHITECTURA VON NEUMANN
1.2 ARHITECTURA HARVARD
1.3 MICROPROCESOR SAU MICROCONTROLER?
1.4 STRUCTURA INTERNĂ A MICROCONTROLERELOR
DIN FAMILIA PIC18F
Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Concluzii

În acest curs s-au studiat următoarele:


 Arhitecturile von Neumann şi Harvard
 Rolul elementelor componente ale sistemelor de calcul
 Avantajele şi dezavantajele celor două tipuri de arhitecturi
 Diferenţa dintre microprocesoare si microcontrolere
 Structura generală a microcontrolerelor
 Modul de execuţie al instrucţiunilor
 Conceptul de pipeline cu unităţile sale de extragere şi execuţie paralele
 Structura unităţii de control şi a UAL

Este interzisă copierea și distribuirea neautorizată a acestui material.


Vă mulţumesc pentru atenţie!

Este interzisă copierea și distribuirea neautorizată a acestui material.


Facultatea de Inginerie și
Tehnologia Informației

Curs 2 – Setul de instrucțiuni

SISTEME CU MICROPROCESOARE

Șef lucr. dr. ing. Duka Adrian-Vasile

Pentru uz intern
Este interzisă copierea și distribuirea neautorizată a acestui material.
Cuprins

Obiective

2.1 FORMATUL INSTRUCŢIUNILOR

2.2 CLASIFICAREA INSTRUCŢIUNILOR

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

2.1 FORMATUL INSTRUCŢIUNILOR

2.2 CLASIFICAREA INSTRUCŢIUNILOR

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Obiective

La finalul acestui capitol cursantul trebuie:


 să cunoască instrucţiunile disponibile
 să cunoască modul în care sunt codificate
instrucţiunile în memoria program
 să cunoască rolul parametrilor instrucţiunilor
 să utilizeze instrucţiunile pentru implementarea
operaţiilor necesare în diferite programe

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

2.1 FORMATUL INSTRUCŢIUNILOR

2.2 CLASIFICAREA INSTRUCŢIUNILOR

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor

RISC = Set Redus de Instrucţiuni

Setul de instrucţiuni cuprinde:


 75 de instrucţiuni
 71 de instrucţiuni pe 16 biţi
 4 instrucţiuni pe 32 biţi

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor

Instrucţiunile realizează operaţii asupra unor date


din memorie

O instrucţiune trebuie să informeze UCP despre:


 tipul operaţiei realizate
 locul unde se găsesc datele cu care instrucţiunea operează.

O instrucţiune va codifica binar următoarele informaţii:


 codul operaţiei
 unul sau mai multi operanzi

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor

Sunt definite 4 formate de instrucţiuni:


 instrucţiuni pe octet
 instrucţiuni pe bit
 instrucţiuni cu constante (literali)
 instrucţiuni de control

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe octet:

Au 3 operanzi:
 Registrul (f)
 Destinaţia rezultatului (d)
 Zona de memorie accesată (a)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe octet:

Au 3 operanzi:
 Registrul (f)
 Destinaţia rezultatului (d)
 Zona de memorie accesată (a)

Operandul f:
 reprezintă adresa de 8 biţi a unui registru din memorie

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe octet:

Au 3 operanzi:
 Registrul (f)
 Destinaţia rezultatului (d)
 Zona de memorie accesată (a)

Operandul d:
 1 bit
 indică destinaţia rezultatului operaţiei realizate de instrucţiune
 d = 0 rezultatul  WREG
 d = 1 rezultatul  f

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe octet:

Au 3 operanzi:
 Registrul (f)
 Destinaţia rezultatului (d)
 Zona de memorie accesată (a)

Operandul a:
 1 bit
 indică modul de acces la registrul f
 a = 0 registrul f se găseşte în Access Bank
 a = 1 registrul f se găseşte într-un Bank specificat prin BSR

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe octet:

Au 3 operanzi:
 Registrul (f)
 Destinaţia rezultatului (d)
 Zona de memorie accesată (a)
15 10 9 8 7 0

Formatul: Cod operaţie d a f (adresa registrului)

Utilizare: cod_operatie f, d, a
cod_operatie f, a

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe octet:

Au 3 operanzi:
 Registrul (f)
 Destinaţia rezultatului (d)
 Zona de memorie accesată (a)

Exemplu: ADDWF REG1, W, BANKED


CLRF 0x01, ACCESS

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe octet:

Au 3 operanzi:
 Registrul (f)
 Destinaţia rezultatului (d)
 Zona de memorie accesată (a)
15 12 11 0

Excepţia: Cod operaţie fs (adresa registrului sursă)


15 12 11 0

1 1 1 1 fd (adresa registrului destinaţie)

Utilizare: MOVFF fs,fd

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe bit:

Au 3 operanzi:
 Registrul (f)
 Bitul din registru (b)
 Zona de memorie accesată (a)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe bit:

Au 3 operanzi:
 Registrul (f)
 Bitul din registru (b)
 Zona de memorie accesată (a)

Operandul f:
 reprezintă adresa de 8 biţi a unui registru din memorie

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe bit:

Au 3 operanzi:
 Registrul (f)
 Bitul din registru (b)
 Zona de memorie accesată (a)

Operandul b:
 3 biţi
 poziţia bitului afectat de instrucţiune în registrul f

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe bit:

Au 3 operanzi:
 Registrul (f)
 Bitul din registru (b)
 Zona de memorie accesată (a)

Operandul a:
 1 bit
 indică modul de acces la registrul f
 a = 0 registrul f se găseşte în Access Bank
 a = 1 registrul f se găseşte într-un Bank specificat prin BSR

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni pe bit:

Au 3 operanzi:
 Registrul (f)
 Bitul din registru (b)
 Zona de memorie accesată (a)
15 12 11 9 8 7 0

Formatul: Cod operaţie b (poziţie bit) a f (adresa registrului)

Utilizare: cod_operatie f, b, a

Exemplu: BSF REG, 4, ACCESS

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni cu constante (literali):

Au un operand:
 valoarea constantei (k)

15 8 7 0

Formatul: Cod operaţie k (constantă)

Utilizare: cod_operatie k

Exemplu: MOVLW d’23’

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni de control:

Pot utiliza următorii operanzi:


 O adresă de salt din memoria program (n)
 Utilizarea stivei rapide (s)
 fără operand

Formatul instrucţiunii GOTO:


15 8 7 0

Cod operaţie n<7:0> (adresă din memoria program)


15 12 11 0

1 1 1 1 n<19:8> (adresă din memoria program)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni de control:

Pot utiliza următorii operanzi:


 O adresă de salt din memoria program (n)
 Utilizarea stivei rapide (s)
 fără operand

Utilizare: cod_operatie n
cod_operatie n,{s}
cod_operatie s
cod_operatie

Este interzisă copierea și distribuirea neautorizată a acestui material.


Formatul instrucţiunilor
Instrucţiuni de control:

Pot utiliza următorii operanzi:


 O adresă de salt din memoria program (n)
 Utilizarea stivei rapide (s)
 fără operand

Exemplu: GOTO main_loop


CALL rutina
RETURN FAST
NOP

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

2.1 FORMATUL INSTRUCŢIUNILOR

2.2 CLASIFICAREA INSTRUCŢIUNILOR

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni matematice pe octet:

Exemplu: ADDWF f, d, a

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni matematice pe octet:

Exemplu: ADDWF f, d, a

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni matematice pe octet:

Instrucţiuni Descriere
ADDWF f,d,a Adună WREG cu f
ADDWFC f,d,a Adună WREG cu f şi cu bitul de transport
SUBWF f,d,a Scade WREG din f
SUBWFB f,d,a Scade f din WREG cu bitul de împrunut
SUBFWB f,d,a Scade WREG din f cu bitul de împrumut
INCF f,d,a Incrementează f
DECF f,d,a Decrementează f
MULWF f,a Înmulţeşte f cu WREG
NEGF f,a Negare f

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni logice pe octet:

Exemplu: RLCF f, d, a

RLCF REG, W, 0

Înaintea instrucţiunii: După instrucţiune:


REG = 11100110 REG = 11100110
C =0 WREG = 11001100
C =1

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni logice pe octet:

Exemplu: RLNCF f, d, a

RLNCF REG, W, 0

Înaintea instrucţiunii: După instrucţiune:


REG = 11100110 REG = 11100110
C =0 WREG = 11001101
C =1

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni logice pe octet:
Instrucţiuni Descriere
ANDWF f,d,a ŞI logic între WREG şi f
IORWF f,d,a SAU logic între WREG şi f
XORWF f,d,a SAU-EXCLUSIV între WREG şi f
COMF f,d,a Complement f
CLRF f,a Resetare biţi din registrul f
SETF f,a Setare biţi din registrul f
SWAPF f,d,a Interschimbare semiocteţi din registrul f
RLCF f,d,a Rotire f la stânga cu bit de transport
RLNCF f,d,a Rotire f la stânga fără bit de transport
RRCF f,d,a Rotire f la dreapta cu bit de transport
RRNCF f,d,a Rotire f la dreapta fără bit de transport

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni matematice şi logice cu constante:

Exemplu: ANDLW k

ANDLW 0x0F

Înaintea instrucţiunii: După instrucţiune:


WREG = 11100110 WREG = 00000110

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni matematice şi logice cu constante:

Instrucţiuni Descriere
ADDLW k Adună WREG cu literal
SUBLW k Scade WREG din literal
MULLW k Înmulţeşte WREG cu literal
ANDLW k ŞI logic între WREG şi literal
IORLW k SAU logic între WREG şi literal
XORLW k SAU-EXCLUSIV între WREG şi literal

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni logice pe bit:

Exemplu: BCF f,b,a

BCF REG, 2, 0

Înaintea instrucţiunii: După instrucţiune:


REG = 11100110 REG = 11100010

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni logice pe bit:

Instrucţiuni Descriere
BCF f,b,a Resetează bitul b din registrul f
BSF f,b,a Setează bitul b din registrul f
BTG f,b,a Schimbă starea bitului b din registrul f

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de comparaţie pe bit:

Exemplu: BTFSC f,b,a

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de comparaţie pe bit:

Instrucţiuni Descriere
BTFSC f,b,a Testează bitul b din reg. f, salt dacă este 0
BTFSS f,b,a Testează bitul b din reg. f, salt dacă este 1

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de comparaţie pe octet:

Exemplu: CPFSEQ f,a

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de comparaţie pe octet:

Exemplu: DECFSZ f,d,a

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de comparaţie pe octet:

Exemplu: implementarea unei bucle for:

REG EQU 0x01

MOVLW d’100’
MOVWF REG

Bucla_for
CLRF 0x00, 0
DECFSZ REG, F, 0
GOTO Bucla_for

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de comparaţie pe octet:

Instrucţiuni Descriere
CPFSEQ f,a Compară f cu WREG, salt dacă f=WREG
CPFSGT f,a Compară f cu WREG, salt dacă f>WREG
CPFSLT f,a Compară f cu WREG, salt dacă f<WREG
TSTFSZ f,a Testează f, salt dacă f=0
INCFSZ f,d,a Incrementează f, salt dacă rezultatul = 0
INCFSNZ f,d,a Incrementează f, salt dacă rezultatul ≠ 0
DECFSZ f,d,a Decrementează f, salt dacă rezultatul = 0
DECFSNZ f,d,a Decrementează f, salt dacă rezultatul ≠ 0

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de mutare:

Exemplu: iniţializarea unei locaţii de memorie

MOVLW 0x55 ; 0x55 WREG


MOVWF 0x2A, 0 ; WREG[F02A]

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de mutare:

Instrucţiuni Descriere
MOVWF f,a Mută WREG în f
MOVF f,d,a Mută f
MOVFF fs,fd Mută fs(sursa) în fd(destinaţie)
MOVLW k Mută literal în WREG
MOVLB k Mută literal (4 biţi) în BSR
LFSR f,k Mută literal (12 biţi) în FSR(f)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de control:

Exemplu: Salt necondiţionat (relativ / absolut)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de control:
Instrucţiuni Descriere
BC n Salt dacă bitul de transport (carry) este 1
BN n Salt dacă bitul negativ este 1
BOV n Salt dacă bitul de depăşire (overflow) este 1
BZ n Salt dacă bitul zero este 1
BNC n Salt dacă bitul de transport (carry) este 0
BNN n Salt dacă bitul negativ este 0
BNOV n Salt dacă bitul de depăşire (overflow) este 0
BNZ n Salt dacă bitul zero este 0
BRA n Salt necondiţionat
GOTO n Salt la adresa / etichetă

Este interzisă copierea și distribuirea neautorizată a acestui material.


Clasificarea instrucţiunilor
Instrucţiuni de control:
Instrucţiuni Descriere
PUSH Pune în stivă (Salvează PC în stivă)
POP Scoate din stivă (Reface PC)
CALL n,s Apel de subrutină
RETURN s Revenire din subrutină
RETLW k Revenire din subrutină cu literal în WREG
RETFIE s Revenire din rutina de tratare a întreruperii
NOP Nici o operaţie

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

2.1 FORMATUL INSTRUCŢIUNILOR

2.2 CLASIFICAREA INSTRUCŢIUNILOR

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Concluzii

Exemplu:

să se iniţializeze registrul de la adresa 0x37 cu valoarea 71


să se incrementeze această valoare de 50 de ori
să se seteze bitul 4 al rezultatului
dacă rezultatul obţinut este > 200 să şteargă conţinutul registrului
de la adresa 0x37
dacă rezultatul obţinut este < 200 să se seteze toţi biţii registrului
de la adresa 0x37

Este interzisă copierea și distribuirea neautorizată a acestui material.


Concluzii

BSF REG, 4, 0
Exemplu: MOVLW D’200’
REG EQU 0X37
CPFSGT REG, 0
CONTOR EQU 0X00
GOTO setare
GOTO resetare
MOVLW D’71’
MOVWF REG, 0
setare
SETF REG, 0
MOVLW D’50’
GOTO sfarsit
MOVWF CONTOR, 0
resetare
Bucla_for:
CLRF REG, 0
INCF REG, F, 0
GOTO sfarsit
DECFSZ CONTOR, F, 0
GOTO Bucla_for
sfarsit
END
Este interzisă copierea și distribuirea neautorizată a acestui material.
Concluzii

În acest curs s-au studiat următoarele:


 Modul de reprezentare al instrucţiunilor în memoria program
 Rolul parametrilor instrucţiunilor
 Clasificarea instrucţiunilor în funcţie de operaţiile realizate
 Descrierea modului de execuţie al instrucţiunilor
 Exemple

Este interzisă copierea și distribuirea neautorizată a acestui material.


Vă mulţumesc pentru atenţie!

Este interzisă copierea și distribuirea neautorizată a acestui material.


Facultatea de Inginerie și
Tehnologia Informației

Curs 3 – Organizarea memoriei

SISTEME CU MICROPROCESOARE

Șef lucr. dr. ing. Duka Adrian-Vasile

Pentru uz intern
Este interzisă copierea și distribuirea neautorizată a acestui material.
Cuprins

Obiective

3.1 MEMORIA PROGRAM

3.2 MEMORIA DE DATE RAM

3.3 MEMORIA EEPROM

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

3.1 MEMORIA PROGRAM

3.2 MEMORIA DE DATE RAM

3.3 MEMORIA EEPROM

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Obiective

La finalul acestui capitol cursantul trebuie:


 să cunoască modul de organizare a memoriei program şi
a memoriei RAM de date
 să cunoască rolul şi structura numărătorului de program
 să poată realiza accesul atomic la regiştrii PC
 să cunoască rolul şi structura stivei
 să poată accesa manual conţinutul stivei
 să înţeleagă mecanismul de adresare implementat prin
Bank-uri şi prin Access Bank

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

3.1 MEMORIA PROGRAM

3.2 MEMORIA DE DATE RAM

3.3 MEMORIA EEPROM

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura memoriei program

 Capacitatea totală de adresare a memoriei program la familia


PIC18 este de 2MB
 Magistrala de adrese a memoriei program are lăţimea de 21 de biţi
 PIC18F4455 are implementată fizic o memorie program de tip
Flash de 24KB

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura memoriei program

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura memoriei program

Reprezentarea instrucţiunilor în memoria program

Este interzisă copierea și distribuirea neautorizată a acestui material.


Numărătorul de program

 Conţine adresa următoarei instrucţiuni care va fi extrasă din memorie


 Are dimensiunea de 21 biţi împărţiţi în trei regiştri de 8 biţi: PCL, PCH şi PCU.
 Se incrementează de două ori, automat, după fiecare fază de extragere
a instrucţiunii din memorie, funcţionând asemenea unui numărător binar uzual

Este interzisă copierea și distribuirea neautorizată a acestui material.


Numărătorul de program

 Scrierea unei valori în registrul PCL (ex. MOVWF PCL) transferă simultan şi
conţinutul regiştrilor tampon PCLATU:PCLATH în regiştrii PCU:PCH.

 Citirea registrului PCL (ex. MOVF PCL,W) se transferă simultan şi conţinutul


regiştrilor PCU:PCH în regiştrii tampon PCLATU:PCLATH.

Este interzisă copierea și distribuirea neautorizată a acestui material.


Numărătorul de program

Exemplu: creşterea valorii PC cu 24 (PC+24) realizându-se astfel un salt peste


următoarele 12 instrucţiuni (24 octeţi) ale programului fără a se utiliza
instrucţiuni speciale de control al execuţiei.

MOVF PCL,W
MOVWF TEMP
MOVLW d’24’
ADDWF TEMP,F Ce face acest cod ?
MOVLW 0
ADDWFC PCLATH,F
MOVLW 0
ADDWFC PCLATU,F
MOVF TEMP,W
MOVWF PCL

Este interzisă copierea și distribuirea neautorizată a acestui material.


Numărătorul de program

Exemplu: creşterea valorii PC cu 24 (PC+24) realizându-se astfel un salt peste


următoarele 12 instrucţiuni (24 octeţi) ale programului fără a se utiliza
instrucţiuni speciale de control al execuţiei.

MOVF PCL,W ; se salvează PCL în registrul TEMP


MOVWF TEMP
MOVLW d’24’ ; se mută constanta 24 în WREG
ADDWF TEMP,F ; se adună la valoarea din PCL
MOVLW 0 ; se pune valoarea 0 în WREG
ADDWFC PCLATH,F ; se adună bitul de transport la PCLATH
MOVLW 0 ; se pune valoarea 0 în WREG
ADDWFC PCLATU,F ; se adună bitul de transport la PCLATU
MOVF TEMP,W ; se înscrie noua valoare în PCL pentru a
MOVWF PCL ; actualiza si restul registrilor PC

Este interzisă copierea și distribuirea neautorizată a acestui material.


Stiva adreselor de revenire

De unde ştie procesorul unde să se întoarcă


cu execuţia la revenirea din subrutină ?

Apelul de subrutină

Este interzisă copierea și distribuirea neautorizată a acestui material.


Stiva adreselor de revenire

Stiva adreselor de revenire


LIFO
31 regiştri x 21 biţi
Stochează adresele de revenire din
subrutine / rutine de tratare a întreruperilor
Apelul de subrutină

Este interzisă copierea și distribuirea neautorizată a acestui material.


Stiva adreselor de revenire

Este interzisă copierea și distribuirea neautorizată a acestui material.


Stiva adreselor de revenire

Este interzisă copierea și distribuirea neautorizată a acestui material.


Stiva adreselor de revenire

 Există posibilitatea de a accesa manual conţinutului stivei prin intermediul


STKPTR şi a regiştrilor TOSU:TOSH:TOSL

 Regiştrii TOS vor conţine întotdeauna imaginea locaţiei din stivă spre care
indică STKPTR

Este interzisă copierea și distribuirea neautorizată a acestui material.


Stiva adreselor de revenire

7 0

STKFUL STKUNF - SP4 SP3 SP2 SP1 SP0

Structura registrului STKPTR

STKFUL : Stack Full (pus pe 1 când indicatorul de stivă ia valoarea 31)


STKUNF: Stack Underflow (pus pe 1 când indicatorul de stivă ia valoarea 0)
SP4:0 : indicator de stivă (ia valori de la 0 la 31)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Stiva adreselor de revenire

PUSH / POP
Instrucţiuni de manipulare a indicatorului de stivă fără a produce saltul spre
sau revenirea dintr-o subrutină.

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

3.1 MEMORIA PROGRAM

3.2 MEMORIA DE DATE RAM

3.3 MEMORIA EEPROM

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura memoriei de date RAM

 Capacitatea totală de adresare a memoriei de date la familia


PIC18 este de 4kB
 PIC18F4455 implementează 2kB
 Memoria este organizată pe octet
 Regiştri de uz general
 Regiştri speciali

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura memoriei de date RAM

 magistrala de date are lăţimea de 8 biţi

 4kB = 4096B = 212B  magistrală de adrese cu laţimea de 12 biţi


dar, câmpul alocat adresei în instrucţiuni este de 8 biţi !

Este interzisă copierea și distribuirea neautorizată a acestui material.


Structura memoriei de date RAM

Există 4 soluţii pentru a ocoli acest inconvenient:


 utilizarea Bank-urilor
 utilizarea Access Bank-ului
 utilizarea instrucţiunii MOVFF
 utilizarea adresării indirecte (vezi curs 4)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Utilizarea Bank-urilor

Memoria este împărţită în Bank-uri


16 Bank x 256 locaţii = 2048 B

Este interzisă copierea și distribuirea neautorizată a acestui material.


Utilizarea Bank-urilor

 Nu este necesară specificarea întregii


adrese (de 12 biţi) pentru fiecare operaţie
de scriere/citire a memoriei, ci doar a unei
părţi a acesteia (8 biţi din cei 12).

Este interzisă copierea și distribuirea neautorizată a acestui material.


Utilizarea Bank-urilor

 Formarea adresei complete de 12 biţi presupune:


• utilizarea unui octet care specifică adresa în cadrul bank-ului
• 4 biţi reprezentând numărul bank-ului accesat

 Registrul de selecţie a bank-urilor conţine cei mai semnificativi 4 biţi ai adresei


de 12 biţi (BSR<3:0>), ceilalţi 8 biţi ai adresei fiind specificaţi în cadrul instrucţiunii.

MOVLW 0x02
MOVLB 0x02
MOVWF BSR

Este interzisă copierea și distribuirea neautorizată a acestui material.


Utilizarea Bank-urilor

Formarea adresei în vederea accesării memoriei RAM prin Bank-uri

Este interzisă copierea și distribuirea neautorizată a acestui material.


Utilizarea Bank-urilor

 Exemplu: modificarea valorii registrului de la adresa 0x20 din Bank 2

MOVLB 0x02 ;selectare Bank 2 (BSR = 2)


CLRF 0x20, BANKED ;accesare registrul 0x20 din Bank 2

 Exemplu: până la 16 regiştri pot avea aceeaşi adresă inferioară

MOVLB 0x02 ;selectare Bank 2 (BSR = 2)


CLRF 0x00, BANKED ;accesare registrul 0x00 din Bank 2
MOVLB 0x03 ;selectare Bank 3 (BSR = 3)
INCF 0x00, BANKED ;accesare registrul 0x00 din Bank 3

Este interzisă copierea și distribuirea neautorizată a acestui material.


Utilizarea Access Bank-ului

Access Bank
 Zonă virtuală de memorie
 Mapează primii 96 GPR şi 160 de SFR
 Bitul de acces a din codul instrucţiunilor trebuie resetat (a=0)
 nu mai trebuie schimbat bank-ul

Exemplu: accesul la reg. TRISA din Bank 15 şi la reg. 0x007 din Bank 0

CLRF TRISA, ACCESS


BSF TRISA, 4, ACCESS
INCF 0x07, ACCESS

Este interzisă copierea și distribuirea neautorizată a acestui material.


Utilizarea instrucţiunii MOVFF

MOVFF Fs, Fd
 instrucţiune lungă (32 biţi)
 Fs - adresa de 12 biţi a registrului sursă
 Fd - adresa de 12 biţi a registrului destinaţie
 mută conţinutul registrului sursă în registrul destinaţie
 necesită 2 cicluri instrucţiune pentru execuţie

Exemplu:

MOVFF 0xF81, 0x220

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

3.1 MEMORIA PROGRAM

3.2 MEMORIA DE DATE RAM

3.3 MEMORIA EEPROM

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Memoria EEPROM

 Memorie nevolatilă
 Se utilizează pentru stocarea datelor permanente
 Sunt disponibili 256 octeţi
 Poate fi accesată indirect prin intermediul regiştrilor speciali:
EECON1, EECON2, EEDATA şi EEADR.

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

3.1 MEMORIA PROGRAM

3.2 MEMORIA DE DATE RAM

3.3 MEMORIA EEPROM

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Concluzii

În acest curs s-au studiat următoarele:


 Organizarea memoriei program la microcontrolerul PIC18F4455
 Numărătorul de program, regiştrii asociaţi şi accesul atomic la valoarea
acestuia
 Stiva adreselor de revenire: structura, utilizarea, regiştrii asociaţi,
modificarea manuală a conţinutului acesteia

Este interzisă copierea și distribuirea neautorizată a acestui material.


Concluzii

În acest curs s-au studiat următoarele:


 Organizarea memoriei RAM de date a microcontrolerului PIC18F4455
 Cele 2 moduri de formare a adresei în vederea accesării locaţiilor
din memora RAM (BANKED / ACCESS)
 Utilizarea instrucţiunii MOVFF pentru a accesa întreaga memorie
RAM
 Organizarea memoriei EEPROM
 Diverse exemple

Este interzisă copierea și distribuirea neautorizată a acestui material.


Vă mulţumesc pentru atenţie!

Este interzisă copierea și distribuirea neautorizată a acestui material.


Facultatea de Inginerie și
Tehnologia Informației

Curs 4 – Adresarea memoriei de date

SISTEME CU MICROPROCESOARE

Șef lucr. dr. ing. Duka Adrian-Vasile

Pentru uz intern
Este interzisă copierea și distribuirea neautorizată a acestui material.
Cuprins

Obiective

4.1 VARIABILE ŞI NUME SIMBOLICE

4.2 ADRESAREA DIRECTĂ

4.3 ADRESAREA INDIRECTĂ

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

4.1 VARIABILE ŞI NUME SIMBOLICE

4.2 ADRESAREA DIRECTĂ

4.3 ADRESAREA INDIRECTĂ

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Obiective

La finalul acestui capitol cursantul trebuie:


 să utilizeze corect numele simbolice
 să cunoască diferenţa între adresarea directă şi
adresarea indirectă
 să înţeleagă rolul regiştrilor de adresare şi accesare
conţinut
 să poată implementa tablouri utilizând adresarea indexată

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

4.1 VARIABILE ŞI NUME SIMBOLICE

4.2 ADRESAREA DIRECTĂ

4.3 ADRESAREA INDIRECTĂ

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Variabile şi nume simbolice

C: Variabilă = zonă de memorie care are un nume şi care


îşi poate modifica valoarea pe parcursul
execuţiei programului
Localizarea exactă în memorie şi legarea numelui
simbolic de adresa fizică nu sunt cunoscute

ASM: Variabilă = registru GPR sau SFR


Control total asupra implementării noţiunii de variabilă

Este interzisă copierea și distribuirea neautorizată a acestui material.


Variabile şi nume simbolice

Exemplu: o variabilă aflată în bank-ul 0, la adresa 2,


trebuie iniţializată cu o valoare.

VAR EQU 0x02

MOVLW B’10001010’ MOVLW B’10001010’


MOVWF 0x02 MOVWF VAR

Ataşarea de nume simbolice unor valori se realizează


cu ajutorul directivei EQU

Este interzisă copierea și distribuirea neautorizată a acestui material.


Variabile şi nume simbolice

Exemplu: o variabilă aflată în bank-ul 0, la adresa 2,


trebuie iniţializată cu o valoare.

VAR EQU 0x02

MOVLW B’10001010’ MOVLW B’10001010’


MOVWF 0x02 MOVWF VAR

Daca valoarea numerica 0x02 este utilizată în instrucţiune


pe post de adresă  adresare simbolică

Este interzisă copierea și distribuirea neautorizată a acestui material.


Variabile şi nume simbolice

Exemplu: #include “p18f4455.inc”

VAR1 EQU 0x02 ;variabile


VAR2 EQU 0x03

Nume CONST1 EQU B’10001010’ ;constante


CONST2 EQU D’20’
simbolice
ORG 0x800 ;adresa de început
MOVLW CONST1 ;CONST1->VAR1
MOVWF VAR1
MOVLW CONST2 ;CONST2->VAR2
MOVWF VAR2
INCF VAR1 ;VAR1++
MOVF VAR1, W ;VAR1->WREG
ADDWF VAR2, F ;WREG+VAR2->VAR2
MOVFF VAR2, LATB ;VAR2->LATB
END

Este interzisă copierea și distribuirea neautorizată a acestui material.


Variabile şi nume simbolice

Exemplu:

X EQU 0x02 ;declarare nume simbolic


MOVLW X ;X este constanta cu valoarea 0x02
ADDWF X ;X este adresa 0x02 a unui reg. GPR

 Nume simbolice ↔ valori numerice


 Depinde de instrucţiune cum sunt interpretate aceste valori
 Ele pot fi interpretate ca:
• Variabile
• Constante

Este interzisă copierea și distribuirea neautorizată a acestui material.


Variabile şi nume simbolice

Directiva CBLOCK:

CBLOCK 0x00 ;valoare de start


VAR1 ;VAR1=0
VAR2 ;VAR2=1
VAR3 ;VAR3=2
VAR4 ;VAR4=3
VAR5 ;VAR5=4
ENDC

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

4.1 VARIABILE ŞI NUME SIMBOLICE

4.2 ADRESAREA DIRECTĂ

4.3 ADRESAREA INDIRECTĂ

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea directă

Câmpul alocat adresei în codul instrucţiunii conţine


adresa efectivă a operandului

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea directă

 Câmpul alocat adresei = 8 biţi + bitul a


 Adresarea directă prin Access Bank
 Adresare directă prin Bank-uri

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea directă

Adresarea directă prin Access Bank  a = 0 (a = ACCESS)

ADDWF 0x3A,W,0 001001 0 0 00111010


ADDWF 0x3A,F,0 001001 1 0 00111010

( Adresa 0x3A ) + ( bitul a = 0 )  adresa accesată 0x03A

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea directă

Adresarea directă prin Bank-uri  a = 1 (a = BANKED)

MOVLB 2
ADDWF 0x3A,W,1 001001 0 1 00111010
ADDWF 0x3A,F,1 001001 1 1 00111010

( Adresa 0x3A ) + ( bitul a = 1 ) + ( BSR = 2 ) adresa accesată 0x23A

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea directă

Exemplu: Să se reseteze regiştrii din Bank-ul 0 mapaţi în


AccessBank

STERG_VECTOR:
CLRF H’00’
CLRF H’01’
CLRF H’02’
v.1 CLRF H’03’
CLRF H’04’
CLRF H’05’
CLRF H’06’
.... .....
CLRF H’5E’
CLRF H’5F’

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea directă

Exemplu: Să se reseteze regiştrii din Bank-ul 0 mapaţi în


AccessBank

STERG_VECTOR:
CLRF H’00’ - Lipsa de flexibilitate
CLRF H’01’
- Ştergerea tuturor regiştrilor
CLRF H’02’
v.1 CLRF H’03’
CLRF H’04’
GPR în acest fel ar ocupa
14% din totalul memoriei
program
CLRF H’05’
CLRF H’06’
.... .....
CLRF H’5E’
CLRF H’5F’

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

4.1 VARIABILE ŞI NUME SIMBOLICE

4.2 ADRESAREA DIRECTĂ

4.3 ADRESAREA INDIRECTĂ

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

 Adresare directă: câmpul alocat adresei în codul instrucţiunii conţine


o adresă constantă (adresa este fixă)

 Adresare indirectă: câmpul alocat adresei în codul instrucţiunii conţine


o adresă variabilă (adresa se poate modifica)

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Regiştri de adresare şi accesare conţinut

 perechi de regiştri FSR: FSR0, FSR1, FSR2


 conţin adrese absolute (12 biţi)
7 4 0 7 0

Cei 4 biţi superiori


- - - - octetul inferior al adresei
ai adresei
FSR0H FSR0L

MOVLW 0x00
MOVWF FSR0L sau LFSR FSR0, 0x200
MOVLW 0x02
MOVWF FSR0H

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Regiştri de adresare şi accesare conţinut

 fiecărei perechi FSRn îi corespunde un registru INDFn


 conţin datele de la adresa stocată în FSRn

7 0

Conţinutul adresei stocate in FSR0H:FSR0L


INDF0

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Regiştri de adresare şi accesare conţinut

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Regiştri de adresare şi accesare conţinut

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Exemplu: utilizarea adresării indirecte

LFSR FSR0, 0x200 ;incarcă în FSR0 adresa 0x200

ADDWF INDF0, F ;adună WREG cu F[200h]→F[200h]

INCF INDF0, F ;F[200h]++ → F[200h]

MOVFF INDF0, 0x00 ;F[200h] → F[000h]

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Exemplu: Să se reseteze
regiştrii din Bank-ul 0 mapaţi
în AccessBank

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

LFSR FSR0, 0x00


MOVLW 0x60
v.2 Bucla_for:
CLRF INDF0
INCF FSR0L,F
CPFSEQ FSR0L
GOTO Bucla_for

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Adresarea indexată

INDFn: accesează conţinutul de la adresa stocată în FSRn


POSTDECn: accesează conţinutul de la adresa din FSRn, apoi
decrementează această adresă
POSTINCn: accesează conţinutul de la adresa din FSRn, apoi
incrementează această adresă
PREINCn: incrementează adresa din FSRn, apoi accesează
conţinutul noii adrese
PLUSWn: adună valoarea (-127÷128) din WREG la valoarea din
FSRn, apoi accesează conţinutul de la adresa nou obţinută

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Exemplu: utilizarea regiştrilor de accesare a conţinutului

LFSR FSR0, 0x100 ;initializarea FSR0 cu adresa 0x100

CLRF POSTINC0 ;F[100h]=0, FSR0++ => FSR0 = 0x101

SETF POSTDEC0, F ;F[101h]=0xFF, FSR0-- => FSR0 = 0x100

INCF PREINC0, F ;F[101h] = 0x00 (overflow),


;FSR0++ => FSR0 = 0x101

Este interzisă copierea și distribuirea neautorizată a acestui material.


Adresarea indirectă

Exemplu: Să se reseteze regiştrii din Bank-ul 0 mapaţi în


AccessBank

LFSR FSR0, 0x00


MOVLW 0x60
v.3 Bucla_for:
CLRF POSTINC0
CPFSEQ FSR0L
GOTO Bucla_for

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

4.1 VARIABILE ŞI NUME SIMBOLICE

4.2 ADRESAREA DIRECTĂ

4.3 ADRESAREA INDIRECTĂ

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Concluzii

În acest curs s-au studiat următoarele:


 Utilizarea numelor simbolice
 Adresarea directă prin Bank-uri
 Adresarea directă prin Access Bank
 Adresarea indirectă
 Regiştrii de adresare FSRn
 Regiştrii de accesare conţinut INDFn, POSTDECn, POSTINCn,
PREINCn, PLUSWn
 Adresarea indexată

Este interzisă copierea și distribuirea neautorizată a acestui material.


Vă mulţumesc pentru atenţie!

Este interzisă copierea și distribuirea neautorizată a acestui material.


Facultatea de Inginerie și
Tehnologia Informației

Curs 5 – Structuri de program

SISTEME CU MICROPROCESOARE

Șef lucr. dr. ing. Duka Adrian-Vasile

Pentru uz intern
Este interzisă copierea și distribuirea neautorizată a acestui material.
Cuprins

Obiective

5.1 MACROURI

5.2 SUBRUTINE

5.3 TABLOURI

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

5.1 MACROURI

5.2 SUBRUTINE

5.3 TABLOURI

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Obiective

La finalul acestui capitol cursantul trebuie:


 să înţeleagă diferenţa între macrouri şi subrutine
 să înţeleagă diferitele moduri de implementare a
tablourilor
 să implementeze corect structurile de program prezentate
 să structureze codul programelor realizate

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

5.1 MACROURI

5.2 SUBRUTINE

5.3 TABLOURI

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


MACROURI

Asamblorul permite definirea propriilor secvenţe de instrucţiuni


sub forma unor macro instrucţiuni
 Ulterior aceste macro instrucţiuni pot fi utilizate asemenea
instrucţiunilor native ale microcontrolerului
 Macrourile sunt secvenţe de instrucţiuni care înlocuiesc
un apel al macroului.
 Exemplu:
Bank2 MACRO
MOVLW 2;
MOVWF BSR
ENDM

Este interzisă copierea și distribuirea neautorizată a acestui material.


MACROURI

Sintaxa generală pentru definirea unui macro:

argumente

Etichetă MACRO [ARG1, ARG2, …]


[INSTRUCTIUNE 1]
[INSTRUCTIUNE 2] Corpul macroului
Denumire macro […]
instrucţiune ENDM

Pereche de directive care


delimitează corpul macroului

Este interzisă copierea și distribuirea neautorizată a acestui material.


MACROURI

Exemplu: definiţia macro-instrucţiunii Movlf (Move literal to


file register)
Movlf MACRO Literal, Destinatie
PUSH ;salvare WREG & STATUS
MOVWF TOSL ;in stiva hardware
MOVFF STATUS, TOSH

MOVLW Literal ;Literal->WREG


MOVWF Destinatie ;WREG->Destinatie

MOVF TOSL,W ;refacere WREG & STATUS


MOVFF TOSH, STATUS
POP
ENDM
Este interzisă copierea și distribuirea neautorizată a acestui material.
MACROURI

Exemplu: apelul macro-instrucţiunii Movlf (Move literal to file


register)

Movlf 0x55, 0x20

Iniţializarea registrului de la adresa 0x20 cu valoarea 0x55

Este interzisă copierea și distribuirea neautorizată a acestui material.


MACROURI

Se recomandă:
 Utilizarea directivei local pentru introducerea etichetelor din corpul
macroului
 Numele date macrourilor să fie diferite de numele instrucţiunilor

Fiecare apel al macroului echivalează cu o inserare a setului


de instrucţiuni din corpul său la adresa de apel

O simplă macro instrucţiune poate ascunde un număr de


efecte secundare asupra unor regiştri GPR şi SFR

Este interzisă copierea și distribuirea neautorizată a acestui material.


MACROURI

Exemplu: o sursă frecventă de erori: saltul peste apelul unui macro

DECFSZ CONTOR, F
My_macro
[…]

 saltul se va produce în interiorul macroului

Este interzisă copierea și distribuirea neautorizată a acestui material.


MACROURI

Avantaje:
creşterea clarităţii codului
reducerea dimensiunii codului la scriere
eficienţă ridicată la execuţia macroului

Este interzisă copierea și distribuirea neautorizată a acestui material.


MACROURI

Dezavantaje:
Apariţia de erori subtile de programare
Creşterea dimensiunii codului compilat

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

5.1 MACROURI

5.2 SUBRUTINE

5.3 TABLOURI

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE

Cerinţe:
subrutina trebuie apelată folosind instrucţiunea CALL
punctul de intrare în subrutină (adresa primei instrucţiuni
din subrutină) trebuie marcat printr-o etichetă
această etichetă va fi numele subrutinei
punctul de ieşire din subrutină trebuie să fie o instrucţiune
de revenire din subrutină

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE

Sintaxa generală pentru definirea unui subrutine:

Etichetă:
[INSTRUCTIUNE 1]
[INSTRUCTIUNE 2] Corpul subrutine
Numele subrutinei […]
RETURN sau RETLW sau RETFIE

Diferite variante ale instrucţiunii de


revenire din subrutină

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE

Apelul subrutinei determină următoarele:


1. STKPTR++
2. PC pe stivă
3. Adresa primei instrucţiuni a subrutinei → PC
4. Se execută instrucţiunile din subrutină până la RETURN
5. La execuţia instrucţiunii RETURN se reface PC din stivă
6. STKPTR--
7. Se execută instrucţiunile din program existente după CALL.

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE
Exemplu: utilizarea subrutinelor (recomandare privind
organizarea codului)

GOTO Main ;salt peste definitia subrutinei

Setare_Port: ;definitia subrutinei


MOVLW 0x7F
MOVWF TRISB
RETURN

Main:
[…]
CALL Setare_Port ;apelul subrutinei
[…]

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE

Utilizarea stivei rapide

Întrerupere / Apel de subrutină MOVLW 0x55 ;0x55->WREG


care modifică WREG
MOVWF 0x20 ;WREG->F[20h]

MOVLW 0xFF F[20h] = 0xFF in loc de 0x55

Trebuie salvat contextul !!!


 Există o stivă o temporară în care se pot salva automat
WREG, STATUS şi BSR

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE

Utilizarea stivei rapide: bitul s=1 (s=FAST)

GOTO Main

Rutina:
[…]
RETURN FAST ; restaurare valori salvate
; în stiva rapidă
Main:
[…]
CALL Rutina, FAST ; salvarea registrilor WREG,
[…] ; STATUS, BSR în stiva rapidă

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE
Instrucţiuni de apel / revenire disponibile

Operaţia Format instrucţiune


Apel
de subrutină CALL aaa
rapid CALL aaa, 1
relativ RCALL ±offset
Revenire
din subrutină RETURN
din subrutitnă rapid RETURN 1
cu literal în WREG RETLW k
din întrerupere RETFIE
din întrerupere rapid RETFIE 1

Este interzisă copierea și distribuirea neautorizată a acestui material.


SUBRUTINE

Avantaje:
creşterea clarităţii codului
modularizarea aplicaţiilor
Se poate utiliza aceeaşi secvenţă de cod din puncte
diferite de program folosind salturi, fără includerea
codului la compilare

Dezavantaj:
Creşte timpul de execuţie

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

5.1 MACROURI

5.2 SUBRUTINE

5.3 TABLOURI

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Tablourile pot fi implementate utilizând:


instrucţiuni microprocesor
instrucţiuni dedicate (tabelare)
adresarea indirectă

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni microprocesor


Instrucţiuni de manipulare a PC + instrucţiunea RETLW
 valorile tabloului nu se pot modica
 tabloul este implementat în Memoria program

Principiu:
Modificarea valorii PC pentru a executa instrucţiunea RETLW
corespunzătoare indexului dorit

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni microprocesor

Tabel:
ADDWF WREG,W ;WREG=index+index
MOVFF PCL,TEMP ;PCL→TEMP,PCH→PCLATH,PCU→PCLATU
ADDWF PCL, F ;PCL+2*index→PCL
RETLW d’101’ ;index 0
RETLW d’115’ ;index 1
RETLW d’90’ ;index 2
RETLW d’83’ ;index 3
RETLW d’85’ ;…
RETLW d’99’
RETLW d’150’
RETLW d’149’

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni microprocesor

Tabel:
ADDWF WREG,W
MOVFF PCL,TEMP
ADDWF PCL, F
RETLW d’101’ MOVLW d’3’
RETLW d’115’ CALL Tabel ;WREG=83
RETLW d’90’
RETLW d’83’
RETLW d’85’
RETLW d’99’
RETLW d’150’
RETLW d’149’

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni microprocesor

Tabel:
ADDWF WREG,W
MOVFF PCL,TEMP
ADDWF PCL, F
RETLW d’101’ MOVLW d’4’
RETLW d’115’ CALL Tabel ;WREG=85
RETLW d’90’
RETLW d’83’
RETLW d’85’
RETLW d’99’
RETLW d’150’
RETLW d’149’

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni microprocesor

Tabel:
ADDWF WREG,W
MOVFF PCL,TEMP
ADDWF PCL, F
RETLW d’101’ MOVLW d’5’
RETLW d’115’ CALL Tabel ;WREG=99
RETLW d’90’
RETLW d’83’
RETLW d’85’
RETLW d’99’
RETLW d’150’
RETLW d’149’

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate


 Citire tabelară: TBLRD – citire octet cu octet
 Scriere tabelară: TBLWT – scriere in bloc de min. 32 octeţi
 tabloul este implementat în Memoria program

Principiu:
 TBLPTR – adresa de 21 de biţi accesată
 TABLAT – octetul accesat

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate

Citirea tabelară. Utilizarea instrucţiunii TBLRD*

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate

Operatia Instructiune
Citire tabelară
TBLPTR nemodificat TBLRD*
TBLPTR post incrementat TBLRD*+
TBLPTR post decrementat TBLRD*-
TBLPTR pre incrementat TBLRD+*

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate


; stocarea sirului de valori
Tablou:
db 0x12, 0x13, 0x90, 0x20, 0x18, 0x23, 0x11

; Rutină de initializare a registrilor de adresare


Init_Adresa:
MOVLW low Tablou
MOVWF TBLPTRL
MOVLW high Tablou
MOVWF TBLPTRH
MOVLW upper Tablou
MOVWF TBLPTRU
RETURN

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate


; stocarea sirului de valori
Tablou:
db 0x12, 0x13, 0x90, 0x20, 0x18, 0x23, 0x11

; Rutină de initializare a registrilor de adresare


Init_Adresa:
MOVLW low Tablou
MOVWF TBLPTRL
MOVLW high Tablou
MOVWF TBLPTRH
MOVLW upper Tablou
MOVWF TBLPTRU
RETURN

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate

; Apelul rutinei de initializare


CALL Init_Adresa

; Accesarea elementelor folosind postincrementarea


TBLRD*+
MOVF TABLAT, W

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate


Tablou:
db 0x12, 0x13, 0x90, 0x20, 0x18, 0x23, 0x11
[…]

CALL Init_Adresa ;initializare adresa tabel

MOVLW d’3’ ;Accesul la elementul cu indexul 3


ADDWF TBLPTRL, F
MOVLW d’0’
ADDWFC TBLTRH, F
MOVLW d’0’
ADDWFC TBLTRU, F
TBLRD*
MOVF TABLAT, W ;WREG = 0x20

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate


Tablou:
db 0x12, 0x13, 0x90, 0x20, 0x18, 0x23, 0x11
[…]

CALL Init_Adresa ;initializare adresa tabel

MOVLW d’4’ ;Accesul la elementul cu indexul 4


ADDWF TBLPTRL, F
MOVLW d’0’
ADDWFC TBLTRH, F
MOVLW d’0’
ADDWFC TBLTRU, F
TBLRD*
MOVF TABLAT, W ;WREG = 0x18

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând instrucţiuni dedicate


Tablou:
db 0x12, 0x13, 0x90, 0x20, 0x18, 0x23, 0x11
[…]

CALL Init_Adresa ;initializare adresa tabel

MOVLW d’5’ ;Accesul la elementul cu indexul 5


ADDWF TBLPTRL, F
MOVLW d’0’
ADDWFC TBLTRH, F
MOVLW d’0’
ADDWFC TBLTRU, F
TBLRD*
MOVF TABLAT, W ;WREG = 0x23

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând adresarea indirectă


tabloul este implementat în Memoria RAM de date
elementele tabloului pot fi modificate

Principiu:
 Elementele se accesează folosind regiştrii de adresare (FSRn)
şi accesare conţinut (INDFn, POSTINCn, PREINCn,
POSTDECn, PLUSWn)

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând adresarea indirectă

Stocare_Valori: ; stocarea valorilor


LFSR FSR0, 0x200
MOVLW d’101’
MOVWF POSTINC0
MOVLW d’115’
MOVWF POSTINC0
[…]
MOVLW d’150’
MOVWF POSTINC0
MOVLW d’149’
MOVWF POSTINC0
RETURN

Este interzisă copierea și distribuirea neautorizată a acestui material.


TABLOURI

Implementarea tablourilor utilizând adresarea indirectă

Stocare_Valori:
LFSR FSR0, 0x200
MOVLW d’101’ Return_Valoare:
MOVWF POSTINC0 LFSR FSR1,0x200
MOVLW d’115’ ADDWF FSR1L, F
MOVWF POSTINC0 MOVLW d’0’
[…] ADDWFC FSR1H, F
MOVLW d’150’ MOVF INDF1, W
MOVWF POSTINC0 RETURN
MOVLW d’149’
MOVWF POSTINC0
RETURN

Este interzisă copierea și distribuirea neautorizată a acestui material.


Cuprins

Obiective

5.1 MACROURI

5.2 SUBRUTINE

5.3 TABLOURI

Concluzii

Este interzisă copierea și distribuirea neautorizată a acestui material.


Concluzii

În acest curs s-au studiat următoarele:


 construirea şi utilizarea macrourilor
 construirea şi utilizarea subrutinelor
 salvarea contextului cu ajutorul stivei rapide
 Implementarea tablourilor în memoria program şi citirea elementelor
acestora prin manipularea PC şi utilizarea instrucţiunii RETLW
 Implementarea tablourilor în memoria program şi citirea
elementelor acestora cu ajutorul instrucţiunilor tabelare TBLRD
 Implementarea tablourilor cu ajutorul adresării indirecte

Este interzisă copierea și distribuirea neautorizată a acestui material.


Vă mulţumesc pentru atenţie!

Este interzisă copierea și distribuirea neautorizată a acestui material.

S-ar putea să vă placă și