Tutorials - PIC

 

Il PC nei Baseline: banchi e pagine


Memoria RAM : Banchi

Una situazione simile a quella della memoria programma si mostra sulla memoria RAM, dove non è possibile accedere ad aree maggiori di 1Fh con quanto l' istruzione contiene. 

Ricordiamo che l' area RAM comprende sia la RAM dati (General Purpose RAM), sia i registri SFR che controllano le periferiche e le operazioni del micro.

Se prendiamo PIC10F200, la sua RAM va da 00h a 1Fh e quindi qualsiasi istruzione di gestione ha bit sufficienti per raggiungere qualsiasi posizione.

Da notare che, in questo caso, come per altri chip, è possibile che una certa area di RAM non sia implementata. Qui si tratta dello spazio tra 07h e 0Fh. Leggendo questa area si ottiene 0 e scrivendola il dato va perso.

Questa situazione è dovuta al fatto che i PIC10F204/206, i quali derivano dall'identica matrice costruttiva, hanno un maggior numero di SFR.

Come abbiamo visto considerando la codifica delle istruzioni, 5 bit sono dedicati alla destinazione e permettono di selezionare indirizzi in tutto lo spazio dei 32 bytes.

 

La massima estensione di memoria RAM che viene coperta direttamente dai bit forniti nell' istruzione si chiama "banco".  
Nei Baseline il banco è ampio 1Fh, cioè 32 bytes.
Lo spazio da 00h a 1Fh si chiama banco 0

 

Però, se prendiamo 12F509, la situazione si complica:

Questo chip ha disponibile RAM da 00h a 3Fh, il che vuol dire due banchi da 1Fh:
  • Bank 0 da 00h a 1Fh
  • Bank 1 da  20h a 3Fh

Abbiamo visto come il codice di una istruzione non permetta di raggiungere indirizzi oltre il Bank 0. Come accedere al Bank 1?

Il sistema è del tutto analogo a quello visto per le pagine: si ricorre all' aggiunta di un bit, che per i Baseline, deriva dal registro FSR:

  • FSR<5> = 0 ->  Bank 0   00h-1Fh
  • FSR<5> = 1 ->  Bank 1   20h-3Fh
Per poter raggiungere l' area tra 20h e 3Fh occorrono 5 bit di indirizzamento (2^5=64).

Il bit 5 di FSR viene aggiunto come bit più significativo a quelli contenuti nella codifica.

In questo modo, facendo variare FSR<5> si indirizza uno o l' altro banco.

E' conseguenza evidente che se i banchi fossero in numero maggiore, ad esempio 4, l' intervento di due bit addizionali ne permetterebbe l' indirizzamento completo.
Con tre bit si potranno commutare 8 banchi e così via.

Torniamo un momento ad osservare la diversa struttura dei due banchi: il primo, da 00h a 1Fh contiene tre elementi:

  1. i registri SFR, da 00h a 06h
  2. un' area di RAM dati, da 07h a 0Fh
  3. un' ulteriore area di RAM dati da 10h a 1Fh

Il banco 1 replica da 20h a 2Fh lo stesso contenuto del banco 0. Ovvero, indirizzando 03h o 23h si accede comunque allo STATUS e indirizzando 0Eh o 2Eh si accede alla stessa locazione  (alias) di RAM dati. Questa situazione è implementata per fare si che si possa accedere agli SFR fondamentali sia che si sta operando nel banco 1 che nel banco 0. Così pure per il tratto di RAM in comune (memoria RAM "shared", condivisa).

Invece, per indirizzare il tratto di RAM dati da 30h-3Fh occorrerà portarsi nel banco 1:

 bsf    FSR, 5              ; commuta sul BANCO 1
 movwf  32h                 ; copia W in 32h

 

  Quindi possiamo riassumere il problema della divisione in banchi della memoria RAM nei seguenti due casi:
  1. Se la RAM si estende solo nelle prime 32 locazioni, tutte le istruzioni possono essere eseguite senza problema.
      
  2. Se l' area RAM si estende oltre i 32 bytes, per accedere ai banchi superiori al Bank 0 occorre azionare i bit di switch relativi al banco voluto.

 



Da notare un punto importante:

Una volta effettuata la sequenza:
 
bsf   FSR, 5

il puntatore FSR<5> indicherà il Bank 1, aggiungendo 1 all' indirizzo contenuto nell' istruzione, fino a che non viene cambiato dal programma (o azzerato al reset).
Se occorre accedere a RAM dati o registri in un altro banco, sarà necessario manovrare ancora questo bit.

Ovvero:

bsf   FSR, 5              ; commuta su Bank 1
clrf  3Ah                 ; azzera locazione 3Ah
clrf  0Ah                 ; azzera locazione 0Ah, area comune ai banchi
clrf  23h                 ; non azzera 23h, ma 33h dato che FSR<5> = 1

invece:

bsf   FSR, 5              ; commuta su Bank 1
clrf  3Ah                 ; azzera locazione 3Ah
clrf  0Ah                 ; azzera locazione 0Ah, area comune ai banchi
bcf   FSR,5               ; commuta su Bank 0
clrf  23h                 ; azzera 23h, dato che ora FSR<5> =
0

Il Macro Assembler MPASM dispone di una direttiva specifica, BANKSEL che effettua la selezione del banco in funzione della label indicata. Così:
 

  BANKSEL   target               ; commuta sul banco che contiene target

