Tips & Tricks - PIC

 

PIC16F18313 - Gli oscillatori interni


PIC16F313 è un microcontroller abbastanza recente e piuttosto nominato in rete. E', dotato di numerose funzioni, tipiche degli Enhanced, a cui si aggiunge una struttura del modulo oscillatore originale, comune ad altri PIC della serie 16F183xx (16F18 323/324/325/326 a 14 pin e /344/345/346 a 20 pin). 
Un modulo oscillatore analogo è presente anche su altri Enhanced del gruppo 16F18xxx.

Le opzioni del modulo oscillatore rendono complesso districarsi nei datasheet che occupano ormai 500 e più pagine. Una possibilità offerta da MPLABX è quella di usare  il Configurator MCC che facilita il lavoro. In ogni caso, per sfruttare appieno il componente è indispensabile avere una chiara idea delle funzioni dei vari parametri e registri, dato che MCC fornisce  soluzioni, ma senza particolari spiegazioni. Nè, peraltro, il foglio dati è sempre sufficientemente chiaro alla prima lettura.

Per chi ha in mano il componente per la prima volta, dunque, alcuni aspetti possono non essere di immediata comprensione. 

Si può dire che in questi Enhanced è particolarmente curato il modulo oscillatore per semplificare il cambio del clock durante l'esecuzione del programma (Clock Switching), l'avvio con doppio clock, generazione di frequenze diverse, ecc..  
Sono implementabili numerose modalità di sorgenti oscillatore esterne e tre sorgenti interne, tutte dotate di PLL e divisori, definibili in configurazione iniziale.
Tutto questo a scapito di una complicazione maggiore rispetto al modulo clock a cui ci hanno abituati i Midrange non-Enhanced.

Vediamo di capire qualcosa di più su questo modulo oscillatore, puntando essenzialmente alle modalità di clock interno, che solitamente sono quelle che per prime andiamo a sperimentare. Le modalità di clock esterno sono trattate in altre pagine.

La via migliore per comprendere il modulo oscillatore è quella di tenere presente il diagramma a blocchi.

Per prima cosa osserviamo che il modulo è composto da tre parti, da sinistra a destra :

  1. blocco degli oscillatori veri e propri, in cui sono presenti due oscillatori esterni (EXTOSC e SOSC) e due oscillatori interni (LFINTOSC e HFINTOSC).
    Gli oscillatori esterni impiegano almeno un pin (o due) e il progettista ha stabilito che al default ci sia un pin (OSC1) con la funzione CLKIN, cosa non comune nei PIC più datati e causa di problemi inaspettati. Nelle modalità con cristallo, i pin impiegati sono due e quindi di default c'è anche il conosciuto CLKOUT, sul pin OSC2. Il segnale CLKOUT è, come solito, la frequenza Fosc/4.

  2. blocco del multiplex. Troviamo qui anche due PLL con rapporto fisso, che possono moltiplicare x4 il clock esterno e x2 quello interno. Il multiplex permette di selezionare quale clock passa al blocco successivo, mentre alcune sorgenti sono inviate alle periferiche.

  3. blocco divisore: il clock scelto dal multiplex viene passato ad un divisore programmabile da 1/1 a 1/512. L'uscita del divisore è condizionata dalla modalità sleep.

Possiamo considerare anche la presenza del moduli FSC (Fail Safe Clock Monitor) che è alimentato dal LFINTOSC a 31kHz e controlla la presenza del clock all'uscita del multiplex. Da osservare che FSC è attivo per oscillatori interni.

Dunque, va tenuto presente che la programmazione del primo blocco è effettuata nella configurazione iniziale.
Qui abbiamo due opzioni per la scelta dell'oscillatore:

  • Il paramentro RSTOSC seleziona la sorgente del clock

Le scelte possibili con RSTOSC sono:

  • _RSTOSC_HFINT32  seleziona HFINTOSC 2x PLL (32MHz)

  • _RSTOSC_EXT4X    seleziona EXTOSC con 4x PLL

  • _RSTOSC_SOSC     seleziona SOSC esterno (31kHz)

  • _RSTOSC_LFINT    seleziona LFINTOSC (31kHz)

  • _RSTOSC_HFINT1   seleziona HFINTOSC (1MHz)

  • _RSTOSC_EXT1X    seleziona EXTOSC 

oscillatori interni   oscillatori esterni

