Il generatore di clock

Quarzo da 12 MHz

Il PIC18 dispone di un'ampia varietà di generatori di clock; è inoltre possibile scegliere la frequenza di funzionamento in un intervallo piuttosto esteso, compreso tra zero e diverse decine di MHz, a seconda del modello.

La ragione per scegliere una frequenza di funzionamento elevata è evidente: ottenere prestazioni migliori.

La ragione per scegliere una frequenza di funzionamento bassa è essenzialmente diminuire il consumo di corrente, proporzionale alla frequenza di clock.

A volte la frequenza di funzionamento è imposta da ragioni esterne: un esempio tipico è la necessità di avere un clock multiplo intero della frequenza usata in un sistema di comunicazione al fine di evitare l'uso di complessi sistemi di sincronizzazione tra la CPU e il clock di trasmissione.

Il PIC18 permette svariate sorgenti di clock:

Occorre inoltre osservare  che a volte sono disponibili più clock, per esempio uno a frequenza elevata, per le attività ordinarie, ed uno a frequenza molto bassa, tipicamente 32 768,0 KHz, usato anche per l'orologio "in tempo reale" interno.

Di seguito un esempio dello schema del generatore di clock, piuttosto complesso e relativo ad un PIC18 recente:

Alcune funzioni richiedono, per il corretto funzionamento, di conoscere la frequenza del clock. Per esempio le macro di ritardo fornite con il compilatore XC8 utilizzano la costante _XTAL_FREQ. Anche la configurazione di alcune periferiche interne (ADC, UART, Timer...) dipende dalla frequenza di clock.

Il clock interno

Sono presenti due clock interni:

Il codice per utilizzare il clock interno, a dispetto dello schema sopra riportato, è in realtà è piuttosto semplice:

Vediamo un semplicissimo codice, riportato solo nelle parti rilevanti, e gli effetti prodotti dal cambiamento di clock. Il programma non fa altro che alternare alta e bassa l'uscita 0 di PORTC (LATCbits.LC0), in un loop infinito.

// Oscillator Selection bits->Internal oscillator block, port function on RA6 and RA7
#pragma config FOSC = INTIO67

void main(void) {
  TRISCbits.RC0 = 0; // Set RC0 as output
  while (1) {
    LATCbits.LC0 = ~LATCbits.LC0;
  }
}

Il codice appena mostrato usa il clock interno alla frequenza predefinita. Nel caso del PIC18F25K20, utilizzato per la dimostrazione, è pari a 1 MHz, cioè il periodo del clock è pari a 1 µs.

Il tempo per cui il segnale rimane alto o basso può essere calcolato come la somma delle durate delle singole istruzioni del loop. Osservando il codice assembly, si vede che il codice esegue un'istruzione macchina dalla durata di 4 impulsi di clock e un'istruzione macchina che ne richiede 8, da cui la durata di 12 µs mostrata nel grafico. Si noti che il periodo del segnale generato è di 24 µs, pari all'esecuzione di due loop. Osservazione 1

Uscita con clock a 1 MHz

Il codice seguente, uguale al precedente se non nella modifica del registro OSCCON, rende il programma quattro volte più veloce: infatti il clock è ora 4 MHz.

#pragma config FOSC = INTIO67
// Oscillator Selection bits->Internal oscillator block, port function on RA6 and RA7

void main(void) {
  TRISCbits.RC0 = 0; // Set RC0 as output
  OSCCONbits.IRCF = 0b101;
  while (1) {
    LATCbits.LC0 = ~LATCbits.LC0;
  }
}

La scala e la posizione dei cursori sono rimasti invariati, ma ora è evidenziata dai cursori l'esecuzione di quattro loop in 12 µs.

Uscita con clock a 4 MHz

Infine, il programma seguente imposta la massima frequenza di funzionamento, scegliendo la frequenza di 16 MHz ed attivando il PLL che moltiplica per quattro tale valore: il periodo teorico a 64 MHz dovrebbe essere 375 ns (12 periodi di clock per ciascun loop, ripetuto due volte). Si noti nel grafico il cambio di scala rispetto ai precedenti. Osservazione 2

#pragma config FOSC = INTIO67
// Oscillator Selection bits->Internal oscillator block, port function on RA6 and RA7

void main(void) {
  TRISCbits.RC0 = 0; // Set RC0 as output
  OSCCONbits.IRCF = 0b111;
  OSCTUNEbits.PLLEN = 1;

  while (1) {
    LATCbits.LC0 = ~LATCbits.LC0;
  }
}

Uscita con clock a 64 MHz

Taratura del clock interno

