I modi possibili per accedere ai banchi nei mid-range sono i seguenti:
- BANKSEL utilizzare questa pseudo istruzione di MPASM
- commutare manualmente gli RP con BCF/BSF
- usare l' indirizzamento indiretto
1. - BANKSEL
La differenza tra la pseudo istruzione banksel
e il classico bsf
STATUS, RP0
è che banksel
si adatta al numero di banchi del processore e agisce sugli switch di banco (RP)
in modo tale da poter puntare con sicurezza al banco in cui sta la label
oggetto.
In questo caso, su entrambi gli RP, per cui è equivalente a:
banksel
|
assemblato
|
; Set PORTB come uscita
banksel TRISB
; banco 1
movf 0x00, W
; Set PORTB uscita
movwf TRISB
banksel PORTB ; banco 0
movlw 0x01 ; RB0 = 1
movwf PORTB
|
; Set PORTB come uscita
bsf STATUS, RP0
; banco 1
bcf
STATUS, RP1
; banco 1
movf 0x00, W
; Set PORTB uscita
movwf TRISB
bcf
STATUS, RP0 ; banco 0
bcf
STATUS, RP1
; banco 0
movlw 0x01 ; RB0 = 1
movwf PORTB
|
Certamente se, durante il programma, non si è mai
toccato RP1, che è a 0 per default al reset, non c'è necessità di applicare
un bcf STATUS, RP1
ogni volta che si cambia banco.
Però bisogna essere sicuri di non averlo mai
toccato; e in un programma che utilizza tutti i banchi, tenere presente dove ci
si trova per agire solo ed esclusivamente sullo switch necessario per passare al
banco voluto può non essere così immediato. banksel,
agendo su tutti gli switch, sacrifica qualche istruzione in più, ma evita tante
grane.
Quindi, anche se
banksel
dà origine a due istruzioni, è
auto esplicativa a livello di listato sorgente ed è da preferire, a meno che ci
siano limiti stretti di memoria o di velocità (cosa che capita molto, molto
raramente in listati semplici per vecchi PIC).
Inoltre banksel
ha la comodità di selezionare da se in quale banco andare, a seconda del
registro indicato.
Ad esempio :
punterà al banco 1, mentre
punterà al banco 3.
2. - BSF/BCF
Se sappiamo che lo spostamento dello switch del banco interessa solamente
un bit, si può risparmiare istruzioni ( e quindi ottimizzare l'esecuzione)
toccando solo quel bit con BSF e BCF.
Ad esempio, se in un processore a 4 banchi si oscilla solamente tra Bank 0
e Bank 1, lasciando a 0 dal default il bit RP1, basterà settare RP0 per
entrare in Bank1 e resettarlo per ritornare in Bank 0.
corretto
|
!! da
evitare !!
|
; Set PORTB come uscita
bsf
STATUS, RP0
; banco 1
movf 0x00, W
; Set PORTB
movwf TRISB
bcf STATUS, RP0 ;
banco 0
movlw
b'00000001' ; RB0 = 1
movwf PORTB
|
; Set PORTB come uscita
bsf
03, bsf
03, ; banco 1
movf 0x00, W
; Set PORTB
movwf TRISB
bcf
03,
;
banco 0
movlw b'00000001' ; RB0 = 1
movwf PORTB
|
Come al solito, è da evitare tassativamente una scrittura in cui si faccia
uso di valori assoluti invece che di label. Questa pessima, deprecabile,
grossolana abitudine deriva solamente da una cattivo imprinting che ignora le
regole di una corretta
programmazione. Va quindi evitata assolutamente.
Non crea nessun vantaggio, ne in velocità di assemblaggio, nè tanto meno in
esecuzione del programma e, per contro, da origine a incomprensibilità del
sorgente e a difficoltà a portarlo da un processore all' altro.
Se proprio si vuole evitare di scrivere tutte le volte STATUS, RPx, basta
crearsi delle macro ad hoc, come se ne trova esempio a bizzeffe sul WEB.
; Macro complete di switch dei banchi BANK0 MACRO
BCF STATUS,RP0
BCF STATUS,RP1
BCF STATUS,IRP ; clear indirect adressing bit
ENDM
BANK1 MACRO
BSF STATUS,RP0
BCF STATUS,RP1
BCF STATUS,IRP ; clear indirect adressing bit
ENDM
BANK2 MACRO
BCF STATUS,RP0
BSF STATUS,RP1
BSF STATUS,IRP ; set bit for indirect adressing
ENDM
BANK3 MACRO
BSF STATUS,RP0
BSF STATUS,RP1
BSF STATUS,IRP ; set bit for indirect adressing
ENDM |
Le macro si usano al posto di BCF/BSF.
; Set PORTB come uscita
BANK1
; banco 1
movf 0x00, W
; Set PORTB
movwf TRISB
BANK0
: banco 0
movlw
0x01 ; RB0 = 1
movwf PORTB
|
Nella versione qui sopra, comprendono lo switch di entrambi gli RP e anche
del bit IRP.
Si possono ovviamente semplificare dove RP1 non vada toccato e IRP neppure.
; Macro minimali di switch dei banchi BANK0 MACRO
BCF STATUS,RP0
ENDM
BANK1 MACRO
BSF STATUS,RP0
ENDM |
Il metodo "manuale" (o le macro) e banksel
hanno vantaggi e svantaggi.
Se banksel
permette di non interessarsi di quale banco si vada chiamare per quel dato
registro, per contro non rende chiaro il banco in cui ci si viene a trovare e
richiederebbe un nuovo banksel
a fronte d ogni chiamata di un registro diverso.
Il metodo "manuale" o le macro rendono noto che banco si va a
chiamare, ma richiedono che si conosca in quale banco si trova il registro su
cui si deve operare.
A riguardo della riduzione del numero delle istruzioni, è meglio il secondo
sistema. A riguardo della leggibilità del sorgente è migliore il primo.
3. - Indirizzamento indiretto
I PIC dispongono di un sistema di indirizzamento indiretto che fa
capo ai registri FSR e INDF e al bit IRP.
|
Un registro a 8 bit, denominato FSR, è integrato da un bit
addizionale IRP per formare un indirizzo a 9 bit.
Con 8 bit si copre un' area da 00h a FFh, mentre con 9
bit si va da 00h a 1FFh, che corrisponde all' ampiezza
dell' area di memoria dati in un PIC a quattro banchi.
Quindi, utilizzando l' indirizzamento indiretto è possibile raggiungere
i primi due banchi senza modificare IRP e tutti e quattro toccando
anche IRP.
Questo metodo è molto semplice ed efficace. |
La sintassi dell' indirizzamento indiretto è questa:
movlw nome_variabile
movwf FSR |
dove nome_variabile
è utilizzato per il suo valore literal: movlw
nome_variabile carica in FSR il valore numerico
corrispondente a quanto asegnato a nome_variabile.
Ad esempio:
caricherà in FSR il valore attribuito
a TRISA nel file processor.inc, ad
esempio 85h.
Ora l' indice dell' indirizzamento indiretto punta su 85h; questo è possibile
perchè la sua ampiezza è 8 bit, quindi con un limite di FFh (Banco 0 e Banco
1).
Si potrà allora scrivere:
; banco di default al reset: Bank 0
movlw TRISA ; pointer indiretto
per TRISA
movwf FSR
movlw setupA ; carica valore di setup
movwf INDF ; all' indiretto
movlw outA ; dato per PORTA
mowvf PORTA ;
movlw TRISB ; pointer indiretto a
TRISB
movwf FSR
bcf INDF,0 ; RB0 = output
bsf PORTB,0 ; RB0 = 1 |
Si passa da Bank 0 (default al reset) a Bank 1 senza toccare gli RP.
Questo sistema, molto efficace:
- può essere usato per accedere a qualsiasi SFR o registro di RAM;
- non richiede di conoscere la posizione del registro nei banchi,
se si tratta dei primi due
In PIC con 4 banchi, per accedere agli ultimi due banchi occorre
modificare il bit IRP (solitamente nello STATUS), portandolo a 1.
Questo spiega la ragione della linea di modifica di questo bit nelle macro di
switch dei banchi viste sopra.
Con questo sistema è possibile, nel caso si usino intensivamente anche i
banchi superiori, puntare con gli RP il banco usato e gestire con
FSR gli altri.
buffer2 equ 0x110 ; buffer in banco
2 bsf
STATUS,RP1 ; seleziona banco 2
bcf STATUS,RP0
bcf STATUS,IRP ; per
indiretto su bank 0 e 1
movlw
PORTA ; pointer indiretto su PORTA
movwf FSR
movf INDF,W
; PORTA in W
movwf EEDATA ;
in EEPROM, banco 2
movwf buffer2 ; e in
buffer |
La prima riga predispone gli RP per il Banco 2. Gli RP saranno in questa
configurazione fino a che non verranno modificati; quindi ogni movimento sui
registri sarà diretto a questo banco.
Contemporaneamente, l' indirizzamento indiretto permetterà di accedere ai
primi due banchi.
Avvertenza:
Se si usa estesamente questo metodo, anche durante le routine di
interrupt, FSR deve fare parte dei registri salvati. |
Note
-
Alcuni dei più recenti mid-range hanno un meccanismo diverso per la
selezione dei banchi, che utilizza non RP, ma un registro apposito BSR - Bank
Switch Register.
-
I PIC enhanced impiegano lo stesso sistema, ma tutti gli SFR e parte
della RAM sono accessibili senza alcuna azione su BSR con l' Access RAM.
Questo rende i PIC18F estremamente più comodi da usare e, abolendo la
necessità di modificare i banchi per accedere agli SFR, molto più efficienti
per quando riguarda la stesura del codice e la velocità di esecuzione.
BSR sarà utilizzato solo per accedere a pagine di registri RAM di uso generale
non raggiungibili in Access RAM.
-
Se vi siete stufati di lottare con i banchi, usate i PIC18.
|