EXT4X e EXT1X sono condizionati dalla selezione effettuata con FEXTOSC
Questo parametro riguarda solo gli oscillatori esterni:

  • _FEXTOSC_LP  LP oscillatore a cristallo 32.768 kHz

  • _FEXTOSC_XT  XT oscillatore a cristallo 100kHz-4 MHz

  • _FEXTOSC_HS  HS oscillatore a cristallo oltre 4 MHz

  • _FEXTOSC_OFF Oscillatore esterno non abilitato

  • _FEXTOSC_ECL EC clock esterno fino a 100 kHz

  • _FEXTOSC_ECM EC clock esterno da 100 kHz a 8 MHz

  • _FEXTOSC_ECH EC clock esterno oltre 8 MHz

esclude oscillatore esterno e libera RA4

In più, troviamo il bit _CSWEN_(ON/OFF) di sicurezza che impedisce o permette la modifica dei bit del registro OSCCON1 durante il funzionamento del programma. Il bit è normalmente ON permettendo la modifica; se  programmarlo OFF impedisce il cambio del clock durante il programma.

Come accennato prima,
il chip ha come scelte "Basis" , cioè di default della configurazione, anche i due bit:

  • _CLKOUTEN_(ON/OFF) che abilita o meno l'uscita del clock FOSC/4 il che occupa un pin (RA4). Questa opzione è comune ad altri PIC.

  • _FEXTOSC_(ON/OFF) che abilita l'oscillatore esterno e occupa il pin di ingresso (RA5). Questa opzione è meno comune e si deve prestare attenzione se si vuole usare RA5 come I/O

Come nota essenziale, se non desiderate oscillatore esterno, ma il libero uso dei pin relativi (RA4 e RA5), dovete inserire obbligatoriamente nel config CLKOUTEN=OFF e FEXTOSC=OFF.

Dunque, queste selezioni effettuate nel config hanno valore per tutto il programma successivo. 

Riassumendo, nel config, queste sono le azioni necessarie nel config per ottenere l'oscillatore interno e tutti i pin liberi:

#pragma config RSTOSC=LFINT   // LFINTOSC (31kHz)
oppure
#pragma config RSTOSC=HFINT1  // HFINTOSC (1MHz)
oppure
#pragma config RSTOSC=HFINT32  // HFINTOSC (32MHz)

#pragma config  FEXTOSC=OFF   // libera RA5 - no clockin
#pragma config  CLKOUTEN=OFF  // libera RA4 - no clockout

La scelta di_RSTOSC tra le tre disponibili viene chiarita più avanti.

Come dichiarato all'inizio, non trattiamo qui le specifiche degli oscillatori esterni, che sono simili a quelle generali dei PIC, a partire da quelli più "antichi"e possono essere facilmente comprese dal foglio dati. Vediamo invece gli oscillatori interni.

Al blocco degli oscillatori fa seguito il multiplex che va gestito da programma, attraverso i bit COSC<2:0> del registro OSCCON1.

  • L'oscillatore LFINTOSC, calibrato in produzione, produce esclusivamente la frequenza di 31kHz. Viene selezionato da COSC=0b100. Non dispone di PLL.

  • L'oscillatore HFINTOSC è anch'esso calibrato in produzione. Dispone di un PLL x2, selezionabile dal multiplex. E' diviso in due sezioni e produce da 1 a 32MHz; la frequenza dipende dai bit HFFRQ<3:0>, che si trovano nel registro OSCFRQ .



Combinando HFFRQ e COSC si possono selezionare diverse frequenze a seconda che si parta da HFINT1 o HFINT32.

Vediamo che HFFRQ consente di scegliere un clock a 1, 2, 4, 8, 12, 16, 32MHz se è stato selezionato HFINT1. Se è selezionato HFINT32, si possono scegliere le frequenze di 16, 24, 32MHz.
Da osservare che il valore di default per HFFRQ è 0110 , ovvero 16MHz, frequenza possibile sia con HFINT1 che con HFINT32.

Per riassumere:

  • l'oscillatore interno è selezionato dal config iniziale

  • LFINT genera 31kHz fissi.

  • HFINT1 e HFINT32  generano le frequenze viste sopra, agendo nel programma sul registro OSCFRQ e OSCCON1  

Il multiplex, comandato dai bit COSC<2:0> di OSCCON1 permette 8 selezioni.
Osserviamo dallo schema iniziale che i due HFINT possono essere selezionati anche con un PLL x2.

L'ultimo blocco è il Postscaler Divider, con fattori da 1 a 512, comandato dai bit CDIV<4:0>.

I segnale del clock, prelevato da diversi punti, alimenta le periferiche e, in uscita, è condizionato dalla modalità sleep. 

Multiplexer e Divider sono gestiti da registri interni che vanno modificati dal programma.
Essenzialmente si tratta del registro OSCFRQ visto sopra, e del registro OSCON1

 

