Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Un orologio con un PIC 16F628a sarà preciso?

Tipologie, strumenti di sviluppo, hardware e progetti

Moderatore: Foto UtentePaolino

0
voti

[21] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteTricka90 » 15 set 2014, 15:49

WALTERmwp ha scritto:Poi, prova ad essere più "preciso" nella descrizione della mancanza di "accuratezza" che ritieni di rilevare.


Ho provato a cronometrare diverse volte e ho rilevato che il lampeggiamento, dopo circa 6 minuti, è già in anticipo di circa 500ms. Si vede persino "a occhio" che il lampeggiamento è più rapido di 1 secondo.
E quest'errore è molto maggiore dell'errore del 0,006% che mi aspettavo dai calcoli...
Avatar utente
Foto UtenteTricka90
662 1 6 10
Expert
Expert
 
Messaggi: 627
Iscritto il: 1 lug 2013, 15:53

1
voti

[22] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteWALTERmwp » 15 set 2014, 16:11

Foto UtenteTricka90, se i parametri sono e sono rimasti quelli ai quali facevi riferimento e nel tuo codice hai lasciato il test impostato sulla costante pari a 1953 compi un altro errore.
Quando è "trascorso" un secondo la tua variabile " i " dovrebbe valere 490.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
22,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6364
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[23] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteTricka90 » 15 set 2014, 16:27

Si, ho lasciato anche 1953. Come mai dovrebbe essere 490? Questo proprio non mi torna...come hai ottenuto questo valore?
Avatar utente
Foto UtenteTricka90
662 1 6 10
Expert
Expert
 
Messaggi: 627
Iscritto il: 1 lug 2013, 15:53

1
voti

[24] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteWALTERmwp » 15 set 2014, 18:21

Ho usato il condizionale, perché non è detto sia corretto quello che ho scritto, ma tu per quale motivo hai conservato quel limite (1953) ?
La mia risposta, se vogliamo, è in parte in questa domanda.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
22,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6364
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[25] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteTricka90 » 15 set 2014, 18:38

Beh, semplicemente ho fatto:
- durata di 1 ciclo = (1 / 4MHz)x4 = 1us
- tempo che trascorre fra due interrupt consecutivi = 1us x 2 x 256 = 512us
- valore della variabile tale che il LED cambia stato ogni secondo = 1s / 512us = 1953
Avatar utente
Foto UtenteTricka90
662 1 6 10
Expert
Expert
 
Messaggi: 627
Iscritto il: 1 lug 2013, 15:53

0
voti

[26] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteTricka90 » 15 set 2014, 18:52

Ora ho provato a seguire il consiglio di Foto UtenteTardoFreak ed utilizzare il timer 2.
Ho seguito passo passo il datasheet e l'esempio del link e sono certo di non aver dimenticato niente ed aver impostato tutto correttamente.
Eppure il codice non funziona. Il LED rimane acceso (e non sta lampeggiando velocemente, l'oscilloscopio è d'accordo). Ho fatto una verifica e ho notato che il programma non accede alla funzione di interrupt. Eppure il timer è acceso, l' "Enable Bit" è attivato, ed è tutto a posto credo. Vi viene in mente qualcosa?
Il codice completo è il seguente:

Codice: Seleziona tutto
unsigned int i = 0;

void interrupt()
{
  if (PIR1.TMR2IF)
     {
      i++;
      if (i == 100)
         {
          PORTB.RB3 = ~PORTB.RB3;    //cambio ogni 1s
          i = 0;
          }
      PIR1.TMR2IF = 0;
      }

}


void main()
{
T2CON = 0b10010011;
PR2 = 250;                  //interrupt ogni 10ms

INTCON.GIE = 1;
PIE1.TMR2IE = 1;

T2CON.TMR2ON = 1;



TRISB = 0;
PORTB = 0;

PORTB.RB3 = 1;

while (1)

{

  }

}
Avatar utente
Foto UtenteTricka90
662 1 6 10
Expert
Expert
 
Messaggi: 627
Iscritto il: 1 lug 2013, 15:53

1
voti

[27] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteWALTERmwp » 15 set 2014, 20:58

