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.
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
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.
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;
}
}
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)
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).
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.
La gestione del quarzo fatta attraverso i configuration bits è semplice:
Data di creazione di questa pagina: marzo 2016
Ultima modifica: 25 aprile 2016
PIC18 in C - Versione 0.991 - luglio 2019
Copyright 2014-2019, Vincenzo Villa (https://www.vincenzov.net)
PIC18 in C di Vincenzo Villa è distribuito con Licenza Creative Commons Attribuzione 4.0 Internazionale