Progetti

   

Tutorial

   

Servizi

   
Benvenuto, Ospite
Nome utente: Password: Ricordami

ARGOMENTO: Frequenzimetro con pic18

Frequenzimetro con pic18 8 Anni 5 Mesi fa #1

  • paoletto
  • Avatar di paoletto
  • Offline
  • Gold Boarder
  • Messaggi: 186
  • Ringraziamenti ricevuti 3
  • Karma: 2
Salve a tutti, ieri al volo ho provato a fare un semplice frequenzimetro con un pic18F4550. Ho usato il timer0 come base dei tempi in modo tale da far scattare un interrupt ogni secondo e poi il timer1 come contatore di fronti di salita con RC0 come ingresso. Dopo ogni secondo Timer1 conterrà proprio il valore di frequenza.
Funziona, ma non è molto preciso, ad esempio calcola 20072Hz invece di 20000, oppure 10036 invece di 10000, quindi sta sbagliando dello 0,36%.
A frequenze molto basse l'errore è grave ad esempio 8Hz invece di 10, ed inoltre la risoluzione fa pena!
Sicuramente si può fare di meglio, in verità volevo usare il modulo Capture ma non ci sono riuscito.




// File template
#include "p18f4550.h"
#include "p18f4550.c"
#include "display.c"
#include "delay.c"
#include <timers.h>
 
 
 
 
// DEFINIZIONI
 
 
 
/*------------------------------PROTOTIPI-----------------------------*/
 
/*--------------------------------MAIN--------------------------------*/
 
void main(void)
 {
	TRISD=0;
	TRISCbits.TRISC0 = 1; //RC0 COME INGRESSO
	Init_LCD();  
	PulisciLCD();
 
	RCONbits.IPEN = 1; //modalità compatibile
	INTCONbits.GIE = 1; //enable global interrupts  
	RCONbits.IPEN = 1;  //enable priority interrupts 
 
 
 
 
 
OpenTimer0( TIMER_INT_ON &
			T0_16BIT &
			T0_SOURCE_INT &
			T0_PS_1_256);
 
 
OpenTimer1( TIMER_INT_OFF &
			T1_16BIT_RW &
			T1_SOURCE_EXT &
			T1_PS_1_2 &
			T1_OSC1EN_OFF &
			T1_SYNC_EXT_ON);
 
 
 
while(1){
 
 
	Scrivistringa("Frequenza:");
		Cursor2LINE();
			Scrivinumero(Frequenza,5);
				Scrivistringa(" [Hz]");
		HomeLCD();
 
		}
 
 
 }	
 
 
	#pragma udata
	volatile unsigned int Frequenza;
 
	//These are your actual interrupt handling routines.
	#pragma interrupt YourHighPriorityISRCode
	void YourHighPriorityISRCode()
 
	{
 
 
		if(INTCONbits.TMR0IF==1)
 
			{
				Frequenza=(ReadTimer1())<<1; //Leggo TIMER1 dopo aver moltiplicato per 2 
 
					WriteTimer1(0);	//Resetto TIMER1 e lo faccio ripartire da 0
 
						INTCONbits.TMR0IF=0;	//Pulisco il flag di 
		                                                          //interruptdiTIMER0
                                                 WriteTimer0(18473);	//Ricarico TIMER0 per avere un 
                                                                         //interrupt ogni secondo
				}
			}
 
 
 
 
 
 

Qualcuno ha usato il modulo Capture per misure di frequenza?
Che risoluzione ha ottenuto?
Che incertezza?

Saluti
Paoletto
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

Frequenzimetro con pic18 8 Anni 5 Mesi fa #2

  • +RGZ
  • Avatar di +RGZ
  • Offline
  • Junior Boarder
  • Messaggi: 22
  • Karma: 0
Salve lo sbaglio del 0,36% secondo me è dovuto al ritardo fra l'intercorrere dell'interrupt causato da TMR0 e la scrittura (dopo il calcolo) del valore Frequenza in memoria, non a caso a 10Khz entrano in TMR1 36 impulsi in più mentre a 20Khz sono 72 impulsi (il doppio esatto). Per ovviare a questo bloccherei subito il timer1 all'intercorrere dell'interupt su TMR0 anche se (prova a guardare il disassemblato) l'istruzione if(INTCONbits.TMR0IF==1) ci metterà del tempo ad essere eseguita (dipende dal clock) e a seconda della frequenza che stai misurando sarà più o meno tascurabile. La base tempi la manterrei vicino a limite della saturazione di TMR1 per la frequenza che stai misurando e non fissa a 1 HZ. Prendi quello che ti ho detto con le pinze devi fare delle prove e dei conti. Saluti Gabriele
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

Frequenzimetro con pic18 8 Anni 5 Mesi fa #3

  • paoletto
  • Avatar di paoletto
  • Offline
  • Gold Boarder
  • Messaggi: 186
  • Ringraziamenti ricevuti 3
  • Karma: 2
Grazie mille Gabriele, bisogna ragionarci un pò. Ieri ho fatto tutto in fretta e furia.
Però penso che il modo migliore sia usare il modulo capture essendo quest'ultimo nato proprio per questi scopi, ma non sono riuscito a farlo funzionare.

Come faresti a non mantenere fissa la base dei tempi?

Saluti
Paoletto
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

Frequenzimetro con pic18 8 Anni 5 Mesi fa #4

  • +RGZ
  • Avatar di +RGZ
  • Offline
  • Junior Boarder
  • Messaggi: 22
  • Karma: 0
Io farei due o più basi dei tempi dipende dal range di frequenza che voglio misurare, all'inizio manterrei quella più breve poi se Tmr1 va in overflow commuto alla successiva in automatico se invece vedo che il valore di impulsi catturato è più piccolo di un certo valore scelgo la base tempi precedente...facile a parole !! ..non ho mai usato il capture Saluti Gabriele
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

Frequenzimetro con pic18 8 Anni 5 Mesi fa #5

  • paoletto
  • Avatar di paoletto
  • Offline
  • Gold Boarder
  • Messaggi: 186
  • Ringraziamenti ricevuti 3
  • Karma: 2
Proverò a fare qualche prova :)
Grazie mille.
Paoletto.
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.
Powered by Forum Kunena
   
© LaurTec 2006-2022