Lcucinelli Inserito: 22 agosto 2011 Segnala Inserito: 22 agosto 2011 Signori ho iniziato da poco a compilare piccoli progetti con Pic basic pro quindi e' ovio il mio livello di conoscenza in materia, scusate anche la quantita' di info che vi spedisco ma non sono pratico di come funziona un forum .Ho un problema con la gestione delle pause , non riesco a far gestire un ritado alla mia uscita secondo l'esempio A , mentre quello che riesco ad ottenere e' il B:Uscita ritarda di 15sec Esempio A Ing ____-----__-------------------Out ______________________--------Sec ____:___:_:______:_____:____ 0 3 5 15 20 Esempio BIng ____----__-------------------Out ________________--------Sec ____:__:_:_______:_____ 0 3 5 15Il problema e' che la pausa non si resetta se l'ingresso torna a 0 per cui se l'ingresso torna a 1 il conteggio non riparte da 0.Il programma e' scritto in pic basic pro: DEFINE OSC 4SYMBOL IN_A = PORTB.0 SYMBOL OUT = PORTB.2TEMP VAR BITFLAG var BITVALORE VAR WORD on interrupt GOTO INT OPTION_REG=%10000000 'OPTION_REG.7=0 ABILITA I PULL UP TRISB=%11000011 INTCON=%11000000 PIE1=%00000100 PCON.3=1 'OSC INTERNO 4 MHZ CMCON=7 T1CON=%00100100 T2CON=0 CCP1CON=%00001010 '0,5HZ 30KHZ VALORE = 65535 'MODIFICARE DA 65535 A 1 PER VARIARE LA VELOCITà DI BLINKING (DIMINUIRE VALORE PER AUMENTARE VELOCITà BLINKING) CCPR1L=VALORE.LOWBYTE CCPR1H=VALORE.HIGHBYTE INIZIO: out = 1 pause 500 out=0 MAIN: IF IN_a = 1 then IF FLAG = 1 THEN GOTO SALTA out=0 PAUSE 15000 'millisecondi di ritardo sulla porta A FLAG = 1 ELSE flag = 0 endif SALTA: IF IN_a = 1 THEN PIE1.2=1 T1CON.0=1 ELSE PIE1.2=0 T1CON.0=0 OUT=0 ENDIF GOTO MAIN ''''''''''''''''''''''''''''''''''''''''''''''''''DISABLE ' Disable interrupts in handlerINT:PIR1.2=0 OUT = NOT OUT RESUME ' Return to main programENABLE ' Enable interrupts after handlerend
Lcucinelli Inserita: 31 agosto 2011 Autore Segnala Inserita: 31 agosto 2011 Salve a tuttic'e qualche esperto che puo' darmi un indicazione sul mio problema ?Forse non sono stato chiaro sul mio problema .Pic usato 16f628a scritto in pic basic pro.Sto' cecando di realizzare un hardware che dovrebbe con un Ingresso che cambia stato far blinkare un Uscita solo dopo 15 sec . ( on delay )Qualcuno puo' aiutarmi ? Alzo ingresso inizia la pausa di 15000ms dopo tale tempo l'uscita inizia a blinkare , in tali condizioni tutto funziona come dovrebbe . In condizioni diverse del tipo Ingresso alto ( per esempio ) 5 secondi, torna basso per 5 secondi ,torna alto 5 secondi e inizia a blinkare , se si analizza il tempo impiegato dall' uscita per alzarsi da quando si e' alzata per l'ultima volta ingresso, noterete che sono passati solo 5 sec !! Ok L'anomalia sta' che il conteggio inizia dal momento che si alza per la prima volta ingresso e non come dovrebbe essere dopo l'ultima volta alto. Invece tutto funziona correttamente se l'ingresso si rialza dopo che sono trascorsi i 15 secondi dall'ultima volta che l'ingresso si e' alzato Esempio. ingresso alto per 5 secondi Basso per 11 sec, per cui ha gia superato di 1 secondo il tempo da me impostato . Il problema e' che non si resetta il contatore quando l'ingresso torna basso.Questo accade perchè nel momento in cui uso la pausa 15000 il PIC non controlla se lo stato dell'ingresso è cambiato e quindi dopo 15sec ti attiva l'uscita indipendentemente da quante volte è cambiato lo stato dell'ingresso, nel momento in cui si attiva l'ingresso potrebbe anche essere attivo ma il PIC non lo sa.Sicuramente nel mio prog. che qualche cosa che non funzioana come dovrebbe sono disposta anche a modificarlo interamente se serve . Vorrei pero' cercare di capire cosa non funziona e rimodificarlo utilizzando il compilatore pic basic pro . Sono certo di un vostro aiutoCiao e grazie Luca
kappa47 Inserita: 1 settembre 2011 Segnala Inserita: 1 settembre 2011 Non conosco il PIC Basic, ma credo ci sia una incongruenza nel tuo listato.Ho numerato il tuo listato per farmi capire:1) IF IN_a = 1 then 2) IF FLAG = 1 THEN GOTO SALTA3) out=04) PAUSE 15000 'millisecondi di ritardo sulla porta A 5) FLAG = 1 6) ELSE7) flag = 08) endifL'istruzione "else" al punto 6 si riferisce al "if" del punto 2 (non del punto 1) equindi l'istruzione al punto 7 non viene mai eseguita.Credo che tu voglia riferirla al punto 1, quindi devi mettere un "endif" tra ilpunto 5 e il punto 6. Non credo che la modifica risolva il problema.Una bozza del main potrebbe essere:1) ingresso = 1 ?2) se SI vai al punto 5 (aspetto che ingresso vada alto)3) pausa 1 sec.4) vai al punto 15) contatore = 156) pausa 1 sec.7) ingresso = 1 ?8) se NO vai al punto 1 (se tornato basso, riparto)9) decremento contatore10) contatore = 0 ?11) se NO vai al punto 6 (tempo NON scaduto: torno a controllare ingresso)12) output = 113) pausa 5 sec.14) ingresso = 0 ?15) se SI vai al punto 1816) pausa 1 sec.17) vai al punto 1418) output = 019) vai al punto 1Buon lavoro.
Lcucinelli Inserita: 1 settembre 2011 Autore Segnala Inserita: 1 settembre 2011 Per iniziare grazie per aver risposta Kappa47 .Ho capito perfettamente il tuo messaggio, il mio listato sicuramente presenta errori , sono un autodidatta che sta cercando di imparare .Se ho capito bene il punto 5 dovrebbe essere il mio timer cioe 15 sec.Ho un dubbio pero' su questo passaggio da te descritto , ti faccio un esempio :se durante il conteggio da 1 a 15 il mio contatore si ferma per qualche problema tipo a 5 ( ingresso Basso ) e si rialza dopo 3 secondi , il contatore da dove riparte ?Grazie di nuovo per il suggerimento ,seguiro il tuo consiglio.Una bozza del main potrebbe essere:1) ingresso = 1 ?2) se SI vai al punto 5 (aspetto che ingresso vada alto)3) pausa 1 sec.4) vai al punto 15) contatore = 156) pausa 1 sec.7) ingresso = 1 ?8) se NO vai al punto 1 (se tornato basso, riparto)9) decremento contatore10) contatore = 0 ?11) se NO vai al punto 6 (tempo NON scaduto: torno a controllare ingresso)12) output = 113) pausa 5 sec.14) ingresso = 0 ?15) se SI vai al punto 1816) pausa 1 sec.17) vai al punto 1418) output = 019) vai al punto 1
kappa47 Inserita: 2 settembre 2011 Segnala Inserita: 2 settembre 2011 Tra il punto 6 e il punto 11 (compresi) hai un loop.Da questo loop esci per due motivi:primo: il contatore va a zero (quindi sono passati 15 sec.) e entri al punto 12secondo: il tuo ingresso torna basso (test sul punto 7) (ti ricordo che sei entratonel loop con l'ingresso alto) torni all'inizio (punto 8).Come detto al post precedente, questo vuole essere una traccia di partenza.Ha sicuramente dei difetti del tipo debouncing sull'ingresso, campionamento piuttosto basso (1 sec), ecc.Se il tuo ingresso varia tra alto e basso con una frequenza maggiore di 1 sec. il programma non funziona.Puoi ovviare facendo pausa di 0,5 sec. e caricare il contatore con 30.Non preoccuparti degli errori: ti assicuro che ne faccio anch'io.Ciao.
mf2hd Inserita: 2 settembre 2011 Segnala Inserita: 2 settembre 2011 Ciao, a occhio c'è sicuramente un errore sull' istruzione PAUSE che tende a prendere il controllo del flusso sino a che non ha terminato il suo conteggio.Quando usi l' interrupt devi impostare i ritardi PAUSE (millisec) o PAUSEUS (microsec) in questo modo:invece di PAUSE 500trasformala in uno o più cicli FOR..TO..NEXTnel tuo esempio 500=$1F4 perciò un byte non ti basta (max 255=$FF)I VAR BYTET VAR BYTEFOR I=1 TO 5 FOR T=1 TO 100 PAUSE 1 NEXT TNEXT ICosì l' interrupt sul timer viene "intercettato" essendo il PAUSE molto breve, Lo stesso vale per le istruzioni simili DELAYMS e DELAYUS del Proton picbasic.P.S. Non ho controllato se il resto del tuo programma è corretto, così come la confgurazione per i timer (prescaler,ecc.).Ti metto un po' di passaggi e pezzi del codice con interrupt ho usato recentemente su un 16F628, forse ti può essere utile...o forse no Mi serviva un interrupt timer a cadenza di un 1 secondo.Il 16F628 usa 4 clock per istruzione, come suppongo la maggior parte dei suoi fratelli.Con un clock di 4MHz (1/4000000=0.25usec) il timer TMR0 viene incrementato ogni 0.25us*4=1us.Dato che TMR0 e' da un byte, per riazzerarsi ha bisogno di 256 incrementi, perciò ogni "giro" corriponde a 1us*256=256us.Usando il prescaler impostato a 64 (OPTION_REG=$05) l' interrupt scatta ogni 256us*64=16.384ms.Per avere un secondo (circa) si dovranno aspettare 61 interrupt : 61*16.384ms=999.424ms.L' errore, se non ho contato male, porta a circa 2s all' ora di cui, a seconda dell' applicazione, bisogna eventualmente tenerne conto.Se si usa il clock interno è probabile che l' errore sia maggiore di quello citato, perche' e' meno preciso di un quarzo esterno.Con gli ultimi modelli di PIC la % di errore sul clock interno dichiarata e' molto contenuta, anche se personalmente ho riscontrato un po' di problemi con le comunicazioni seriali su pins non dedicati.Percio', se possibile, quarzo o risuonatore...e c'e' un intoppo in meno.Il codice e' con sole istruzioni in picbasic, volendo si possono inserire delle routine in assembler.Per questo tipo di metodo, che pero' richiede anche MPASM e forse la versione PRO del compilatore, vedi gli esempi sul sito del produttore oppure le famose routine di Darrel Taylor (link)).---Programma tipo---(Inserire le dichiarazioni varibili, clock, micro, condizioni iniziali, ecc.)Conta VAR BYTE (variabile per conteggio interrupt)Conta=0 (condizione iniziale per variabile contatore)OPTION_REG=$5 (prescaler = 64)ON INTERRUPT GOTO InterRoutine (l' interrupt salta al propria sub)INTCON=$A0 (abilita l' interrupt TMR0)Main:(qui si mette il programma: attenzione all' uso di PAUSE)GOTO Main(qui si possono mettere eventuali SubRoutine chiamate dal programma: sempre attenzione all' uso di PAUSE)SubRoutine1:...RETURNSubRoutine2:...RETURNecc.DISABLE (qui comincia la routine dell' interrupt)InterRoutine:Conta=Conta+1 (incrementa contatore ad ogni interrupt/prescaler)IF Conta<61 THEN Salta (verifica se raggiunto 1s circa)Conta=0 (azzera la var usata per conteggio di raggiunto 1s circa)(qui si mette la parte di programma che e' strettamente legata all' interrupt)(es. l' incremento di variabili Secondi e Minuti)Secondi=Secondi+1IF Secondi=60 THENSecondi=0Minuti=Minuti+1ENDIF(ecc.)Salta: INTCON.2=0 (riabilita interrupt su TMR0)RESUMEENABLEEND
Lcucinelli Inserita: 3 settembre 2011 Autore Segnala Inserita: 3 settembre 2011 Signori grazie per le info , cerchero di farle fruttare ... sicuramente ci risentiamo per il momento grazie mille
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora