Wednesday, March 28, 2012

Indirizzamento indiretto

L'indirizzamento indiretto e' una delle caratteristiche piu' interessanti del PIC 16F84. Grazie a questo sistema e' possibile accedere sia in lettura che in scrittura ad un dato registro GPR in modo indirietto, ovverosia specificandone l'indirizzo sotto forma di dato contenuto in un altro registro.
All'apparenza il meccanismo potrebbe apparire come una complicazione non strettamente necessaria, in realta' e' estremamente utile. Un esempio aiutera' a capirne l'ambito di utilizzo: normalmente per poter accedere in scrittura ad un dato registro occorre specificarne l'indirizzo direttamente nell'istruzione.
Ad esempio, il codice seguente carica il registo 0x0C con il valore 0xA3:

MOVLW 0xA3
MOVWF 0x0C

Il valore 0x0C e' ovviamente specificato nell'istruzione MOVWF. Fin qui niente di male. Ma come si potrebbe fare per caricare tutti i registri GPR con il medesimo valore 0xA3? Con il metodo tradizionale l'unico sistema e' quello di ripetere l'istruzione MOVWF per tutti i registri, in questo modo:

MOVLW 0xA3
MOVWF 0x0C
MOVWF 0x0E
MOVWF 0x0F
...
...
...
MOVWF 0x4F

L'operazione richiede quindi la ripetizione di MOVWF ben 68 volte, con grande spreco di memoria di programma. In effetti non si possono creare cicli per ripetere MOVWF in quanto l'indirizzo del registro corrente deve essere necessariamente codificato nell'istruzione (non e' un dato che si puo' incrementare di uno).
Per risolvere il problema ci viene in contro il sistema dell'indirizzamento indiretto. Grazie ad esso si puo' accedere ad un dato registro GPR tramite due registri di appoggio:

FSR
INDF

FSR si trova all'indirizzo di memoria 0x04 ed e' mappato in entrambi i banchi RAM.
INDF si trova all'indirizzo di memoria 0x00 ed e' mappato in entrambi i banchi RAM.
Per vedere la loro posizione in memoria RAM consultare la sezione "Memoria RAM/FLASH/EEPROM".

Il registro FSR serve per specificare l'indirizzo di memoria del registro che vogliamo accedere; per farlo e' sufficiente scrivere il relativo indirizzo in questo registro. Una volta fatto questo, tutte le eventuali letture e scritture effettuate nel registro INDF saranno svolte come se si stesse effettivamente accedendo al registro in questione e puntato da FSR.

Esempio

Scrivere una subroutine che cancella tutti i registri GPR (il primo registro GPR e' alla locazione 0x0C e l'ultimo alla locazione 0x4F)

FSR EQU 0x04
INDF EQU 0x00
STATUS EQU 0x03

:clearall

MOVLW 0x0C ;inizializzo il puntatore al primo registro GPR
MOVWF FSR ;e lo scrivo nel registro FSR
next:
CLRF INDF ;cancello il contenuto di INDF
INCF FSR ;incremento di uno il puntatore
MOVF FSR,0
SUBLW 0x50
BTFSS STATUS,2 ;se FSR=0x50 vai a RETURN, altrimenti vai a next
GOTO next
RETURN

No comments:

Post a Comment