stefano_ Inserito: 10 febbraio 2005 Segnala Share Inserito: 10 febbraio 2005 salve a tutti,il problema questa volta è che devo far suonareun cicalino per un secondo avendo com start un impulso che dura 5ms proveniente dal pic.Ho fatto la seguente prova:dall'uscita del pic vado alla base di un transistor npn (bc337) tramite una r da 10K, collego il collettore a +5v e l'emettitore a massa, fatto ciò ho messo in parallelo al cicalino un condensatore da 4,7 uF.Il problema è che in questa maniera il cicalino suona per circa 4 / 5 secondi, vorrei solamente diminuire la durata sino ad arrivare a 0.5 / 1 secondo al massimo come posso fare ?? Ho sbagliato tutto oppure c'è qualcosa di buono ??Grazie 1000 a tutti Link al commento Condividi su altri siti More sharing options...
bit Inserita: 11 febbraio 2005 Segnala Share Inserita: 11 febbraio 2005 Ci sono 2 modi:-Togli il condensatore e riprogrammi il pic in modo che ti dia un impulso di 1 secondo.-Diminuisci la capacità del condensatore (prova 1 uF)Ciao! Link al commento Condividi su altri siti More sharing options...
FranSys Inserita: 11 febbraio 2005 Segnala Share Inserita: 11 febbraio 2005 Non riesco a capire per quale motivo non gestisci il ritardo direttamente dal programma del PIC! Ciao. Link al commento Condividi su altri siti More sharing options...
stefano_ Inserita: 11 febbraio 2005 Autore Segnala Share Inserita: 11 febbraio 2005 perche il pic lo utilizzo per visualizzare delle cifre su 4 display multiplexati, quindi il loop principale del programma del pic lo utilizzo per variare lo stato delle uscite ogni 5ms quindi il ritardo di cui sopra lo dovrei fare tramite l'interrupt ( magari di overflow del tmr0 ) ma non so proprio da dove cominciare.Il pic lo programmo in basic tramite pic basic ma non ho capito ancora come gestire l'interrupt, per questo ho voluto fare un circuitino esterno che con l'impulso mi fa rimanere attivo il cicalino per 1s circa.Se sapete qualcosa sull'interrupt in pic basic AIUTATEMI !!!comunque grazie 1000 per le vostre risposte male che va utilizzerò il cond + piccolociao e grazie ancora Link al commento Condividi su altri siti More sharing options...
FranSys Inserita: 11 febbraio 2005 Segnala Share Inserita: 11 febbraio 2005 Non finirò mai di ripeterlo: prima di utilizzare linguaggi di programmazione di "alto" livello con i PIC, bisogna comprendere bene l'Assembler. E comuque c'è sempre la possibilità di realizzare le routine potenti e complesse in Basic o in C e le routine che necessariamente devono essere affidabili e snelle in Assembler.Ti riporto il codice per la gestione in Assembler di tmr0 ad interrupt. Si tratta di un lavoro che avevo fatto anni fa su PIC16F876 e funziona benissimo. Non limitarti ad un copia e incolla... il codice è molto commentato e faresti bene a capirlo prima di implementarlo nella tua applicazione. Se il tuo compilatore basic decompila, potresti provare a dargli in pasto il file ASM e verificare se lo interpreta correttamente. Trovi applicazioni simili sui tutorial Microchip.Tieni presente che io uso molto le macro e le subroutine e tendo a definire i MIEI mnemonici, il tutto è molto semplificabile. Ti ho lasciato le macro per i vari valori di prescaler per darti la possibilità di cambiare la base dei tempi del timer. ; ***************************************************************************** ; LIST STATEMENT ; ***************************************************************************** list p=16F876 ; ***************************************************************************** ; REGISTER FILES ASSIGNMENT ; ***************************************************************************** tmr0 equ H'01'; timer 0 status equ H'03'; stato ALU option_reg equ H'81'; controllo opzioni diverse intcon equ H'0B'; controllo interrupt ; ***************************************************************************** ; REGISTER BITS ASSIGNMENT ; ***************************************************************************** c equ H'00'; riporto z equ H'02'; risultato logico/aritmetico t0if equ H'02'; interrupt timer 0 t0ie equ H'05'; abilitazione interrupt timer 0 gie equ H'07'; abilitazione interrupt globali rp0 equ H'05'; bit 0 selezione banco memoria rp1 equ H'06'; bit 1 selezione banco memoria ps0 equ H'00'; bit 0 valore prescaler ps1 equ H'01'; bit 1 valore prescaler ps2 equ H'02'; bit 2 valore prescaler psa equ H'03'; bit assegnazione prescaler t0cs equ H'05'; selezione sorgente clock timer 0 ; ***************************************************************************** ; INTERNAL BIT DEFINITIONS ; ***************************************************************************** #define zero status,z; bit di zero #define carry status,c; bit di carry #define tmr0_int intcon,t0if; interrupt timer 0 #define tmr0_int_en intcon,t0ie; abilit. int. timer 0 #define glb_int_en intcon,gie; abilit. int. globali #define clk10ms tmr1s,0 ; clock 10 ms ; ***************************************************************************** ; CONSTANTS DEFINITION ; ***************************************************************************** #define tmr0_rst_val H'00'; valore reset timer 0 #define tmr0_pst_val D'99'; valore preset timer 0 ; ***************************************************************************** ; VARIABLES ASSIGNMENT ; ***************************************************************************** tmr1s equ H'20'; timer 1 secondo ; ***************************************************************************** ; RESET VECTOR ; ***************************************************************************** org H'00' ; vettore reset goto Init ; inizializzazione programma ; ***************************************************************************** ; INTERRUPT VECTOR ; ***************************************************************************** org H'04' ; vettore di interrupt goto IntT0 ; gestione interrupt ; ***************************************************************************** ; MACROS ; ***************************************************************************** ; ; Bank ; bank0 macro ; inizio macro bcf status,rp0; seleziona banco memoria 0 bcf status,rp1; // endm ; fine macro bank1 macro ; inizio macro bsf status,rp0; seleziona banco memoria 1 bcf status,rp1; // endm ; fine macro bank2 macro ; inizio macro bcf status,rp0; seleziona banco memoria 2 bsf status,rp1; // endm ; fine macro bank3 macro ; inizio macro bsf status,rp0; seleziona banco memoria 3 bsf status,rp1; // endm ; fine macro ; ; Timer 0 ; tmr0_clk_int macro ; inizio macro bank1 ; seleziona banco memoria 1 bcf option_reg,t0cs; abilita clock interno bank0 ; seleziona banco memoria 0 endm ; fine macro tmr0_int_enf macro ; inizio macro movlw 0x00 ; azzeramento bit registro movwf intcon ; // bsf glb_int_en; abilitazione interrupt glob. bsf tmr0_int_en; abilitazione interrupt tmr0 endm ; fine macro tmr0_rst macro ; inizio macro movlw tmr0_rst_val; azzeramento timer 0 movwf tmr0 ; // endm ; fine macro tmr0_pst macro ; inizio macro movlw tmr0_pst_val; impostazione timer 0 movwf tmr0 ; // endm ; fine macro ; ; Prescaler ; prsclr_tmr0 macro ; inizio macro bcf option_reg,psa; abilita prescaler (tmr0) endm ; fine macro prsclr_2 macro ; inizio macro bank1 ; seleziona banco memoria 1 bcf option_reg,ps0; rapporto prescaler 1:2 bcf option_reg,ps1; // bcf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro prsclr_4 macro ; inizio macro bank1 ; seleziona banco memoria 1 bsf option_reg,ps0; rapporto prescaler 1:4 bcf option_reg,ps1; // bcf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro prsclr_8 macro ; inizio macro bank1 ; seleziona banco memoria 1 bcf option_reg,ps0; rapporto prescaler 1:8 bsf option_reg,ps1; // bcf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro prsclr_16 macro ; inizio macro bank1 ; seleziona banco memoria 1 bsf option_reg,ps0; rapporto prescaler 1:16 bsf option_reg,ps1; // bcf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro prsclr_32 macro ; inizio macro bank1 ; seleziona banco memoria 1 bcf option_reg,ps0; rapporto prescaler 1:32 bcf option_reg,ps1; // bsf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro prsclr_64 macro ; inizio macro bank1 ; seleziona banco memoria 1 bsf option_reg,ps0; rapporto prescaler 1:64 bcf option_reg,ps1; // bsf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro prsclr_128 macro ; inizio macro bank1 ; seleziona banco memoria 1 bcf option_reg,ps0; rapporto prescaler 1:128 bsf option_reg,ps1; // bsf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro prsclr_256 macro ; inizio macro bank1 ; seleziona banco memoria 1 bsf option_reg,ps0; rapporto prescaler 1:256 bsf option_reg,ps1; // bsf option_reg,ps2; // bank0 ; seleziona banco memoria 0 endm ; fine macro ; ***************************************************************************** ; INIT ; ***************************************************************************** Init call IniT1s ; Inizializzazione timer 1 secondo call IniT0 ; inizializzazione timer 0 goto Main ; salto a programma principale ; ***************************************************************************** ; SUBROUTINES ; ***************************************************************************** ; ; IniT1s azzera il timer 1 secondo. ; IniT1s clrf tmr1s ; azzera il timer 1 secondo return ; fine subroutine ; ; IniT0 inizializza il timer 0. Le impostazioni sono le seguenti: sorgente di ; clock interna, prescaler abilitato con rapporto 1:64, interrupt timer 0 ; abilitato, interrupt globali abilitati, impostazione registro al valore 99. ; IniT0 tmr0_clk_int ; abilitazione clock interno prsclr_tmr0 ; abilitazione prescaler prsclr_64 ; rapporto prescaler 1:64 tmr0_int_enf ; abilitazione interrupt tmr0_pst ; impostazione registro timer return ; chiusura subroutine ; ; IntT0 verifica lo stato del bit di interrupt del timer 0. Se il timer 0 ha ; raggiunto la condizione di overflow, viene azzerato l'interrupt e ; aggiornato il contatore. Le funzioni nop sono necessarie per ottenere un ; timing pari esattamente a 10 ms (9.984 + 16 us) e tenendo presente che è ; richiamata una macro. ; IntT0 btfss tmr0_int; verifica interrupt timer 0 retfie ; fine subroutine bcf tmr0_int; azzeramento interrupt timer 0 nop ; nessuna operazione nop ; // nop ; // nop ; // nop ; // nop ; // nop ; // nop ; // nop ; // tmr0_pst ; impostazione registro timer 0 call TmrSvc ; aggiornamento timer 1 secondo retfie ; fine subroutine ; ; TmrSvc gestisce tmr1s che è un contatore incrementale da 0 a 100. La base dei ; tempi è pari a 10 ms. L'overflow del contatore viene pertanto raggiunto ogni ; secondo. ; TmrSvc incf tmr1s,w ; incrementa il timer e salva in w xorlw D'100' ; verifica se il valore è 100 btfsc zero ; // clrf tmr1s ; se valore = 100 azzera il timer incf tmr1s,f ; se valore != 100 incrementa il timer return ; fine subroutine ; ***************************************************************************** ; MAIN ; ***************************************************************************** Main ; INSERISCI QUI IL PROGRAMMA PRINCIPALE goto Main ; chiude il loop ; ***************************************************************************** ; END ; ***************************************************************************** End ; fine del programma Ricorda che usare una rete RC per generare un ritardo avendo a disposizione un microprocessore che fa anche il caffè è tremendamente squalificante! Ciao. Link al commento Condividi su altri siti More sharing options...
FranSys Inserita: 11 febbraio 2005 Segnala Share Inserita: 11 febbraio 2005 Ho notato che la formattazione del codice fa un po' schifo... forse nel file che ho copiato c'era qualche TAB che è stato sostituito da spazi dalla funzione CODE del forum. Se decidi di usarlo è meglio metterlo a posto in modo che sia bel leggibile. Lo farei io ma non ho tempo! Ciao. Link al commento Condividi su altri siti More sharing options...
stefano_ Inserita: 11 febbraio 2005 Autore Segnala Share Inserita: 11 febbraio 2005 grazie 1000 FranSys la penso come te ma non è semplice affatto imparare l'assembler senza nessuno a fianco che ti dia qualche dritta,voi del forum siete gentilissimi e sempre pronti a tutto ma vi assillerei troppo se ad ogni problema spedissi un post comunquevoglio provare ...... speriamo bene... Link al commento Condividi su altri siti More sharing options...
Niki77 Inserita: 13 febbraio 2005 Segnala Share Inserita: 13 febbraio 2005 Non ho ben capito se il pin che utilizzi per il cicalino è utilizzato anche per pilotare un altra cosa oppure no.Nel secondo caso non potresti risolvere con queste due seguenti righe?High X' (x=pin da controllare)pause 1000 '(attesa 1 secondo)Low X ' (x=pin da controllare)Andare a cercare un interrupt per la temporizzazione di durata di un cicalino mi sembra una discreta complicazione inutile.Ciao a tutti Link al commento Condividi su altri siti More sharing options...
stefano_ Inserita: 14 febbraio 2005 Autore Segnala Share Inserita: 14 febbraio 2005 si, il pin è libero il problema è che io utilizzo altre 4 uscite per pilotare 4 display a 7 segmenti multiplexandole ogni 5msse utilizzo pause il multiplexing si blocca per 1 secondo !!!grazie 1000 a tutti Link al commento Condividi su altri siti More sharing options...
k6233 Inserita: 14 febbraio 2005 Segnala Share Inserita: 14 febbraio 2005 (modificato) Puoi fare in questo modo:Quando la condizione per far suonare il cicalino si verifica setti l'uscita, se l'uscita è settata inizi a incrementare la variabile contatore, quando questo ha raggiunto tot conteggi (io ho messo 800) resetti l'uscita e azzeri la variabile.Considera che la durata del suono è legata al tempo ciclo del tuo programma, in questo caso dura 800 scansioni.Ovviamente il tempo non sarà costante dal momento che dipende dalle scansioni, ma eviti di usare interrupt o altre cose complicate, se il suono dura 1 secondo o 1,1 secondi poco cambiacontatore var wordcontatore=0cicalino=0******* TUO CODICE *******If condizionesuono=1 then high cicalinoif cicalino=1 then contatore=contatore+1if contatore>=800 then low cicalino:contatore=0Io molte volte faccio così.CiaoMarco Modificato: 14 febbraio 2005 da k6233 Link al commento Condividi su altri siti More sharing options...
FranSys Inserita: 14 febbraio 2005 Segnala Share Inserita: 14 febbraio 2005 Anch'io a volte ho usato il metodo di k6233, quando non serviva precisione. Però è una soluzione poco elegante che ho adottato solo per comodità.Credo che la gestione degli interrupt, per chi usa i microcontrollori, sia un "must have", spesso irrinunciabile. Tenete presente che sfrondando il codice che ho riportato, il tutto si riduce ad una ventina d'istruzioni. Attenzione alla frequenza del quarzo dell'oscillatore. Io usavo un quarzo da 4 MHz per avere 1 us per ogni step di programma.Ciao. Link al commento Condividi su altri siti More sharing options...
stefano_ Inserita: 15 febbraio 2005 Autore Segnala Share Inserita: 15 febbraio 2005 per K6233facendo come dici tu sorge il seguente problema:dopo il codice che accende il cicalino collegato per esempio alla portb 5 trovo il seguente codice che serve per accendere i displayportb = % 1001 come puoi notare cambio lo stato dei soli primi quattro bit ma nonostante ciò il bit 5 va a zeroconsiderando che cambio lo stato delle uscite all'interno di un ciclo select e che ripeto l'operazione per 30 voltecome posso fare ???grazie 1000 a tutti Link al commento Condividi su altri siti More sharing options...
k6233 Inserita: 15 febbraio 2005 Segnala Share Inserita: 15 febbraio 2005 Il bit 5 va a 0 perchè fai una assegnazione diretta al valore della portab.Per evitare questo dovresti cambiare lo stato dei primi quatto bit singolarmente:high portb.0low portb.1low portb.2high portb.3Credo ci siano altri modi (meno macchinosi) ma adesso sono un pò arrugginito, è un pò di tempo che non scrivo codice!!!SalutiMarco Link al commento Condividi su altri siti More sharing options...
stefano_ Inserita: 15 febbraio 2005 Autore Segnala Share Inserita: 15 febbraio 2005 grazie,provo subito poi ti faccio sapere come è andata !!! Link al commento Condividi su altri siti More sharing options...
stefano_ Inserita: 17 febbraio 2005 Autore Segnala Share Inserita: 17 febbraio 2005 ciao K6233funziona !!!! tutto ok o quasi.....visto che ci sono ne approfitto per romperti ancora un pò e chiederti l'ultimo aiuto.Devo vedere se una variabile vale 5 o un multiplo di 5 e se è così attivare porta.4 .Il codice che ho utilizzato è il seguenteif variabile = 5 or variabile = 10 or variabile = 15 then set porta.4come puoi notare non è che sia il massimo anche perche devo arrivare fino a 100 !!!ho visto che c'è una funzione che si chiama modulus e il simbolo è //Dall'. in linea mi sembrava di aver capito che questa funzione mi restituisse il resto della divisione quindi se il resto di variabile // 5 è 0 significa che la variabile vale 5 o un suo multiploPurtroppo non è cosi questo ragionamento va bene solo per il numero 2 e quindi riesco a vedere se un numero è pari ( 2 o un suo multiplo )con 5 non funziona.Come posso fare ??grazie 1000 a tutti,non so proprio come farei senza di voi !!!!ciao ciao Link al commento Condividi su altri siti More sharing options...
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