Il caso del PIC renitente alla ri-programmazione
|
Non si
programma...
La conoscenza dei più complessi meccanismi di funzionamento
dei PIC, anche
perchè la documentazione relativa è scarsa o poco chiara, può non essere indispensabile per utilizzare il
microcontroller, ma la sua mancanza rende difficile uscire da situazioni che siano
al
di fuori della "normalità" prevista.
Vediamo un caso piuttosto comune.
Si trovano spesso poste sui forum questioni come la seguente:
"..
un pic16Fxx e quando setto T1OSCEN si programma
correttamente la prima volta poi non si programma più, ne ho provato più di
uno ma niente da fare, non si cancella neanche."
E' una situazione che si incontra in chi sta
cercando di realizzare circuiti del genere orologio, usando PIC a 18pin e
cristallo a 32768Hz.
A prima vista parrebbe
il solito problema dovuto all' imperizia dell' operatore che sbaglia qualcosa nei
collegamenti o nell' uso del programmatore, ma non è così: si tratta di una situazione più intricata.
Sfortunatamente, chi presenta in rete esempi circuiti che possono
nascondere questo problema pare non lo abbia mai incontrato, dato che non ne
parla assolutamente (cosa che da pensare sulla serietà di quanto si recupera
nel gran mare del WEB...). Il principiante arriva così a trovarsi di fronte
ad un comportamento apparentemente assurdo del chip e per quanto faccia non
riesce a venirne fuori, con non poco stress.
Vediamo come, con una conoscenza più approfondita del chip che si sta usando, non è difficile
avere un orientamento sulla direzione in cui svolgere le ricerche delle
cause del problema e sul semplice modo di risolverlo.
Iniziamo
allora a veder alcune particolarità dei PIC in questione.
Midrange a 18 pin.
I PIC della famiglia Midrange, in package a 18 pin, hanno una particolare
disposizione dei pin:
|
come tutti, dispongono delle funzioni PGD/PGC per la
programmazione, che fanno capo ai RB7 e
RB6.
Va però notato che gli stessi pin condividono anche la funzione di
collegamento ai componeti esterni dell' oscillatore di Timer1 T1OSC1/T1OSC2.
Questo l' elemento chiave del problema.
|
Ricordiamo chel'
oscillatore esterno di TMR1 può essere abilitato o disabilitato da
programma.
Va considerato anche che il chip dispone della possibilità di essere programmato sia in
HVP che LVP:
- Programmazione LVP. In questa modalità, che va imposta dalla linea
di __CONFIG, portando a 1 il bit della Configuration Word, il chip organizza
la sua struttura interna in modo da entrare in stato di programmazione
quando sono presenti la tensione di alimentazione Vdd e il pin RB3/PGM è a
livello alto. Questa modalità è quella di default di un chip quando esce
dalla catena di produzione.
- Programmazione HVP. Questa modalità è quella principale: il chip
entra in modalità programmazione quando la Vpp (>10V circa) viene
applicata al pin RA5/MCLR
Cosa
vuol dire "entra in modalità programmazione"? Vuol dire che i pin PGD/PGC
vengono sottratti ad ogni altra destinazione ed utilizzati dalla comunicazione seriale con il dispositivo di programmazione.
In modalità programmazione, nessuna delle funzioni interne è abilitata, esclusa quella
dedicata alla scrittura della flash, mentre i pin rimanenti sono portati in
condizione di alta impedenza ed esclusi dall' operazione.
Per ultimo, notiamo che in questi chip il pin RA5/MCLR/Vpp può essere sottratto alla
funzione di MCLR e destinato ad essere un ingresso digitale (RA5). Questo è
possibile dato che la funzione di reset al power on (POR) è eseguita
internamente al chip e non richiede elementi esterni. Ma quando viene applicata
la Vpp, anche se MCLR è destinato in configurazione a funzionare come ingresso
digitale, un trigger interno provvede ad escludere questa impostazione e
attivare, invece, il meccanismo di programmazione.
Nei progetti come quello indicato all' inizio, l' hardware prevede l' uso del
clock interno, a cui si aggiunge quello di Timer1; il primo, di relativa
precisone,viene usato per il ciclo istruzioni, non critico. Il secondo, preciso
in relazione all' uso di un quarzo, è utilizzato per l' RTC. Ne deriva che, in fase di configurazione iniziale ci troviamo ad aver impostato almeno
queste opzioni:
__CONFIG
_MCLRE_OFF & _LVP_OFF & _PWRTE_OFF & _INTRC_IO
Vediamo che il chip è configurato per:
- _INTRC_IO
oscillatore interno, RA6 e RA7
disponibili come I/O
_MCLRE_OFF pin MCLR dedicato come ingresso digitale RA5
_LVP_OFF programmazione HVP
_PWRTE_OFF power on timer disabilitato
Queste
impostazioni, ricordiamo, NON sono una parte del programma, ma sono una scelta
tra le possibili configurazioni dell' hardware programmabile del
microcontroller. Non dipendono, quindi, dal clock, ma vengono applicate all' atto
della programmazione e sono fissate e non modificabili fino ad una nuova ri
scrittura.
La
scelta 1 significa che il microcontroller è guidato da un clock interno, che
entra in funzione non appena (o meglio, dopo breve istante) viene applicata la
tensione di alimentazione. Il clock è il segnale che fa avanzare il Program
Counter e sul quale si sincronizzano tutte le operazioni interne. Non appena il
clock è attivo e la linea di reset è rilasciata, il Program Counter inizia a
contare dal vettore di reset e la logica di controllo provvede alla presa delle
istruzioni ed alla loro decodifica e esecuzione.
La
scelta 2 indica che il pin di MCLR esterno è disabilitato e che la sequenza di
POR è gestita esclusivamente dalla logica interna
La
scelta 3 indica che non si desidera la programmazione Low Voltage e che il pin
RB3 è utilizzabile come I/O. Questo vuol dire che il microcontroller andrà in
modalità programmazione quando verrà rilevata una tensione Vpp applicata al
pin RA5. Fino a quel momento il chip è in modalità di funzionamento normale.
La
scelta 4 indica che si è disabilitato il timer di Power On e la relativa attesa
supplementare tra l' arrivo della Vdd e l' avvio del programma.
Molto
importante è ora avere ben chiaro questo: nel momento in cui applico la Vdd,
che ci sia un qualsiasi hardware collegato o meno al microcontroller -dato che,
per la configurazione vista sopra, il chip non dipende
nè da un clock esterno, nè da un reset esterno- dopo il TOST (Oscillation
Start-up Timer Period), param.32, pari a 1024 Tosc, la linea di RESET viene
rilasciata e il programma va in esecuzione, dato che PWRTE è disabilitato e
il Tpwrt è annullato.
A questo punto il programma viene avviato, con il PC che punta all'
istruzione contenuta al vettore di reset. Dopo poche istruzioni, cosa fa il programma?
Attiva l' oscillatore di
Timer1:
MOVLW B'00001001'
MOVWF T1CON
Questo
abilità i pin RB6/7 come T1OSO/T1OSI
per il collegamento con un quarzo + i relativi passivi esterni
|
In seguito all' abilitazione dell' oscillatore esterno di Timer1, a
questi pin vengono collegati dei gate che hanno la funzione di realizzare
questo oscillatore, studiato per un cristallo con frequenza attorno ai 32kHz e a bassa
energia, del genere di quelli utilizzati negli orologi.
Di conseguenza le funzioni di I/O dei due pin sono escluse, dato
che andrebbero a disturbare l' oscillatore.
|
Dunque,
ricapitoliamo:
- viene applicata la Vdd
- dopo TOST il programma inizia la sua esecuzione
- dopo qualche micro secondo, l' esecuzione imposta RB6 e
RB7 come
supporto per l' oscillatore esterno.
Questo,
ripetiamo, anche se al chip c'è collegata solo Vdd e Vss: dato che esiste un clock e la linea di reset è rilasciata,
il programma in FLASH viene eseguito.
Da notare che viene eseguito qualsiasi contenuto della memoria programma, anche se questa è
vuota.
Infatti il contenuto della cella di flash non programmata è normalmente FFh e l' ALU
interpreta questo come un
movlw 0xFF
e che è eseguibile, anche se non origina alcuna azione visibile
all' esterno. Quindi, ad un chip in cui abbiamo configurato il clock interno e niente
dipendenza da MCLR, anche se la memoria programma è "vuota", un
"programma" è comunque in azione; la logica interna eseguirà movlw 0xFF
(o qualunque altra cosa si trovi nella memoria programma) fino a che il Program
Counter è arrivato a fine memoria, dopo di che si avrà un wrap
around alla locazione di reset e così via indefinitamente.
Ora,
partiamo dal chip non ancora programmato. Lo colleghiamo al programmatore e lo
programmiamo. Semplice.
Ma in effetti ci sfugge cosa vuol dire questo.
Vuol dire che il dispositivo di programmazione :
- applica la Vdd/Vss al chip
- quindi applica la Vpp al pin MCLR/Vpp e questo attiva la comunicazione su
PGC/PGD.
-
Il chip viene letto, scritto, cancellato, ecc.
Questo è possibile perchè, anche se il chip all' applicazione della Vdd/Vss ha
iniziato ad eseguire movlw 0xFF della memoria "vuota", l' applicazione
della Vpp stoppa questa esecuzione, bloccando la logica interna ed attivando
invece quella relativa alla comunicazione seriale di programmazione ICSP e alle
operazioni relative (riconoscimento del chip, lettura e scrittura della Flash,
ecc.).
Il chip viene riconosciuto e programmato correttamente.
Una volta rilasciata la Vpp, i pin
PGC/PGD riprendono le funzioni imposte dal
programma caricato e al prossimo reset esso viene avviato e funziona
correttamente.
MA...
...se voglio ri programmare il chip, il dispositivo di programmazione non è
in grado di rilevarlo!
E' successo questo: nelle prime righe di esecuzione del programma si attiva la funzione di oscillatore per Timer1 e,
purtroppo, i pin dell' oscillatore sono gli stessi della comunicazione ICSP.
Vuol dire che il dispositivo di programmazione :
- applica la Vdd/Vss al chip
- il programma si avvia e commuta i pin RB6/RB7 per la funzione di
oscillatore
- quando si applica la Vpp al pin MCLR/Vpp, questo attiva la comunicazione su
PGC/PGD.
- ma, una
volta che sui pin ha preso la prevalenza la funzione dell' oscillatore, questa
impedisce il regolare funzionamento dello scambio di dati seriale.
Il chip funziona correttamente sul circuito (se il nostro programma è
corretto...), ma quando voglio ri programmarlo, succede che il programma ha già attivato l'
oscillatore di Timer1 e la comunicazione col chip non è più possibile.
Il
chip, programmato la prima volta, non lo potrà essere più successivamente. Non
essendo possibile la comunicazione su PGC/PGD il
chip non potrà essere letto o scritto
quindi risulterà inesistente per il software di programmazione.
A
meno che...
A meno che, durante la programmazione, non si utilizzi l'opzione Use Vpp First Program
Entry.
Questo è possibile su molti programmatori, tra cui i Pickit2 e 3
nel software Pickit Programmer.
L' opzione è stata proprio introdotta per risolvere questo genere
di situazioni. Come
agisce? Semplicemente applicando la Vpp prima della Vdd.
La
conseguenza dovrebbe essere evidente: essendo presente la Vpp, il chip passa
immediatamente in stato di programmazione. Non essendo stata eseguita la parte
del programma che abilita l' oscillatore di Timer1, i pin PGC e PGD conservano la loro
funzione intatta.
Il chip è accessibile è può essere riscritto, letto, cancellato.
Ovviamente
questo è possibile se è il programmatore a fornire la Vdd/Vss come nel caso
dei Pickit, mentre non è possibile per gli ICD o il RealCE, che richiedono il
chip alimentato esternamente. Comunque, altri
programmatori, commerciali e non, hanno questa possibilità.
Per approfondire, ricordiamo che, per la programmazione HVP, sono disponibili due metodi:
|
VDD First, effettua l' applicazione di Vdd tenendo PGC
e PGD a livello basso, poi alzando il pin MCLR da VIL a Vppi. Questo
metodo può essere utilizzato con qualsiasi Configuration Word, tranne
quando INTOSC e le opzioni MCLR interni sono selezionati.
Questa è la tecnica di default, utile quando VDD è già
applicato, perché non è necessario scollegarla per entrare in
modalità programmazione.
|
|
VPP First agisce
tenendo PGC e PGD a livello basso e aumentando nel contempo la
tensione al pin MCLR da VIL a Vpp, quindi applicando VDD e
avviando poi la programmazione.
Questo metodo può essere utilizzato per cancellare qualsiasi
parola di configurazione con l' oscillatore interno INTOSC e MCLR
disabilitato: VPP First impedisce al dispositivo di eseguire codice
prima che sia attivata la modalità di programmazione. |
Quando il problema non c'è
Essenzialmente
il problema non si pone se:
- non viene configurato il clock interno
- non viene abilitato da programma il clock di Timer1
Se,
infatti, non c'è clock, la logica interna che gestisce il flusso delle
istruzioni non può funzionare e il programma non può avviarsi, mentre la
comunicazione ICSP
per la programmazione, che non dipende da questo clock, è
comunque attivabile.
Il problema non sussiste anche se non si sovrappone la funzione di oscillatore di
Timer1 ai
pin PGD/PGC (pare esista qualche possibilità che, in
condizioni particolari di programma, anche senza l' abilitazione di T1OSC, il
problema si presenti avendo configurato il clock interno e disabilitato MCLR).
Il
problema non si pone anche nel caso in cui da configurazione sia stato abilitato
il metodo LVP: in tal caso basta che il pin RB3 sia mantenuto a livello alto
all' arrivo della Vdd per portare il micro nella modalità di programmazione.
Diverso
è il discorso dei bootloader che caricano sempre in modalità seriale, ma sotto
controllo di un programma (il bootloader, appunto) pre caricato e residente
nella memoria programma del microcontroller.
Riassunto
Il problema della impossibilità di ri programmare il chip si verifica quando il
dispositivo è stato precedentemente programmato in modo tale che:
- Si usa l'oscillatore interno -e-
- Il pin MCLR è disattivata per utilizzare come ingresso digitale invece -e-
- Il codice di programma attivato il Timer1 Oscillator nel registro delle T1CON. Quanto prima questo viene attivato dopo il vettore di reset tanto più
è probabile che il problema si verifichi.
Dunque
questo problema può essere prevenuto:
- evitando una delle tre condizioni di cui sopra,
- o, se necessarie, utilizzando la modalità di programmazione Vpp First
oppure LVP (con perdita della funzione di I/O di RB3)
Il
problema della apparente mancata possibilità di ri programmare il chip riguarda
i Midrange a 18 pin che hanno in condivisone PGC
e PGD con l' oscillatore
di Timer1, quindi:
- PIC16F627A/628A/648A
- PIC16F818/819
- PIC16F87/88
Non ci sono al momento notizie del problema su PIC18F a 18 pin (18F1220/1230/1320/1330) o negli
Enhaced Midrange PIC16F1847/1826/27, anche se hanno la medesima situazione di
condivisione dei pin. Altri chip a 18 pin come PIC16F716 hanno PGD/PGC collegati a pin diversi da
quelli dell' oscillatore di TMR1; altri, sempre a 18 pin, come i Baseline 16F54/57/59 non hanno Timer1.
Per
i chip con numero diverso di pin la condivisone delle funzioni è differente e
quindi il problema non dovrebbe verificarsi.
Caveat
Ovviamente
si deve intendere che durante una programmazione on circuit con una connessione ICSP:
- il quarzo sui pin T1OSI/T1OSO viene rimosso
- alla linea RB5/MCLR non è collegato alcun carico tale da abbattere la Vpp
al di sotto del valore minimo necessario alla scrittura della Flash,
- il valore della Vpp è da considerare al minimo di 10V (max. 13V)
- il dispositivo di programmazione non è una delle troppe porcherie
collegate alla seriale del PC e quindi con segnali, sopratutto Vpp,
inadeguati
Le
operazioni di recupero del chip vanno fatte collegando al programmatore il solo
chip e non attraverso una connessione ICSP
on board a meno di essere ben sicuri
che questa garantisca la correttezza di temporizzazione e livello dei segnali di
programmazione.
Non
rientra in questo problema il caso in cui il programmatore non riesca a
stabilire la connessione con il chip anche se questo non ha le condizioni
indicate nel paragrafo -Riassunto-. Per questo genere di situazioni si dovrà
ricercare la causa in una cattiva connessione tra chip e dispositivo di
programmazione.
Altri
metodi
Un ulteriore modo per aggirare il problema potrebbe essere quello di inserire nel sorgente, tra il vettore di
reset e l' inizio del programma vero e proprio, una routine di attesa di un paio
di secondi, il che darebbe tempo al programmatore di attivare la Vpp prima dell'
istruzione che abilita T1OSC. Si tratta però di un escamotage poco pratico, da
applicare solo se non esiste alcuna altra possibilità.
Per conoscenza, riportiamo anche questa procedura di "hacking" hardware per
forzare l' accesso alla Configurazion Word con un Pickit2:
- Mettere il chip su una breadboard dove è collegato solamente il Pickit2
- Aprire l' applicazione Pickit2 Programmer (2.40 o versione successiva).
- Selezionare "Famiglia Dispositivo> Midrange"
- Impostare la Vdd alla tensione di 3,0 volt
- Selezionare "Family Dispositivo> Midrange" di nuovo; ora
dovrebbe rilevare il chip
- Se non viene rilevato, ridurre la VDD di 0,1 volt e riprovare. Ripetere
l'operazione fino a quando il chip viene rilevato correttamente
- Selezionare il pulsante WRITE per cancellare. Non occorre un .hex
particolare; basta che sia rimosso il programma e la Configuration Word
precedenti
Riporto
questo a puro titolo di informazione in quanto non ho mai avuto l' occasione di
verificare il metodo praticamente..
Documentazione
PIC12F6XX/16F6XX
Memory Programming Specification DS41204H
|