Vai al contenuto
PLC Forum


Errori Durante La Programmazione Dei Pic - ...con i relativi rimedi.


bit

Messaggi consigliati

Salve a tutti. Parliamo di programmazione di PIC.

Per una volta vorrei aprire una discussione alla rovescia. Invece di proporre problemi e chiedere soluzioni voglio fare il contrario: raccogliere in questo post tutti gli errori logici (quindi non rilevabili da alcun compilatore) più o meno frequenti che si commettono durante la programmazione di questi micro e che spesso fanno letteralmente impazzire poichè sono difficilmente individuabili.

Suggerirei di mantenere aperta questa discussione, invitando tutti a postare qui gli errori che hanno rilevato con la loro esperienza. Inviterei inoltre a postare SOLO gli errori a cui si è trovata la soluzione, spiegandola in modo chiaro e preciso, in modo che chi legge possa capire subito.

Per mantenere una chiara leggibilità a chi cerca qui una soluzione ai suoi problemi di programmazione, suggerirei di evitare di postare qui richieste di charimenti, o commenti non inerenti strettamente all'argomento trattato. Se nel dubbio non si è sicuri della correttezza della soluzione trovata, o dell'inerenza all'alrgomento, si può sempre aprire un'altra discussione.

Volendo di potrebbe aprire un'altra discussione con i commenti relativi a questa.

Ovviamente questi sono solo suggerimenti, ma credo che con l'impegno di tutti si possa tenere in vita una cosa utile, che permetta di risparmiare tempo prezioso.

Invito anche i moderatori a valutare questa proposta, eventualemente correggendola per renderla più adatta all'utilizzo da parte di tutti gli utenti e adeguandola allo scopo generale del forum.

Vi ringrazio anticipatamente dell'impegno ad aiutare questa discussione.

Comincio io postando tutti gli errori che ho rilevato fin'ora nei miei lavori.

Alcuni di voi potrenno ritenere ovvi certi consigli. Per loro chiedo un po' di pazienza in più e ricordo a tutti che ci sono sul forum tanti principianti che potrebbero facilmente cadere in questi errori.

-Utilizzo errato di registri:

Ogni registro RAM può essere utilizzato più volte, anche per funzioni diverse. Questo permette di risparmiare memoria, ma occorre porre particolare attenzione a non utilizzare contemporaneamente il solito registro per funzioni differenti. Caso abbastanza comune che può capitare in programmi di una certa comlpessità, dove magari coesistono più cicli concatenati e è facile riutilizzare un registro che è già stato utilizzato in una subroutine, in un ritardo, o nel vettore di interrupt.

Un modo molto comune per creare problemi è l'utilizzo di subroutine copiate da programmi diversi. Non è difficile aver utilizzato lo stesso nome per registri differenti anche in programmi diversi.

Caso tipico: avevo usato il nome TEMP1 per un contatore di ritardo in una conversione AD, e lo avevo riutilizzato per contare nel programma principale i cicli eseguiti.

Consiglio: utilizzare nomi di registri il più significativi possibile, in modo da rendere chiaro il suo utilizzo all'interno del programma.

-Puntamento indiretto della RAM. Esso si effettua caricando nell'apposito registro FSR l'indirizzo del registro che si vuole leggere, o scrivere. Il registro puntato è quindi disponibile col nome di INDF.

Questo permette indirizzamenti ciclici della ram, ma se non si ha bene sott'occhio l'organizzazione che si è dato ai registri nel nostro programma, non è difficile andare a sovrascrivere registri già usati per altre funzioni. Porre attenzione all'effettivo indirizzo dei registri e della RAM puntata indirettamente.

-Uso scorretto delle istruzioni RLF e RRF.

Sono istruzioni di shift, la prima shifta verso sinistra un registro, la seconda lo shifta verso destra. Il bit in uscita va in STATUS,C il bit in ingresso è prelevato sempre da STATUS,C. Sebbene l'istruzione si riferisca ad un registro da 8 bit, i bit in movimento sono in realtà 9, perchè va considerato anche il bit STATUS,C, che fa parte del ciclo di rotazione.

Va considerato ciò che vogliamo dall'istruzione RLF e RRF. Molto probabilmente sarà necessario settare o resettare il bit STATUS,C prima di effettuare l'operazione, a meno che non si voglia proprio prelevare il valore di detto bit.

Un esempio: si può utilizzare l'istruzione RRF per effettuare la divisione per due del valore di un registro. Ovviamente il bit CARRY dovrà essere precedentemente resettato, pena l'ottenimento di valori errati come risultato della divisione. Il bit CARRY potrebbe infatti essere rimasto settato a 1 da precedenti istruzioni.

