Sunteți pe pagina 1din 16

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

S-ar putea să vă placă și