Tutorials - PIC18

 

Passare da PIC16 a PIC18

 



Gli opcodes

Una prima area di attenzione riguarda gli mnemonici delle nuove istruzioni che hanno funzioni simili, ma più ampie di quelle dei mid-range.

Ad esempio, gli shift possono essere effettuati con o senza carry, per cui la lista :

;shift temporary left 2 times
    clrc
    rlf    TEMP0, f
    rlf    TEMP0, f

potrà essere cambiata in :

;shift temporary left 2 times
    rlncf   TEMP0, f
    rlcf    TEMP0, f

Per chi proviene dall' avere già utilizzato i PIC mid-range, il passaggio ai PIC 18F è, quindi, assai semplice, oltre che fonte di facilitazioni consistenti.

Si possono però creare alcuni punti di ambiguità per quanto riguarda il nuovo set di istruzioni

Un primo punto è la lunghezza delle istruzioni 18F che è, di base, 16 bits. Quindi le istruzioni iniziano sempre in locazioni PARI e un salto ad un indirizzo programma dispari è errato.
Questo è importante per chi ha l' abitudine di utilizzare il simbolo $ per puntare un salto.
Più avanti un paragrafo tratta esplicitamente di questo argomento, anche perchè la questione non è così semplice, esistendo nel set istruzioni anche a 32 bit, il che rende il calcolo "manuale" delle destinazioni abbastanza complesso (basta usare label invece di indirizzi assoluti e il problema è risolto ).

Un altro punto riguarda le istruzioni di rotazione che, nei mid-range, coinvolgono sempre il Carry (gli opcodes rlf e rrf).

Nei 18F, invece, sono disponibili due opcodes per ogni direzione della rotazione, ovvero :

  • rrcf / rlcf  che agiscono come gli equivalenti rlf / rrf 
  • e rrncf / rlncf che, invece, ruotano il registro oggetto SENZA coinvolgere il Carry

Dunque una sostituzione diretta dei mid-range rlf / rrf è, per gli enghanced, rlcf / rrcf ; in ogni caso MPASM, compilando per un PIC18, indica gli eventuali opcodes rlf / rrf come errori.

Inoltre varie delle nuove istruzioni hanno un diverso effetto sullo STATUS.
Ad esempio le istruzioni di rotazione dei 18F possono modificare il bit Z (oltre al nuovo flag N), cosa che, invece, nei mid range non era possibile. Questo è abbastanza secondario, in quanto il programma mid-range non fa certo uso di flag che non ha disponibili, mentre il fatto che un test successivo possa fare leva sul flag Z (che l' istruzione PIC18 ha modificato) può rendere difficoltoso il debug.

Interessante l' istruzione di sottrazione , subwf dei mid-range, che nei 18F ha come equivalente subwfb (che, ricordiamo, hanno come risultato di sottrarre W dal file f !).
Esistono però una subwf, che non tiene conto del borrow , ma anche una sunbfwb, che opera in modo opposto, ovvero sottrae f da W, tenendo conto del borrow.

Per quanto riguarda i branch sui flag dello STATUS, ovvero bc, bnc, bz, bnz, ecc., in effetti si tratta di branch e non di skip , ed è un opcode a tutti gli effetti e non uno pseudo opcode o una macro :

;verify if zero
    addwf  res, f
    bc     
     incf  res, f
next ...    

da origine ad un immediato errore di assemblaggio perchè bc si aspetta un indirizzo a cui effettuare il branch. 
Il sorgente dovrà corretto con:

;verify if zero
    addwf  res, f
    bc     next
    incf   res, f
next ... 

Se poi è dichiarata una macro con lo stesso nome bc, saranno segnalati altri errori.

Analoga situazione nel caso in cui si siano usati gli pseudo opcodes accettati da MPASM, pratica del tutto comune e lecita per i mid-range, ma non più adeguata ai 18F. Ad esempio:

    skpnc
    addlw  0x01
    movwf   TEMP0

non può essere sostituita da :

    bnc
    addlw  0x01
    movwf   TEMP0

in quanto skpnc  è uno "skip", che, se il carry è 0, salta la riga successiva  addlw  0x01 , mentre bnc  è un "branch"  e richiede una label a cui saltare:

        bnc     next
        addlw   0x01
next    movwf   TEMP0

Questo punto è sensibile quando si voglia traslare un sorgente mid-range dove sono stati utilizzati pseudo opcodes accettati da MPASM o macro del genere:

    movf    TEMP1, w
    skpnz    
    incfsz  TEMP1, w
    addwf   ACC1, f

dove è stato usato lo pseudo opcodes (o la macro) skpnz , non più utilizzabile con i 18F, e che deve diventare:

    movf    TEMP1, w
    bnz     $+4
    incfsz  TEMP1, w
    addwf   ACC1, f

oppure:

    movf    TEMP1, w
    btfss   STATUS,Z
    incfsz  TEMP1, w
    addwf   ACC1, f

   

La tabella seguente mette a confronto i vari metodi di branch e che evidenzia come l' uso delle istruzioni specifiche del set 18F permette una riduzione sia del codice che del tempo di esecuzione.:

branch del set PIC18 metodi "tipo PIC16"
Metodo Cicli Metodo Cicli Metodo Cicli
BC  carryset 2 (1) / 1 BTFSC  STATUS, C
GOTO   carryset

3 (2) / 2

BTFSS STATUS, C
GOTO  carry0
2 (3) / 2
BNC carry0 BTFSS STATUS, C
GOTO  carry0
BTFSC STATUS, C
GOTO 
carryset
BN  negative BTFSC STATUS, N
GOTO  negative
BTFSS STATUS, N
GOTO  positive
BNN positive BTFSS STATUS, N
GOTO  positive
BTFSC STATUS, N
GOTO  negative
BOV  ovflw BTFSC STATUS, OV
GOTO  ovflw
BTFSS STATUS, OV
GOTO  novflw
BNOV novflw BTFSS STATUS, OV
GOTO  novflw
BTFSC STATUS, OV
GOTO  ovflw
BZ    zero BTFSC STATUS, Z
GOTO  zero
BTFSS STATUS, Z
GOTO 
notzero
BNZ  notzero BTFSS STATUS, Z
GOTO  notzero
BTFSC STATUS, Z
GOTO  zero

 

NOTE:

  •  branch del set 18F hanno la possibilità di spaziare -127 / +128 istruzioni
     
  • per ampiezze maggiore è necessario ricorrere ai metodi "tipo PIC16" tenendo presente la possibilità di sostituire GOTO, che non ha limitazioni di distanza, con BRA per salti entro 1 k.

 


Azione

La soluzione ideale è impadronirsi del nuovo set di opcodes e comprenderne bene le funzioni.

 


 

 

 

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