Anche nell'utilizzo di più istruzioni RRF o RLF in successione (ad esempio per effettuare la divisione per 4 o per 8), può rendersi necessario il reset del CARRY prima di ogni istruzione. Valutare bene ciò che si desidera ottenere.

-Attenzione alle istruzioni che contangono la condizione di posizione del risultato, in particolare:

ADDWF, ANDWF, COMF, DECF, DECFSZ, INCF, INCFSZ, IORWF, MOVF, RLF, RRF, SUBWF, SWAPF, XORWF.

Tali istruzioni infatto contemplano la possibilità di porre il risultato dell'operazione stessa nel registro stesso o nel registro accumulatore, semplicemente specificandolo al temine dell'istruzione stessa tramite ,W o ,F.

Ad esempio c'è differenza tra ADDWF REGISTRO,W e ADDWF REGISTRO,F. Entrambe le istruzioni effettuano la somma tra il registro REGISTRO e l'accumulatore W. La prima però pone il risultato nell'accumulatore, la seconda nel registro REGISTRO.

E' facile dimenticarsi di specificare l'indirizzamento del risultato. Ciò non viene segnalato come errore dal compilatore (almeno MPasm non lo segnala), poichè di default tale impostazione è ,F.

Viene solo segnalato nei messaggi del compilatore, che ci avvisa che ha posto la condizione di default. Controllare sempre la correttezza della scrittura di tali istruzioni evitando di omettere la specifica ,W o ,F. Sfruttare i messaggi generati dal compilatore nel file .err (leggibile come un normale file .txt) è un buon metodo.

-Attenzione quando si scrive sulla eeprom dati interna al PIC. E' richiesto un tempo relativamente lungo per la scrittura, durante il quale non è possibile richiedere una seconda scrittura. Testando il bit EECON1,WR prima di effettuare una scrittura possiamo controllare l'effettiva disponibilità della eeprom a ricevere un nuovo dato. Il bit EECON1,WR dovrà essere a 0, ciò significa il temine del ciclo di scrittura precedente. Nel caso trovassimo il bit EECON1,WR a 1, sarà necessario aspettare prima di richiedere una nuova scrittura.

Un semplice sistema è inserire prima della scrittura un ciclo del tipo:

ATT_WR: BTFSC EECON1,WR ;attesa fine scrittura precedente

GOTO ATT_WR

Porre attenzione al banco di memoria in cui si trova il registro EECON1, variabile da PIC a PIC.

Inoltre ricordate che eventuali interrupt devono essere disabilitate durante le istruzione di scrittura in eeprom.

-Salvataggio e ripristino dei registri STATUS e W in interrupt.

Quando si esegue un vettore di interruzione è necessario salvare il valore dei registri STATUS e dell'accumulatore W, per evitare malfunzionamenti del programma principale, che potrebbe trovare modificato il valore di questi registri dall'esecuzione di un interrupt.

Un buon sistema è il seguente:

All'inizio del vettore di interruzione:

MOVWF ACC_W ;salvataggio registro w

MOVF STATUS,W ;carico valore registro status

MOVWF ACC_ST ;salvataggio registro status

BCF STATUS,RP1 ;bank 0

BCF STATUS,RP0 ;bank 0

Alla fine del vettore di interruzione:

MOVF ACC_ST,W ;ricarico registro status

MOVWF STATUS ;ripristino registro status

SWAPF ACC_W,F ;ripristino registro w

SWAPF ACC_W,W ;ripristino registro w

RETFIE

Le istruzioni BCF STATUS,RPX permettono di assicurarci la correttezza del banco di memoria utilizzato, nel caso esistesse la possibilità che il programma principale abbia selezionato un banco diverso da 0.

Inoltre se esiste questa possibilità è necessario che i registri di salvataggio ACC_W e ACC_ST siano definiti in un'area della RAM accessibile in tutti i banchi di memoria (di solito gli ultimi 16 byte rispettano questa condizione, ma non in tutti i PIC). Queste istruzioni permettono di ripristinare il banco di memoria che era selezionato all'arrivo dell'interrupt e di riavere i valori di STATUS e W esattamente com'erano stati lasciati.

-Attenzione al corretto utilizzo dei banchi di memoria. Molti registri si trovano in banchi diversi dal bank0. E' necessario selezionare il banco corretto prima di utilizzare questi registri. Inoltre al termine dell'utilizzo è necessario ripristinare il banco corrente del programma, di solito il bank0.

Il compilatore può aiutarci in questo. Infatti nel file .err vengono segnalati tutti i registri non situati nel bank0 che abbiamo utilizzato. Un semplice controllo di questo file potrà permetterci di controllare se nel nostro programma abbiamo inserito la selezione del bank giusto. Attenzione! Il controllo spetta a noi, il complilatore ci suggerisce solo quali registri controllare.

Link al commento
Condividi su altri siti


Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...