Vai al contenuto
PLC Forum


Frequenzimetro con PIC16F18346


dott.cicala

Messaggi consigliati

Salve a tutti.

 

Nel PIC usato nella mia ultima realizzazione (il carico fittizio intelligente poi ribattezzato RF Analyzer) sono avanzati un paio di pins e una discreta quantità di memoria.

Ho pensato quindi di dotarlo di un frequenzimetro capace di leggere fino a 50MHz e magari dotarlo successivamente di un prescaler in modo tale da estendere la lettura fino oltre i 500MHz. C'è anche abbastanza spazio sul display

Cattura.JPG.9502c5210b44e3cb993e26bb430c2fec.JPG

 

Facendo una veloce ricerca in rete è facile trovare moltissimi frequenzimetri basati su un pic.

Spesso viene usato il vecchio 16F84 o l'altrettanto anziano 16F628, ma a me non è mai piaciuta la pappa pronta e quindi voglio sviluppare qualcosa di mio.

 

Ho a disposizione vari timers a 16bit, compreso il TMR0 che nei vecchi pic è a 8bit.

 

L'idea sarebbe quella di utilizzare TMR1 per conteggiare gli impulsi, quindi comandato da T1CKI, ed usare TMR0 per generare una base tempi fissa a 100ms.

 

La precisione non sarà eccelsa anche perché non ho usato un quarzo e nemmeno ci sarebbe lo spazio per aggiungerlo, ma l'oscillatore interno, ma a me non interessa. L'obbiettivo è quello di avere un'indicazione di massima con precisione al kHz nell'intervallo 100kHz - 50MHz.

 

Diamo per scontato che il condizionamento del segnale sia affidato ad altro circuitino da appiccicare dietro e che si occuperà di trasferire a T1CKI

un segnale ben squadrato, di ampiezza sufficiente e con duty cycle sempre al 50%.

 

Le considerazioni iniziali che ho avanzato sono le seguenti:

 

1) In 100ms

    di un segnale a 50MHz potrò contare 5milioni di impulsi

    di un segnale a 100kHz potrò contare 10mila impulsi

 

2) TMR1 va in overflow ogni 65536 impulsi

 

Di conseguenza 

a 50MHz TMR1 andrà in overflow 76,2939453125 volte

a 100kHz andrà in overflow 1,52587890625 volte

 

Se definisco una variabile longuint Tmr1Count  per contare quante volte TMR1 è andato in overflow avrò che la frequenza misurata sarà

(tenendo conto che TMR1 viene azzerato prima di iniziare il conteggio)

Fatt = 10*(TMR1+(65536*Tmr1Count));

 

3) C'è già una routine di interrupt usata per la lettura dell'encoder. Se ai due timer faccio generare i relativi interrupts, ne andranno gestite la priorità

    Se leggo i due timer in polling....mi sa che il risultato sarà pessimo.

 

Sono graditi commenti e suggerimenti 

Modificato: da dott.cicala
Link al commento
Condividi su altri siti


del_user_97632

Ciao,

soluzione di 2 interrupt dovrebbe andare bene senza problemi. (Editato) Se e' un pic 16 (14 bit) c'e' un unico interrupt (entry point @ 4), dentro verifichi quale dei due timer e' scattato, per la frequenza solo incrementi la variabile ed esci. Quando scatta l'interrupt a tempo "fisso" leggi il conteggio di TMR1, lo processi, poi azzeri tutto (almeno io proverei cosi).

 

Saluti.

Modificato: da _angelo_
Link al commento
Condividi su altri siti

43 minuti fa, _angelo_ scrisse:

Se e' un pic 16 (14 bit) c'e' un unico interrupt

Grazie per la risposta.  Hai ragione, c'è un interrupt solo.

 

Per il resto sto agendo proprio come hai descritto tu.

 

 

 

Link al commento
Condividi su altri siti

io avevo fatto un quache cosa di simile con pic, anni fa, ma facendo contare gli impulsi da uno dei contatori durante una base dio tempo calcolata con un timer.

Link al commento
Condividi su altri siti

1 ora fa, _angelo_ scrisse:

fammi sapere, mai fatto un frequenzimetro quindi sono curioso se funziona.

Senz'altro...ma deve funzionare altrimenti lo brucio! :superlol:

 

9 minuti fa, Livio Orsini scrisse:

ma facendo contare gli impulsi da uno dei contatori durante una base dio tempo calcolata con un timer.

E' più o meno lo stesso procedimento. Un timer è la base tempi, nel mio caso fissa a 100ms, l'altro timer conta gli impulsi.

 

Al momento sto valutando a chi far contare gli impulsi e a chi far fare la base tempi

 

Link al commento
Condividi su altri siti

3 minuti fa, dott.cicala scrisse:

nel mio caso fissa a 100ms,

 

Io l'avevo fatta variabile a decadi da 1ms a 1"

Link al commento
Condividi su altri siti

Certamente sarebbe meglio avere una base tempi variabile, ma per il momento mi accontento.

E' un opzione che considererò se avanzerà ancora della memoria.

La situazione attuale è questa

mem.JPG.3ace14c7eb5036874ed43b98353ed266.JPG

Dovrebbe bastare per tutto ma onde evitare di scrivere codice che poi non ci sta, meglio procedere a piccoli passi

Link al commento
Condividi su altri siti

del_user_97632

Per curiosita, stai usando mplab C senza ottimizzazioni size erc (free), con ottimizzazioni, o assembly ? Oppure altri compilatori ?

Modificato: da _angelo_
Link al commento
Condividi su altri siti

XC8 è bellissimo ma la versione free spreca la memoria. Sottoscrivere l'abbonamento è un costo che non reputo giustificabile per scopi amatoriali.

Assembly è potente ma non ha l'immediatezza di lettura e quindi, dopo un po' di tempo per capire cosa fa un certo fw, magari scritto di fretta e con pochi commenti, mi trovavo costretto a ristudiarmi tutto da capo.

 

Fra tutti gli altri linguaggi e compilatori ho preferito il C trovando in MikroC for Pic nella versione full (249€) un compromesso decente tra prestazioni e costo.

 

Il rovescio della medaglia è che ha delle librerie letteralmente da vomito che non funzionano quasi mai o funzionano male con i pic più recenti.

 

Il PIC16F18346 è del 2015 e di conseguenza le librerie per lcd, adc, flash e tutte quelle che ho provato, non funzionano e me le sono dovute scrivere una per una....in compenso però riesco a sfruttare la memoria fino all'ultimo byte.

 

Ad esempio, il codice dell' RF Analyzer non può essere compilato con XC8 per mancanza di spazio, con MikroC invece ne avanza.

Link al commento
Condividi su altri siti

Poche righe e....Funziona!

Ecco la ISR

//##############################################################################
// Interrupt
//##############################################################################
void interrupt()
{
   //**********************************
   //  TMR0 Time Base 100ms
   //**********************************
     if(PIR0.TMR0IF)
      {
       TMR0H=0xCE;
       TMR0L=0xEA;
       T1CON.TMR1ON=~T1CON.TMR1ON;
       if(!T1CON.TMR1ON)
         {
          Fatt=2*(TMR1+(65536*T1count));
          TMR0=0;
          TMR1=0;
          T1count=0;
          T1CON.TMR1ON=1;
         }
       PIR0.TMR0IF=0;
      }
   //**********************************
   //  TMR1 Pulse Counter
   //**********************************
     if(PIR1.TMR1IF)
       {
        T1count++;
        PIR1.TMR1IF=0;
       }
}

la routine di visualizzazione

void(frcount)()
{
  // Centinaia MHz
  Fmis[7]=(Fatt/10000000) %10;
  if(Fmis[7]==0)LCD_Chr(4,1,' ');
  else LCD_Chr(4,1,48+Fmis[7]);
  // Decine MHz
  Fmis[6]=(Fatt/1000000) %10;
  if(Fmis[7]==0 && Fmis[6]==0)LCD_Chr(4,2,' ');
  else LCD_Chr(4,2,48+Fmis[6]);
  // Unità MHz
  Fmis[5]=(Fatt/100000) %10;
  LCD_Chr(4,3,48+Fmis[5]);
  // Separatore
  LCD_Chr(4,4,',');
  // Centinaia kHz
  Fmis[4]=(Fatt/10000) %10;
  LCD_Chr(4,5,48+Fmis[4]);
  // Decine kHz
  Fmis[3]=(Fatt/1000) %10;
  LCD_Chr(4,6,48+Fmis[3]);
  // Unità kHz
  Fmis[2]=(Fatt/100) %10;
  LCD_Chr(4,7,48+Fmis[2]);
  Lcd_Out(4,8, "kHz");
}

