Vai al contenuto
PLC Forum


Sorgente Asm


totion

Messaggi consigliati

Ciao a tutti, sono un nuovo iscritto, mi complimento con voi per l'enorme quantità di informazioni e aiuti che avete messo a disposizione di molti.

Vengo al problema: sto cercando di programmare un Pic 16F84 per creare un dimmer. Lo so che non è molto semplice... Ho già fatto il circuito di potenza, rilevamento zero-cross e interfaccia ottica per il triac. Ora mi trovo alle prese con cosa mettere dentro al pic, ho iniziato con alcune prove: gestione TRM0, interrupt e simulazione di una rouine in background. Nello specifico ho pensato di usare l'interrupt come campionatore del un tasto di comando che grazie a una subroutine riesca a discriminare la richiesta utente in base a una tipologia di pressione a intervalli del bottone. Il problema e che non riesco a capire perchè mi si pianta l'esecuzione, in pratica non riesco ad uscire dalla gestione dell'interrupt per tornare alla normale esecuzione della routine principale. A chi ha voglia di dedicarmi un po' di tempo posso postare il listato completo.

Grazie mille.

Totion

Link al commento
Condividi su altri siti


Premetto che con un PIC non ho mai realizzato un dimmer ne usato gli interrupt (ne faccio a meno fino all'ultimo ;)), il primo dubbio che mi viene in mente e' che non vengano salvati e ripristinati correttamente i registri necessari (tipicamente STATUS e W) all'inizo e alla fine della ISR, cioe' quello che nal datasheet e' chiamato "context saving".

ciao Claudio F

Link al commento
Condividi su altri siti

Grazie della risposta.

Sinceramnete non so di che cosa stai parlando... per gli interrupt ho preso spunto da un esempio della guida di Tanzilli. Ho modificato il suo listato per provare, praticamente cambio la frequenza di lampeggio di un led e funziona, senza badare ai due registri STATUS o W. Il problema c'è nel passo sucessivo quando vado a introdurre richiami a subroutine con degli "if goto"(... btfss PORTB,BUTTON .... goto RichiestaSuRilascio ...). Ho impostato una specie di debug con la segnalazione per mezzo di livelli alti o bassi di alcune linee di uscita del Pic e grazie a questa procedura riesco a tracciare dove si pianta il programma ma senza capirne il motivo. Sicuramente è la mia ignoranza che mi cela il corretto uso di queste procedure...

Non è possibile che vinca lui... ormai è un fatto personale che va oltre la gretta programmazione!

totion

Link al commento
Condividi su altri siti

Sono andato a leggere il datasheet e ho modificato il codice inserendo le parti suggerite, non ho la possibilità di provare se non questa sera... speriamo che sia questo. Devo documentarmi meglio... so che se si cerca di improvisare non si ottengono mai buoni risultati, però è un modo come un'altro per imparare cose nuove :)

Vi farò sapere...

Totion

Link al commento
Condividi su altri siti

Non e' sempre detto che il context saving sia necessario, di solito lo e', ma in casi particolari (o particolarmente semplici come l'esempio di Tanzilli) puo' essere evitato senza veder insorgere effetti collaterali. Per esempio se tutto il software si basa su interrupt e il loop principale del programma di base e' semplicemente un ciclo vuoto infinito (una GOTO che salta a se' stessa) non ha senso parlare di salvataggi. Viceversa se c'e' una sostanziosa elaborazione di base che viene interrotta dagli interrupt, allora si deve fare in modo che il programma base non si accorga nemmeno dell'avvenuta esecuzione dell'interrupt handler (o ISR), alla fine della gestione dell'interrupt almeno i registri W e STATUS devono contenere lo stesso valore che avevano prima, quindi questi vanno salvati in due registri temporanei (primissima operazione da compiere nel gestore dell'interrupt) per essere poi rimessi a posto appena prima della RETFIE. Sul datasheet e' riportato il salvataggio:

MOVWF W_TEMP

SWAPF STATUS,W

MOVWF STATUS_TEMP

e il recupero:

SWAPF STATUS_TEMP,W

MOVWF STATUS

SWAPF W_TEMP,F

SWAPF W_TEMP,W

Naturalmente W_TEMP e STATUS_TEMP sono due registri temporanei che andranno definiti come al solito con una EQU o una RES.

ciao Claudio F

Link al commento
Condividi su altri siti

Ieri sera sono riuscito a trovare il problema...

descrivo brevemente la mia struttura:

...

InizioInterrupt

btfss PORTB,BUTTON

goto RichiestaSuRilascio

FineInterrump

...

;SubRoutine

RichiestaSuRilascio

...

goto FineInterrump

_RichiestaSuRilascio

...

