Lettura della FLASH
Con i meccanismi ora visti, possiamo leggere il contenuto
della memoria Flash in modo molto semplice ed efficiente.
ATTENZIONE:
La lettura del contenuto della memoria programma (Flash) non deve
essere confuso con lo svolgersi del programma stesso.
Nello svolgimento del programma, il meccanismo del Program Counter
manda in esecuzione alla decodifica delle istruzioni i codici
contenuti nelle celle della memoria programma.
Con "lettura della memoria programma", invece, intendiamo
indicare l' operazione di leggere, sotto controllo del programma
stesso, il contenuto delle celle della memoria Flash.
Questa operazione è fondamentale per l' impiego delle tabelle (lookup
tables) scritte in memoria programma.
le tabelle NON sono sequenze di codici di istruzione, ma dati che
servono a particolari operazioni logiche o matematiche del programma
(conversioni, approssimazioni, funzioni matematiche, ecc.).
|
Con questo stiamo effettuando una operazione analoga a
quanto viene fatto nei mid-range con le tabelle retlw, ma in un modo molto
più semplice e diretto.
Se il meccanismo del Program Counter si muove a passi di 2
bytes, l' istruzione di Table Read (TBLRD) accede ad un bytes alla volta,
copiandolo nel registro TABLAT, che è uno degli SFR in RAM.
Il bit 0 di TBLPTR determina se viene letto un byte dispari o pari.
Si ottiene quindi uno scambio tra Flash e RAM: il contenuto
delle tabelle può essere letto e passato al processore per l' elaborazione.
L' operazione di lettura non richiede alcun meccanismo
particolare e non necessità di tempi di attesa.
Le operazioni da eseguire sono le seguenti:
-
inizializzare il puntatore TBLPTR sulla locazione voluta
-
effettuare una operazione di lettura
-
recuperare il byte letto nel registro TABLAT
Ad esempio:
movlw UPPER
(indirizzo) ; carica puntato con bit 16:21
dell' indirizzo
movwf TBLPTRU
movlw HIGH (indirizzo)
; carica puntatore con bit 8:15
movwf TBLPTRH
movlw LOW
(indirizzo) ; carica puntatore con
bit 0:7
movwf TBLPTRL |
e, se l' area d memoria è inferire a 64 k basterà:
movlw HIGH
(indirizzo) ; carica puntatore con bit
8:15
movwf TBLPTRH
movlw LOW
(indirizzo) ; carica puntatore con
bit 0:7
movwf TBLPTRL
|
ignorando il TBLPTRU.
A questo punto basterà la sola istruzione :
TBLRD*
; legge il contenuto di (indirizzo)
|
per spostare il contenuto di (indirizzo)
nel TABLAT, da cui si potrà leggere o
maneggiare come necessario:
movf
TABLAT, W ; carica dato in WREG |
Nel caso in cui debba leggere una sequenza di dati, ci
vengono in aiuto le altre istruzioni TBLRD*+, TBLRD*- e TBLRD+*.
Ad esempio, vogliamo leggere 16 bytes da una tabella in
memoria FLASH all' indirizzo (tabella) e
trasferirli in RAM a partire dall' indirizzo target:
movlw HIGH
(tabella) ; carica puntatore con bit
8:15
movwf TBLPTRH
movlw LOW
(tabella)
; carica puntatore con bit 0:7
movwf TBLPTRL
movlw
.16
; leggere 16 bytes
movwf cntr
lsfr FSR0, target
loop:
; loop di spostamento
tblrd*+
; lettura dalla FLASH
movff TABLAT, POSTINC0 ; scrittura in RAM
decfsz cntr
; counter -1 = 0 ?
bra loop
; no - loop
; si - fine
|
La stessa cosa nel set di istruzione dei mid-range sarebbe
ben più complessa...
Ovviamente le altre forme dell' istruzione TBLRD saranno
usate per altri tipi di loop, a seconda della necessità.
Da notare che esiste una TBLRD+*, ma non una TBLRD-*.