Tips & Tricks - PIC

 

I banchi nei PIC16F


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
,
; 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 :

banksel TRISB

punterà al banco 1, mentre

banksel EECON1

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:

   movlw   TRISA
   movwf   FSR

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

  1. 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.
     
  2. 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.
     
  3. Se vi siete stufati di lottare con i banchi, usate i PIC18.
     

 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 20/10/10.