nel quale troviamo i bit NOSC<2:0> (New Oscillator Sources) e NDIV<3:0> (New Divider) che permettono lo switch fra le diverse sorgenti di clock

Il PLL x2 opera solo con le frequenze 8, 12,16 per generare i valori di HFINT32.

I bit NOSC<2:0>  selezionano la sorgente; abbiamo, per l'oscillatore interno, le scelte LFINT, HFINT1 e HFINT32
Da notare che inizialmente, (per default)  NOSC è uguale a RSTOSC della configurazione. Questo semplifica un po' le cose.
Le altre 4 opzioni riguardano clock esterno.

I bit NDIV<3:0> selezionano il fattore di divisione, secondo la table 7.2 qui sopra.

Si può pensare che la presenza di tutti questi registri e opzioni non aiuta certamente a dipanare l'intricata matassa degli oscillatori, ma la situazione non è poi così tragica; vediamo di chiarire attraverso alcuni esempi.

Prima consideriamo lo stato di default dei bit di configurazione al POR.

  1. CSWEN è a 1, abilitando la modifica del clock da programma. Se non la desideriamo dobbiamo portare il bit a 0:
    #pragma config CSWEN = OFF

    Attenzione che con CSWEN disabilitato non c'è la possibilità di commutare la frequenza del clock durante l'esecuzione del programma.

  2. RSTOSC è al default 0x111, ovvero seleziona l'oscillatore esterno EXT1X. Per usare un oscillatore interno si rende necessario impostare 0x110 (HFINTOSC1) oppure 0x100 LFINTOSC oppure 0x000 HFINTOSC32
    #pragma config RSTOSC = HFINTOSC1/HFINTOSC32/LFINTOSC

  3. FEXTOSC è 0x111 che seleziona il modo ECH. Per escludere oscillatori esterni occorre modificare con 0x100 che disabilita gli oscillatori esterni.
    #pragma config FEXTOSC = OFF

  4. CLOCKOUTEN è, stranamente a 1, disabilitando l'uscita del clock. Se vogliamo l'uscita occorre portarlo a 0.
    #pragma config CLKOUTEN = ON

  5. FCMEM è a 1, abilitando il fail safe monitor. Se non interessa:
    #pragma config FCMEM = OFF

impostazione utile  impostazione indispensabile

Per i registri interessati al clock i default sono:

  1. OSCCON1=0b0qqq 0000. Da notare che NOSC è uguale a RSTOSC in configurazione. Quindi, se, ad esempio, è stato scelto RSTOSC=HFINT1 nel config, sarà automaticamente NOSC=0b110  
    NDIV
    seleziona al default il divisore 1/1. Occorre modificarlo se serve un diverso valore.

  2. OSCFRQ=0b0000 0110, ovvero HFFRQ seleziona 16MHz, possibile sia con HFINT1  che con HFINT32 . Occorre modificarlo se serve un diverso valore.

Vediamo alcuni esempi:

Per avere al default un clock a 31KHz:

#pragma config RSTOSC = LFINTOSC
// NOSC = 0b100 per LFINTOSC, NDIV=0b0000 per div. 1/1
// OSCCON1=0b01000000;    // LFINT 1/1 
 

Non serve modificare nessun registro perchè:
- OSCCON1
per default seleziona LFINT1 e un divisore 1/1


Per avere al default un clock di 1MHz, con i pin OSC1/2 liberi:

#pragma config FEXTOSC = OFF, RSTOSC = HFINT1 
#pragma config CLKOUTEN = OFF, CSWEN = ON

Non serve modificare nessun registro perchè:
- OSFRQ per default seleziona una frequenza di 16MHz
- OSCCON1
per default seleziona HFINT1 e un divisore 1/16


Per modificare la scelta precedente a 
4MHz.

OSCFRQ=0b00000110;       // HFFRQ=0b110  per 16MHz
// NOSC=0b110 per HFINT1, NDIV=0b0010 divisore 1/4
OSCCON1 = 0b01100010;    // HFINT1 div. 1/4 

oppure

OSCCON1bits.NOSC = 0b110; // HFINT1
OSCCON1bits.NDIV = 0b0000; // Div. 1/1
OSCFRQbits.HFFRQ = 0b0111; // = 4 MHz


Se vogliamo un clock a 32MHz basterà nel config:

#pragma config FEXTOSC = OFF, RSTOSC = HFINT32 
#pragma config CLKOUTEN = OFF, CSWEN = ON

oppure

OSCCON1bits.NOSC = 0b000;  // HFINT32
OSCCON1bits.NDIV = 0b0000; // Div. 1/1
OSCFRQbits.HFFRQ = 0b0110; // 32 MHz 
OSCENbits.HFOEN = 1;       // HFINTOSC enabled 

 