Per questo ...
Tricka90 ha scritto:Come mai dovrebbe essere 490? Questo proprio non mi torna...come hai ottenuto questo valore?
... se come prescaler scegli il rapporto 1:8 (datasheet, pag.23) invieresti un impulso, al TRM0 Reg (datasheet, pag.46) ogni x millisecondi dove: x=((1/ (4 MHz/4)) * 8); in tal caso x == 8 microsecondi.
Se imposti il timer 0 per contare da 0 a 255, quando si verifica l'overflow sono trascorsi 2,04 millisecondi ( 8 microsecondi * 255).
In un secondo, il blocco timer andrebbe in overflow n volte dove: n=(1 s/ 2,04 ms); in tal caso n == 490.
Ogni volta che esegui la routine di interrupt incrementi la tua variabile " i " sino a raggiungere "quota" 490.
A quel punto è trascorso il tuo secondo.
Mi sono basato sui parametri che tu avevi riferito.
Non era mia intenzione proporre un indovinello ma semplicemente lasciarti dare la spiegazione.
Penso che quanto sopra sia corretto, ma vale appunto per il timer 0 ( ... e per i parametri stabiliti).
Altra questione è l'impiego del timer 2 per il quale mi sembra tu stia facendo riferimento a ben "altro" utente ... (Foto UtenteTardoFreak) ...

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
22,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6364
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[28] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteTricka90 » 15 set 2014, 23:35

Ok capisco, allora forse non mi ero spiegato bene: ho mantenuto intatti tutti i parametri tranne il prescaler, quest'ultimo l'ho portato a 2 e ho mantenuto il valore di "i" a 1953 in modo che il LED lampeggiasse ogni secondo.
Certo avrei potuto anche fare come dici tu: mantenere il prescaler a 8 ma portare la "i" a 490.
In entrambi i casi però il LED non lampeggia con precisione e non riesco proprio a capire come mai...potrebbe essere colpa di MikroC, il software che utilizzo?
Avatar utente
Foto UtenteTricka90
662 1 6 10
Expert
Expert
 
Messaggi: 627
Iscritto il: 1 lug 2013, 15:53

4
voti

[29] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteGuidoB » 16 set 2014, 1:29

Ciao Foto UtenteTricka90,
volevo aggiungere un suggerimento a quelli, peraltro ottimi, che ti hanno già dato i "colleghi di forum".

Quando vuoi ottenere una frequenza accurata a lungo termine ma:

1) la frequenza dell'oscillatore che hai, pur essendo stabile, non ha il valore nominale esatto che ti aspetti; e/o

2) la frequenza dell'oscillatore, divisa da prescaler e contatori, non è un multiplo della frequenza che vuoi (e quindi non puoi effettuare una divisione intera per ottenerla);