sostituisce la scrittura di FSR<5> :

  BANKSEL   target               ; commuta sul banco che contiene target
 
movf      target, f            ; test file for 0

ovunque si trovi la destinazione target .



Esistono Baseline in cui la RAM disponibile assume dimensioni maggiori di 64 bytes. 

Ad esempio, 16F57 dispone di RAM da 00h a FFh, che viene divisa in 8 banchi da 32 bytes ciascuno.
Anche qui, la prima parte dei banchi replica in modo identico il contenuto del Bank 0, ovvero registri SFR e una parte di RAM sono condivisi in qualunque banco ci si trovi.
La RAM dati dei vari banchi successivi a Bank 0 viene selezionata con lo stesso sistema visto prima, solamente basato su tre bit (2^3 = 8):

FSR<7:5>

Banco Indirizzi
000 0 00h-1Fh
001 1 20h-3Fh
010 2 40h-5Fh
011 3 60h-7Fh
100 4 80h-9Fh
101 5 A0h-BFh
110 6 C0h-DFh
111 7 E0h-FFh

Se la RAM si estende fino a 7Fh sarà divisa in 4 banchi e sarà necessario ricorrere allo switch di banco effettuato da due bit, 6 e 5 di FSR:

  • FSR<6:5> = 00 ->  Banco 0   00h-1Fh
  • FSR<6:5> = 01 ->  Banco 1   20h-3Fh
  • FSR<6:5> = 10 ->  Banco 2   40h-5Fh
  • FSR<6:5> = 11 ->  Banco 3   60h-6Fh

La direttiva BANKSEL si adegua automaticamente alla gestione di 1, 2 o 3 bit a seconda del processore che viene dichiarato nel sorgente. In questo senso l' uso di BANKSEL consente di rendere più leggera la lettura del sorgente stesso.

  BANKSEL  target                ; commuta sul banco che contiene target

Se target  si trova nel Bank 7, il BANKSEL sostituisce la meno chiara scrittura:

  bsf    FSR,7            ; commuta sul banco che contiene target
 
bsf    FSR,6            
  bsf    FSR,5

La direttiva ha il vantaggio di poter utilizzare label invece di assoluti, cosa fondamentale in una buona programmazione Assembly.


    Il registro FSR è in particolare relazione con l' indirizzamento indiretto
Con questo metodo di indirizzamento è possibile raggiungere qualsiasi file in qualsiasi banco attraverso la coppia di registri FSR-INDF

Banchi e MPASM

In presenza di più banchi appare la ragione degli alias dei registri SFR e dell' area RAM condivisa in tutti i banchi, in quanto il passaggio da un banco all' altro richiede istruzioni aggiuntive, tante più quanto aumenta il numero dei banchi disponibili, e che penalizza l' esecuzione del programma, rallentandola, oltre richiedere una costante attenzione da parte del programmatore nello stendere il sorgente.

Per venire in aiuto in questa direzione, MPASM introduce un warning tutte le volte che, durante la compilazione, incontra nel sorgente un registro non allocato in bank 0. Il prompt del messaggio è questo:

"Message[302] : Register in operand not in bank 0. Ensure that bank bits are correct"

e ricorda al programmatore che l' indirizzo su cui sta lavorando potrebbe richiedere una commutazione del banco.
Il warning è una segnalazione che non blocca la compilazione e che può essere abolita con un comando:

errorlevel -302

In pratica si sconsiglia vivamente di inserire questa linea di comando, principalmente ai neofiti: in questo caso è una vera assurdità, in quanto la segnalazione è indispensabile per evitare e  correggere errori di allocazione dei banchi. Anche per un esperto, la segnalazione è utile per evitare distrazioni. Potrà essere inserita solamente nella versione finale del sorgente, debuggato e funzionante, per alleggerire il file di lista .lst.


Esiste una varietà di casi in cui i registri SFR non sono esattamente replicati nei vari banchi.

Per il PIC12F519 ci sono 2 banchi, il cui contenuto non è però identico:

L' area di RAM tra 27h e 2Fh è un alias della RAM tra 07h e 0Fh, per cui, indirizzando, ad esempio:
- 0Ah o 2Ah si accederà comunque alla stessa cella di RAM.

L' area di RAM tra 10h e 1Fh appartiene al banco 0 e quella tra 30h e 3Fh al banco 1, per cui l' acceso sarà dipendente dallo stato di FSR<5>.

Il problema sorge per gli SFR: nel Banco1 sono solo parzialmente copie di quelli del Banco 0, in quanto qui appaiono i tre registri EExxx necessari alla gestione della Flash dati: per accedere ai registri EEDATA, EEADR, EECON occorrerà prima agire sul bit 5 di FSR.

Quindi, indirizzando, ad esempio:
- 03h o 23h si accederà comunque allo STATUS

Indirizzando invece  05h si accederà a OSCCAL, ma per indirizzare EEDATA (25h) occorrerà passare nel Bank 1.

Le stesse considerazioni sono valide se il numero di banchi è maggiore e i registri sono disposti diversamente sui banchi.


Al reset (POR) il o i bit del registro FSRx che comandano i banchi sono posti per default a 0, quindi si accede direttamente al Bank 0.

 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 06/05/13.