Se vogliamo impostare il clock di default del sistema a
2MHz:

#pragma config RSTOSC = HFINT32
#pragma config CSWEN = ON


OSCFRQbits.HFFRQ = 0b0011;  // 8 MHz con 4 MHz x2
OSCCON1bits.NDIV = 0b0010;  // divisione è 1:4 FOSC=2MHz


Se vogliamo impostare il clock di sistema a 8MHz. 

#pragma config RSTOSC = HFINT32  
OSCFRQbits.HFFRQ = 0b0011;       // 8MHz con 4MHz x2

 


Quando stiamo lavorando con un clock e vogliamo passare ad un altro valore, basta agire sui registri interni.
Ad esempio, vogliamo passare a 8MHz da una qualsiasi altra frequenza:

OSCCON1bits.NOSC=0b110; // HFINT1

OSCCON1bits.NDIV=0;     // div. 1/1

OSCFRQ=0b011;           // 8MHz
 

Agendo sul divisore si potranno ottenere numerosi valori sottomultipli di un clock.


Una applicazione di test.

Occorre:

  •  un oscilloscopio o un frequenzimetro

  •  e un tools adeguato (SNAP, PICKIT4 o 5, ICD4 o 5, ICE4). 
    Con questi PIC non è più possibile utilizzare tools come PICKIT3.

  • si consiglia di aggiornare MPLABX all'ultima versione disponibile

Collegate lo strumento a OSC2 (RA4).
Collegate i pin ICSPDAT, ICSPCLK e MCLR ad un connettore adatto a ICSP/ICD
Scrivete un semplice sorgente e utilizzate il debug in circuit per lanciarlo e verificare i registri OSCCON1 e OSCFRQ

Esempio di sorgente per un clock di 32MHz:

/**********************************************************
prova clock 18313
*********************************************************/
PORTA
| RA5 |  RA4 |  RA3 | RA2 | RA1 | RA0 |
|-----|------|------|-----|-----|-----|
| -   |clkout| MCLR |  -  | CLK | DAT |

*********************************************************/
#include <xc.h>

#pragma config FEXTOSC = OFF    // FEXTOSC disable 
#pragma config RSTOSC = HFINT32 //  
#pragma config CLKOUTEN = ON    // CLKOUT Fosc/4 su RA4
#pragma config CSWEN = ON       // Clock Switch Enable
#pragma config MCLRE = ON       // MCLR/VPP 
#pragma config LVP = ON         // LVP on per SNAP

// *****************************************************
void main() {
asm ("NOP");                    // per debug


// OSCFRQ=0b00000110; // HFFRQ=0b110 per 16MHz
// NOSC=0b110 per HFINTOSC, NDIV=0b0010 per divisore 1/4
// OSCCON1 = 0b01100010; // HFINT1 1/4  

while(1);
}

  • Nel Config sono toccati solo i punti essenziali.
    La riga LVP=ON  va introdotta se utilizzate SNAP

  • asm ("NOP"); serve come punto di stop nel debug prima di eseguire eventuali linee di programma.

  • Le linee di programma qui sono commenti, ma possono essere inserite per modificare il clock di default.
    Se nessuna riga di programma è scritta, sul pin CLKOUT sarà visibile la frequenza di default prodotta dalla configurazione scelta.

  • Nella finestra di visione dei registri del debugger, si aggiungeranno quelli che si voglio monitorare, essenzialmente OSCFRQ e OSCCON1.

  • Se si modifica il default aggiungendo linee di istruzioni, si potrà aggiungere un breakpoint alla riga asm ("NOP"); in modo da poter analizzare i registri sia al default, sia dopo l'esecuzione delle istruzioni.

L'oscilloscopio o il frequenzimetro rileveranno su RA4  la frequenza Fosc/4.


E gli altri registri del clock?

Per inciso, ci si può chiedere perchè non si è parlato degli altri registri del modulo oscillatore.
La loro situazione è questa:

  • OSCCON2 è la replica in sola lettura di OSCCON1. Ha funzioni di verifica.

  • OSCCON3 è un registro di controllo e flag degli oscillatori.

  • OSCSTAT è un registro di flag di stato degli oscillatori

  • OSCEN riguarda le modalità di abilitazione degli oscillatori. 

  • OSCTUNE è il registro di modifica del clock

La loro situazione al default è tale da non creare problemi con la scelta dell'oscillatore e vanno manipolati solo nei casi in cu siano richieste specifiche prestazioni o controlli. Per questo, consultare il foglio dati, sezione 7, DS40001799E-page 66 e seguenti.

 



 

Copyright © afg . Tutti i diritti riservati.
Aggiornato il 11/04/24 .