In pratica io all'interno della parte dell'interrupt handler facevo un GOTO a una subroutine "esterna" e da questa una GOTO alla fine dell'interrupt. Modificando il programma con una vera "chiamata" call e conseguente return ho risolto il crash. Purtroppo la mia impostazione era voluta per simulare una sorta di "if else" all'interno dell' ISR mentre ora mi trovo con una serie di if da gestire... Poco male, l'importante è essere riuscito a fare un passo avanti.

per Claudio F:

la dritta che mi hai dato sarà utilissima in seguito, dovrò estendere funzionalità che andranno a modificare tali registri e quindi sarà necessario salvarne il contenuto a seguito di un interrupt.

per dlgcom:

ho leggiucchiato dell'enorme utilità di questo programma ma devo ancora andare a fondo sull'argomento... non mancherò di postare domande inerenti a configurazione e uso.

Vi ringrazio dell'enorme aiuto che mi avete dato, cercherò di tenervi aggiornati sugli sviluppi di tale ambizioso progetto, spero che i miei problemi siano utili a indirizzare altri utenti.

Grazie,

Totion

Modificato: da totion
Link al commento
Condividi su altri siti

lo sviluppo del programma procede a rilento ma procede, complice di questo andazzo mplab che non n evuole sapere di funzionare sul mio PC. Ho installato NT4 service pack6, secondo le indicazioni di microchip dovrebbe essere possibile l'uso su questo SO, ma purtroppo quando cerco eseguire l'IDE non va. Mi appare una popup che riporta: "Project Manager's initialization failed: couldn't acquire the standard component categories manager. (COM may not be correctly installed)". Durante la fase di installazione mi ha dato un problema sul mancato reperimento di un componente Ola... che non riuscia a trovare il kernell32... Mi sono subito preoccupato e di fatti non ne vuole sapere di partire.

Idee in merito?

Grazie,

Totion

Link al commento
Condividi su altri siti

Il problema di mplab è stato risolto alla radice installando in una partizione win98...

Grazie a questo ide ho praticamente scritto e simulato il 60% del software. Una volta

pubblicato sul Pic sono iniziati i problemi... molti risolti dal non corretto

dimensionamento temporale dei ritardi ma uno in particolare rimane e non ne capisco il motivo.

Riporto parte del listato dove; inizializzo una "variabile", la valorizzo, ne decreneto il

contenuto di un certo valore e la uso per determinare il ritardo in una soubroutine di prova.

Durante la simulazione, con mplab, procede tutto correttamente tanto che ho inserito dei controlli (if variabile == X)

per capire il contenuto della variabile. Purtroppo in esecuzione reale sembra che il valore di ritardo

e quindi della variabile non cambi.

...

;Registro Contastore attesa richiesta Dimmer

AttesaDimmer RES 1

...

;Imposto l'AttesaDimmer con nessun ritardo

movlw LUCE_MAX

movwf AttesaDimmer

...

;decremento il ritardo del Dimmer

movlw STEP_DIMMER

subwf AttesaDimmer,F

...

Delay

movlw 156

movwf TMR0

movlw AttesaDimmer

movwf Count

;Loop di conteggio

DelayLoop

;TMR0 vale 0 ?

movf TMR0,W

btfss STATUS,Z

goto DelayLoop ;No, aspetta...

movlw 156 ;Si, reimposta TMR0 e controlla se

movwf TMR0 ;e' passato per 125 volte per lo zero

decfsz Count,1

goto DelayLoop

return

;fine Delay

Ci ho sbattuto la testa per diverse ore senza trovare via d'uscita... attendo ansioso

suggerimenti per andare avanti.

Grazie,

Totion

Link al commento
Condividi su altri siti

Non ho capito quale variabile non cambia...

Pero' oi userei il timer0 in un altro modo , come sai , quando passa per lo zero , alza un flag specifico , quindi potresti controllare questo ..

se vuoi io ho un simulatore hardware , ICD2 , posso verificare il prg , direttamente sul pic...

Link al commento
Condividi su altri siti

dlgcom grazie per la disponibilità, ti mando il listato in pm!

Io uso la subroutine di ritardo con il TMR0 per motivi di test, verrà poi sostituita da una routine ad hoc.

La variabile che non cambia, a quanto pare solo nella soubRoutine di ritardo DelayLoop è AttesaDimmer. Entità che ho intenzione di usare per variare il ritardo di innesco del triac. Un impulso di zero-cross scatena un interrupt, quest'ultimo esegue un ritardo variabile(dipendente dal valore di AttesaDimmer) e poi manda in conduzione il triac tramite un fotoaccopiatore...

Avanti con lo sviluppo!

Totion

Link al commento
Condividi su altri siti

Purtroppo ancora niente, sono piantato sul quel cavolo di problema e non ne riesco ad uscire.

Il presunto effetto di ritardo dovuto al diverso valore della variabile non si riesce ad ottenere.

Qualcuno sa come uscirne?

Grazie,

Totion

Link al commento
Condividi su altri siti

  • 3 weeks later...

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...