Il clock interno è poco preciso, soprattutto in presenza di significative variazione di temperatura o tensione di alimentazione. Indicativamente il fogli tecnici riportano tolleranze dell'ordine del 2%, che diventano il 5% e oltre alle temperature estreme. Solo pochi modelli di PIC18 riescono a migliorare la precisione, rimanendo comunque nell'intorno del punto percentuale.

Per questo è disponibile il registro OSCTUNE che permette di effettuare la taratura durante l'esecuzione del programma. In pratica è possibile un piccolo incremento o decremento della frequenza dell'oscillatore interno, per compensare le tolleranza di produzione e dovute alle condizioni esterne. Ovviamente per fare ciò è necessario disporre di un clock esterno preciso, come potrebbe essere la frequenza di rete o un clock di una trasmissione seriale esterna.

Per esempio, usando (in alternativa!) le due seguenti impostazione si ottengono i due segnali riportati. La configurazione di base è la stessa dell'ultimo esempio sopra riportato (clock nominale di 64 MHz)

OSCTUNEbits.TUN = 0b011111; // Maximum frequency (31)

OSCTUNEbits.TUN = 0b100000; // Minimum frequency (-32, two's complement)

66.3 MHz 62 MHz

Come è possibile vedere il periodo diventa 362 ns (oppure 387 ns), che corrisponde rispettivamente ad una frequenza di clock di circa 66 (oppure 62 MHz).

Generatore di clock al quarzo

Spesso è necessario utilizzare riferimenti temporali migliori di quelli disponibili internamente. Per questo vengono inseriti elementi risonati meccanici posti esternamente al circuito integrato. Tipicamente si utilizzano cristalli di quarzo oppure, in situazioni meno critiche, risuonatori ceramici.

Lo schema elettrico presente sui fogli tecnici è riportato qui sotto. In genere, per i quarzi a frequenza elevata, non è necessaria la resistenza Rs ed occorre impostare l'oscillatore primario in modalità HS; il valore dei due condensatori (decine di pF) andrebbe scelto dopo collaudi approfonditi, in varie condizioni di temperatura ed alimentazione.

Accanto una realizzazione su breadboard, con un PIC18F14K50. Osservazione 3. La fotografia di apertura è una realizzazione più convenzionale, dove sopra al quarzo, sono visibili i due condensatori C9 e C10.

Schema di un generatore di clock quarzato Un generatore di clock al quarzo realizzato su breadboard

La gestione del quarzo fatta attraverso i configuration bits è semplice:

  1. Occorre innanzitutto attivare l'oscillatore adatto al quarzo, in genere per i quarzi ad alta frequenza è di tipo HS:
    #pragma config FOSC = HS
  2. Occorre quindi attivare il PLL. Infatti in genere si preferisce non utilizzare quarzi a frequenza troppo elevata, per non creare eccessive problematiche EMI: valori tipici sono compresi tra 8 e 16 MHz, che permettono frequenze di clock comprese tra 32 e 64 MHz.
    #pragma config PLLEN = ON

 Osservazioni

  1. Leggendo i fogli tecnici le due istruzioni assembly BRA e BTG sono indicate rispettivamente con la durata di 2 e 1 cicli del segnale FSOC, a sua volta con frequenza pari ad un quarto di quella del clock. Da cui l'apparente discordanza.
  2. (osservazione per chi è abituato ad utilizzare strumentazione da laboratorio) Ci si potrebbe stupire del segnale mostrato particolarmente "pulito", senza ringing o riflessioni. Ed anche dei tempi di salita particolarmente elevati per una logica CMOS ad alta velocità. Questo è dovuto al fatto che il PIC18 all'accensione predispone tutte le porte per avere uno slew rate ridotto. Se per qualche ragione vi servono fronti veloci potete disattivare questa opzione, impostando esplicitamente il registro SLRCON (PORT Slew Rate Control):
    SLRCONbits.SLRC = 0; // Set slew at the standard rate
    In questo caso occorre prestare attenzione nella progettazione del circuito stampato, usando tecniche tipiche delle linee di trasmissione. Meglio in questo caso evitare di realizzare il circuito su breadboard. Aspettatevi inoltre problematiche EMI!
  3. La realizzazione su breadboard degli oscillatori quarzati è critica e richiede collegamenti estremamente brevi; a volte è necessario qualche tentativo per la scelta dei due condensatori


Data di creazione di questa pagina: marzo 2016
Ultima modifica: 25 aprile 2016


Licenza Creative Commons Attribuzione 4.0 Internazionale


Pagina principaleAccessibilitàNote legaliPosta elettronicaXHTML 1.0 StrictCSS 3

Vai in cima