e avanza ancora spazio

capture_001_01042019_195822.jpg.7612544189f0f395ed01bb82982e49ed.jpg

 

La prima prova

IMG_0002.JPG.2654f33d324c870ec3fa59d89e54eabe.JPG  IMG_0004.JPG.8d6d47abdd455ef228300bae26ade9f7.JPG

La base tempi deve essere calibrata meglio

 

Modificato: da dott.cicala
Link al commento
Condividi su altri siti

del_user_97632

Ottimo !

Con l'assembly i calcoli a 16 bit e il programma nel suo insieme non sarebbero stati cosi rapidi :)

 

Carina la cosa che i nuovi pic salvano page/status e diversi altri registri in automatico entrando nell'interrupt, oltre a tutte le nuove features dell'indirizzamento indiretto piu potente, istruzioni aggiunte etc, e a costare 1/5 dei vecchi.

 

Si, chiedevo perche' da poco ho usato xc8 per una applicativo su 16f14455 e ho riempito il 95% della flash con le ottimizzazioni in size.
Avevo avvisato l'azienda per cui ho fatto l'applicativo che partivo con la versione di prova ma c'era questo possibile problema. Ora il periodo di prova e' scaduto e sara' purtroppo loro sventura pagarsi se serve la licenza mensile. Non ero riuscito a trovare rapidamente una soluzione migliore, dunque, grazie dell'idea di MikroC.

 

Per mio uso e consumo pagare licenze per i pic 14bit e' intollerabile, visti gli avr, e poi stm32 etc. Ma questo e' solo quello che penso io.

 

Saluti e ben fatta.

 

angelo

 

Modificato: da _angelo_
Link al commento
Condividi su altri siti

Sì in effetti i nuovi pic sono molto interessanti, fra le tante novità, il PPS che qui mi ha salvato.

Infatti avevo già realizzato il pcb e l'ingresso T1CKI era usato per altro scopo.

Col pps l'ho potuto spostare su di un pin libero

 

   INTCON.GIE = 0;             // DISABLE INTERRUPTS
   PPSLOCK    = 0x55;          // PPS LOCK/UNLOCKS SEQUENCE
   PPSLOCK    = 0xAA;          // PPS LOCK/UNLOCKS SEQUENCE
   PPSLOCK    = 0x00;          // ENABLE WRITES
   T1CKIPPS   = 0x01;          // Peripheral input is RA1
   PPSLOCK    = 0x55;          // PPS LOCK/UNLOCKS SEQUENCE
   PPSLOCK    = 0xAA;          // PPS LOCK/UNLOCKS SEQUENCE
   PPSLOCK    = 0x01;          // DISABLE WRITES

Si poteva fare anche prima, ma non con tutte le periferiche.

 

Ti raccomando di non usare MikroC per scopi professionali. 

Riserva spesso bruttissime sorprese, come ad esempio crashare improvvisamente, spesso al CTRL Z mischiando il codice o cancellandone delle parti, oltre a quanto detto delle librerie.

Per questa ragione mi tengo sempre una copia salvata in notepad++, al limite mi perdo i settaggi dei fuses, ma di quelli ce ne si accorge subito

Modificato: da dott.cicala
Link al commento
Condividi su altri siti

del_user_97632

Ok grazie !

 

Si tante novita' carine, ho visto,

poi ci sono anche i nuovi amici come ANSEL , da assaporare e sbatterci bene la testa :)

 

Mi pare di capire che MikroC e' solo per windows, io lavoro esclusivamente su Linux, lavoro nel settore open-source e difficilmente carico windows. comunque, il compilatore potrebbe girare sotto emulatore senza problemi. Daro' un occhiata.

 

Rigurado i crash, accipicchia !  Hai provato a usare il compilatore da riga di comando (credo mcpp.exe) ? Potresti programmare in eclipse o altri editor carini e lanciare il compilatore da un comando di toolbox o da console.

 

 

Modificato: da _angelo_
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...