ALLORA puoi utilizzare vantaggiosamente un "trimmer software" (non ne conosco un nome ufficiale, ma io l'avevo battezzato così).

Facciamo un esempio:
hai una frequenza di oscillatore Fosc di circa 4 MHz e vuoi ottenere una frequenza, accurata a lungo termine, di 1 Hz.

La tua frequenza di 4 MHz passa attraverso un primo divisore per 4, un prescaler e un contatore autoricaricante. Questa catena divide la frequenza per (supponiamo) 2^{18}, cioè per 262144.

Quindi avrai a disposizione una frequenza che ti genera un interrupt \frac{4\cdot 10^{6}}{2^{18}}= 15,258789... volte al secondo.

Da lì, per tirare fuori 1 Hz, devi dividere per 15,258789... che non è un numero intero, e quindi l'operazione non è così banale.

Qui viene in aiuto il trimmer software.

Definiamo una variabile intera senza segno da, supponiamo, 32 bit. Cioè un unsigned long, sulla maggior parte delle macchine. La chiameremo contatore.

Definiamo una unità di tempo (che in omaggio al tuo nickname chiamerò trick :mrgreen: ), dove 1\,\textup{trick}=2^{-32}\,\textup{s}, cioè 1\,\textup{trick}=0,23283...\,\textup{ns}.
2^{32} trick fanno 1 secondo, e dovrebbe essere ormai chiaro dove voglio andare a parare.

Se ad ogni interrupt sommiamo alla variabile contatore il periodo, espresso in trick, della frequenza di 15,258789... Hz, ecco che contatore andrà in overflow una volta al secondo.

Il periodo della frequenza di 15,258789... Hz espresso in trick è:

\frac{2^{32}}{\frac{4\cdot 10^{6}}{2^{18}}}=\frac{2^{32}\cdot 2^{18}}{4\cdot 10^{6}}=\frac{2^{50}}{4\cdot 10^{6}}=281\,474\,976,71...\,\textup{trick}

che arrotonderemo all'intero più vicino, cioè 281 474 977.

E adesso vediamo la procedura di interrupt:

Codice: Seleziona tutto
#define SOFTWARE_TRIMMER_VAL 281474977
...
unsigned long contatore = 0;
unsigned long trimmer = SOFTWARE_TRIMMER_VAL;
...
void interrupt()
{
  if (... /* È l'interrupt dell'auto-reload timer? */)
  {
    /* Sì! Incrementiamo il contatore: */
    contatore += trimmer;
    if (contatore < trimmer)
    {
      /* Overflow contatore: vuol dire che è passato 1 secondo! */
      /* Eseguiamo le operazioni relative, per esempio aggiorniamo i secondi: */
      ...
    }
    /* Reset interrupt flag: */
    ...
  }
}

Visto che facile?

Attenzione: l'aggiornamento dei secondi ha un leggero jitter.
Infatti a volte la procedura di interrupt aggiorna i secondi dopo 15 chiamate, altre volte dopo 16. Questo è necessario per mantenere un'alta accuratezza a lungo termine.

Possiamo calcolare anche la granularità del trimmer. In questo caso, aumentandolo o diminuendolo di una unità alla volta, la granularità è di circa una parte su 281 474 977, cioè circa 3,6 parti per miliardo. Tradotto in rapporto di tempi, circa un decimo di secondo all'anno. Se è ancora troppo, bisogna aumentare il numero di bit del contatore.

I quarzi hanno tolleranze generalmente misurate in parti per milione.
Per esempio, un quarzo da 4 MHz con una tolleranza di 20 p.p.m. potrebbe oscillare a 4 000 080 Hz anziché alla frequenza nominale di 4 000 000 Hz. Tralasciando derive per temperatura e simili, in questo esempio ciò darebbe un errore sistematico (un anticipo) di circa 53 secondi al mese.

Ma con il trimmer software possiamo compensare questo errore. Come?
Basta ricalcolare il valore del trimmer:

\frac{2^{32}}{\frac{4\,000\,080}{2^{18}}}=\frac{2^{32}\cdot 2^{18}}{4\,000\,080}=\frac{2^{50}}{4\,000\,080}=281\,469\,347,32...\,\textup{trick}

la cui parte intera ha una differenza di 5630 trick in meno rispetto al valore nominale calcolato in precedenza.

Se hai un buon frequenzimetro puoi misurare la frequenza dell'oscillatore e fare il calcolo a tavolino.
Ma si può anche pensare ad un aggiornamento "dinamico": ogni volta che regoli l'orologio, questo oltre a rimettere in sincronia l'orario potrebbe calcolare l'errore sul tempo trascorso dalle regolazioni precedenti. Quindi potrebbe ricalcolare il valore del trimmer per minimizzare l'errore futuro.

E le temporizzazioni corte ???

Abbiamo detto che questo trimmer software mantiene una buona accuratezza a lungo termine, ma che a breve termine c'è un certo jitter (non tutti i secondi sono lunghi uguali).

Per temporizzazioni corte sarebbe bene avere una base dei tempi con periodo il più possibile vicino a tempi "standard" (1 ms o 10 ms per esempio). Per ottenere questi tempi si può scegliere un opportuno fattore di divisione del timer auto-ricaricante.
In questo modo si possono ottenere temporizzazioni corte ripetibili e senza jitter, se pure affette da un errore sistematico dovuto al fattore di divisione (che deve essere intero e fisso) e alla tolleranza del quarzo.

Per temporizzazioni lunghe, anziché far avanzare i secondi, per esempio, ogni 100 scadenze di un timer da 10 ms, si può applicare a questa base dei tempi da 10 ms il metodo già visto del trimmer software, ottenendo in questo modo il "meglio dei due mondi":

- temporizzazioni corte ripetibili e senza jitter;
- temporizzazioni lunghe accurate sul lungo periodo.

Buona notte a tutti! O_/
Big fan of ƎlectroYou!
Avatar utente
Foto UtenteGuidoB
14,4k 6 12 13
G.Master EY
G.Master EY
 
Messaggi: 2243
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

2
voti

[30] Re: Un orologio con un PIC 16F628a sarà preciso?

Messaggioda Foto UtenteWALTERmwp » 16 set 2014, 11:51

Foto UtenteGuidoB, il trick ... potrebbe diventare l'unità di base dei tempi (clandestina) da impiegare nei microcontrollori ... sembra quasi un "trucco" ...

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
22,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6364
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

PrecedenteProssimo

Torna a Realizzazioni, interfacciamento e nozioni generali.

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite