- Il problema dell' R-M-W
- R-M-W nei PIC18: cosa succede
- Note
- Una ulteriore considerazione
Il problema dell' R-M-W
Agli utilizzatori dei PIC16 dovrebbe essere noto il problema di di latch
indesiderato dello stato di un GPIO, chiamato R.M.W Problem.
Microchip ha provveduto a risolvere il problema nella
famiglia PIC18, attraverso una variazione della struttura dei registri del
port.
R-M-W: cosa succede nei PIC18
Confrontiamo il port nei PIC enhanced rispetto a quello dei mid range.
Mid-range |
Enhanced |
|
|
Possiamo osservare come la struttura sia identica, ad esclusione di un
gate tri-state che permette di portare sul bus dati il contenuto del Data
Latch (circuito evidenziato in rosso).
Per contro, leggendo PORT (circuito azzurro) si legge non il
contenuto del Data Latch, ma lo stato del pin, attraverso il segnale RD
PORT.
In questo modo, attraverso il comando RD LAT si viene a creare un
ulteriore registro di accesso al por.
Quindi i registri passano da due a tre..
Mid-range |
Enhanced |
- TRIS:
- direzione pin
- PORT:
- in lettura, legge lo stato del pin
- in scrittura, scrive in Data Latch
|
- TRIS:
- direzione pin
- PORT:
- in lettura, legge lo stato del pin
- in scrittura, scrive in Data Latch
- LAT:
- in lettura, legge il Data latch
- in scrittura, scrive in Data Latch
|
Quindi, ad esempio, esisteranno TRISA, PORTA e LATA. E così TRISB,
PORTB, LATB, ecc.
Dagli schemi di principio qui sopra si nota anche che una scrittura su
PORT o su LAT agiscono identicamente sul Data Latch.
Quindi, se scrivere PORT o LAT ha la stessa destinazione (Data Latch
attraverso il segnale WR PORT o WR LAT), parrebbe che non ci siano reali
vantaggi, dato che anche nei PIC18 una modifica in un port passa per una
sequenza R-M-W a 4 fasi, identicamente ai mid-range.
Però è diverso il meccanismo
attraverso cui la fase Q2 preleva il dato da modificare !
Vediamo di chiarire bene la funzione di PORT e di LAT, perchè su
questa differenza si basa l' eliminazione del problema R-M-W.
PORT |
-
Leggendo PORT si legge non il contenuto del Data latch, ma lo stato
del pin, attraverso un diverso latch che memorizza il livello logico del
pin nel momento della lettura
- Scrivendo PORT, la situazione del port viene letta dallo stato
reale dei pin, modificata e poi scritta in Data Latch (e dall' uscita di
questo, passato al buffer del pin).
|
LAT |
- Leggendo LAT si legge non lo stato dei pin, ma il contenuto del
Data Latch.
- Scrivendo LAT, la situazone del port letta non è quella dei pin,
ma quella del contenuto di Data Latch. Questo viene letto, modificato e
riscritto, indipendentemente dallo stato momentaneo del livello elettrico
dei pin.
|
Se confrontiamo una scrittura su PORt e una su LAT, nello
svolgersi delle 4 fasi, la differenza è ancor più chiara:
Mid-range |
Enhanced |
-
Q1: l' istruzione è
decodificata
-
Q2:
viene letto lo stato
attuale del PORT e questo è il valore salvato in un registro provvisorio
-
Q3: viene modifcato il
bit voluto
-
Q4: il registro
provvisorio viene copiato nel Data Latch di in PORTB
|
-
Q1: l' istruzione è
decodificata
-
Q2:
viene letto lo stato
del Data Latch e questo è il valore salvato in un registro provvisorio
Q3: viene modifcato il
bit voluto
Q4: il
registro provvisorio viene copiato nel Data Latch di in LAT
(PORT)
|
Ne risulta che un comando diretto a LAT agisce sempre su un
registro interno, che è separato dai pin attraverso il buffer e il cui
valore NON è influenzato dal carico posto oltre il buffer.
Avendo ben chiaro questo punto, una sequenza di istruzioni del tipo:
;
set IOpin
bsf
PORTB, 0
bsf
PORTB, 1 |
con un carico elevato su RB0 potrebbe dare origine all' errore.
Ma scrivendo:
;
set IOpin
bsf
LATB, 0
bsf
LATB, 1 |
abbiamo la sicurezza che entrambi i pin saranno a livello 1.
|
Immaginiamo che PORTB sia inizialmente tutto a 0 ed abbia un
carico capacitivo abbastanza consistente. Cosa succede ?
-
Q1: l'
istruzione BSF è decodificata
-
Q2: viene
letto lo stato attuale del LATB= 00000000b e questo valore è
salvato in un registro provvisorio
-
Q3: viene
modifcato il bit 0 portandolo a 1; il registro provvisorio
conterrà 00000001b
-
Q4: il
registro provvisorio viene copiato nel
Data Latch di in PORTB
Questa operazione è
completata in un ciclo, che a 40 MHz dura 100 nano secondi.
Il condensatore esterno comincia ad essere caricato alla
massima corrente erogabile dal pin e richiede un certo numero di
microsecondi, ad esempio 1 us.
Intanto il processore non si è certo fermato in attesa della carica
del condensatore, ma sta provvedendo all' esecuzione dell'
istruzione successiva. |
-
Q1: l' istruzione
BSF è decodificata
-
Q2: viene letto lo
stato attuale del LATB= 00000001b e questo valore è salvato in un
registro provvisorio
-
Q3: viene modifcato
il bit 0 portandolo a 1; il registro provvisorio conterrà 00000011b
-
Q4: il registro
provvisorio viene copiato nel Data Latch di in PORTB
Si accenderanno sia il LED 1 che il LED 2.
Il LED 1, in cui il carico capacitivo rallenterà la salita della tensione,
si accenderà comunque, anche se 1 us in ritardo, in quanto il dato di
accessione è stato scritto nel Data Latch.
Il problema R-M-W è eliminato.
Quindi la regola è:
-
Scrivere in LAT
-
Leggere in PORT
|
Scrivere in LAT evita l' R-M-W Problem.
Leggere in PORT
permette di conoscere lo stato effettivo del livello logico del pin.
- Va considerato che se il cambio di stato del bit non è diretto ad un IO,
ma ad un altro registro interno, il problema del glitch non si pone, in
quanto non ha alcun riflesso all' esterno del chip ed è allora preferibile
la prima sequenza di istruzioni, perchè più breve.
- Va compreso che quanto
evidenziato non ha nulla a che fare con il problema della
formazione di glitch a seguito di commutazioni indesiderate dei pin di
uscita e neppure con il problema del debounce per i segnali in ingresso.
|
Una ulteriore considerazione
Quanto detto riguarda il problema della mancata esecuzione di
una istruzione che operi con l' R-M-W. L' eliminazione del
problema con l' uso di LAT non ha niente a che fare con la possibilità
o meno di generare impulsi. Ad esempio, se con le istruzioni:
;
pulse IOpin
bsf
LATB, 0
bcf
LATB, 0 |
si intende generare un impulso di 1 ciclo di durata, questo sarà
possibile solo se il carico sul pin è quello indicato da Microchip.
Se ci troviamo con un carico capacitivo elevato su RB0, sarà probabile che
la tensione non riesca a salire fino a livello logico 1 prima di essere
riportata a 0 dalla seconda istruzione.
|
Se il rate dell' impulso è sproporzionato rispetto al tempo
di carica del condensatore, si finisce per non raggiungere il livello
1 e non riuscire a riportarsi al livello 0 perchè il condensatore
deve anche scaricarsi e deve fare questo sempre attraverso il
buffer interno del pin.
Così, invece dell' atteso segnale in uscita B (rosso), si otterrà la
curva A (in blu). |
Questo non ha nulla a che vedere con il problema R-M-W, ma
semplicemente con l' impossibilità di comandare ad alta velocità un carico
superiore alle possibilità del buffer del pin.
Sarà necessario aggiungere esternamente un buffer in grado di soddisfare le
richieste del carico e della frequenza di commutazione.
Ad esempio, per pilotare gate di MOSFET, sopratutto se non
logic-level, è necessario interporre obbligatoriamente un gate driver, pena
un surriscaldamento del transistor, che non riesce ad arrivare alla piena
conduzione e lavora con fronti di salita e discesa inadatti, oltre all'
impossibilità di superare limiti di frequenza molto bassi.
Alcuni esempi di gate driver:
|
|
|
Buffer a transistor
complementari |
Buffer low side Semtech |
Buffer low side
Linear con protezione da sovracorrente |
Un gran numero di costruttori di semiconduttori, compresa la
stessa Microchip realizza gate driver integrati, high e low side, singoli e
multipli.
|