Corso programmazione PICMicro in C – Approfondimenti – Clock e UART su PIC12F1822 e 12F1840
I PIC12F1822 e PIC12F1840 sono due dei nuovi “piccoli” nati in famiglia Microchip. Hanno solo 8 pin ma sono dotati di alcune caratteristiche avanzate presenti anche sui PIC a 16bit. Questi due pic sono equivalenti, l’unica differenza tra i due è che il 1840 ha un quantitativo doppio di memoria (7Kb di memoria programma contro i 3.5Kb del 18F22 e 256B di RAM contro i 128 del fratello minore. Entrambi hanno 256B di eeprom dati).
Il PIC12F1822 e il PIC12F1840 fin’ora sono i soli della famiglia 12F ad avere sia l’UART (che nella fattispecie è una EUSART) che il modulo MSSP (SPI,I2C) insieme a tante altre caratteristiche tra cui un oscillatore interno capace di andare fino a 32MHz sfruttando un PLL. In questo post do quindi qualche appunto utile per aiutarvi nel settaggio del clock e nell’utilizzo dell’UART. Dato che i settaggi sono parecchi… incominciamo subito!
Indice dei contenuti
Il Clock del PIC12F1822/40
Diamo innanzitutto uno sguardo allo schema del clock, che potete trovare sul datasheet:
Abbiamo la possibilità di sfruttare svariate sorgenti di clock: una sorgente esterna (quarzo o oscillatore) da collegare ai pin OSC1/OSC2, l’oscillatore esterno a bassa potenza, normalmente utilizzato per il Timer1 ma utilizzabile anche per la CPU, e il blocco oscillatore interno che ha 2 moduli separati: uno a 500KHz e uno a 31KHz (Oscillatore interno a bassa frequenza, LFINTOSC). Quello a bassa frequenza è utile per sfruttare la funzione Two-Speed start-up: ovvero avviare la CPU con l’oscillatore a bassa frequenza, aspettare che quello ad alta frequenza si stabilizzi e quindi passare a questo. Questo oscillatore si può anche usare in caso di malfunzionamento dell’oscillatore principale (Fail-Safe), ma anche come oscillatore primario e quindi avere consumi molto ridotti, funzione utile nei sistemi a batteria.
La sorgente a 500KHz (oscillatore interno a media frequenza, MFINTOSC) viene inviata tal quale ad un postscaler con numerose uscite; tramite un multiplexer selezioniamo la sola uscita con la frequenza che ci interessa. L’oscillatore a media frequenza ha anche un modulo PLL interno che porta la frequenza a 16MHz (oscillatore interno ad alta frequenza, HFINTOSC). Anche questa frequenza viene inviata allo stesso postscaler. L’uscita del multiplexer associato al postscaler viene quindi inviata ad un secondo multiplexer tramite il quale possiamo eseguire lo switching tra le varie sorgenti di clock ed alimentare infine la CPU.
La sola frequenza di 8MHz, ottenuta dall’oscillatore HFINTOSC, può essere usata tal quale o inviata ad un PLL che la moltiplica per 4, fornendoci un clock interno di 32MHz. Il PLL 4x ha anch’esso un piccolo multiplexer per poter ricevere in ingresso eventualmente anche il clock esterno.
Una prima selezione del clock viene eseguita nella (nelle) word di configurazione:
Il bit FCMEN (Fail-safe Clock Monitor Enable) consente di abilitare (1, default) o disabilitare (0) la funzione di Fail-Safe: se l’oscillatore primario si guasta si passa all’oscillatore secondario a bassa potenza.
Il bit CLKOUTEN (Clock OUT Enable – è un bit negato) messo a zero consente di avere sul pin n°3 (RA4) un clock in uscita pari a FOSC/4, messo a 1 consente di utilizzare RA4 come normale I/O. Questo bit viene ignorato se la selezione prevede di utilizzare un quarzo esterno (il quale ovviamente deve utilizzare entrambi i pin). Il bit CLKOUTEN è da tenere in seria considerazione nel caso in cui avete problemi di settaggio del clock: abilitando questa funzione con un oscilloscopio potete controllare la frequenza ed essere sicuri di aver settato il clock in maniera corretta. Basta ricordarsi che la frequenza in uscita da tale pin è quella di sistema divisa per 4, per cui se avete impostato il clock a 32MHz, da qui deve venire fuori un’onda (pressappoco) quadra a 8MHz.
I 3 bit FOSC (Oscillator Frequency selection) consentono il settaggio dell’oscillatore primario:
Per usare l’oscillatore interno utilizzeremo l’impostazione 100. In questo modo il pin n°2 (RA5) può essere usato come normale I/O.
Della configuration word 2, per quanto riguarda la questione del clock, ci interessa unicamente il bit 8, PLLEN, che posto a 1 consente di attivare il PLL. Il settaggio del PLL nella config word non è indispensabile in quanto può essere settato a mano anche nel registro OSCCON. La differenza che c’è nel settarlo da una o dall’altra parte è questa: se lo settiamo nella config word, poi il PLL non può più essere disattivato, per cui la CPU girerà sempre al massimo.
Rispondo prima della domandina: ovvio che non rimane attivato “per sempre”: lo potete disattivare con la successiva riprogrammazione!
Se invece tale bit si pone a zero, il PLL può essere attivato/disattivato via software, questa è una buona scelta nei casi in cui stiamo progettando un’applicazione che deve anche avere un occhio ai consumi e vogliamo passare da una modalità all’altra per ottimizzare consumi e prestazioni.
La configurazione per il clock ovviamente non si ferma alla config word, bisogna anche impostare il registro OSCCON:
Il bit 7, SPLLEN (Software PLL ENable) è il bit di cui vi parlavo prima che consente di abilitare/disabilitare il PLL via software. Il funzionamento di questo bit è ininfluente se si è settato PLLEN nella word di configurazione.
I bit IRCF (Internal oscillator Frequency select) permettono di agire sul primo multiplexer e quindi selezionare la frequenza in uscita dal postscaler associato al modulo oscillatore interno:
Vedete che tra queste selezioni ce ne sono alcune duplicate (ad esempio 125KHz compare due volte) questo perchè nel postscaler ci entrano sia l’MFINTOSC (500KHz) direttamente che l’HFINTOSC (16MHz), per cui è ovvio che dividendo i 16MHz si ottengono alcune frequenze già fornite anche dai 500KHz. Vediamo che la prima selezione è quella che consente il consumo più basso: viene utilizzato l’oscillatore interno a bassa frequenza. La selezione 1110 ci consente di avere in uscita 8MHz e quindi, se abbiamo abilitato il PLL, 32MHz.
I bits SCS (System Clock Select) anche sono importanti e consentono di eseguire un’ulteriore selezione anche a runtime:
Impostando a 00 questi bit, la selezione del clock viene eseguita in base a quanto abbiamo specificato nella config word, altrimenti è possibile cambiare questa impostazione anche con il programma in corso e scegliere l’oscillatore esterno dedicato al timer1 oppure il blocco oscillatore interno.
Il registro OSCSTAT (OSCillator STATus) ci permette di sapere in che stato si trova l’oscillatore e soprattutto se è stabile e il PLL si è agganciato. é necessario controllare i bit in questo registro e rimanere in attesa fino a che tutto non è a posto prima di iniziare il programma principale.
Nel file allegato in fondo all’articolo è disponibile il sorgente con un esempio di settaggio per utilizzare l’oscillatore interno a 32MHz.
L’UART
Il modulo UART a disposizione su questi due pic12F è un modulo EUSART, ha in pratica alcune caratteristiche avanzate. La prima caratteristica, che potrebbe sembrare un po’ assurda su un pic che ha soltanto 6 I/O è la possibilità di scegliere i pin da utilizzare per le funzioni RX e TX del modulo. In questo pic è presente difatti il registro APFCON (Alternate Pin Function Control Register) che consente di direzionare alcuni moduli su pin alternativi. Non è la funzione PPS che abbiamo sui PIC24F. Questa è molto più semplice:
Il bit 7 (RXDTSEL) ci permette di avere la funzione RX sul pin RA1 (bit a zero, impostazione di default) o sul pin RA5 (bit posto a 1).
Il bit 2 (TXCKSEL) ci permette di avere la funzione TX sul pin RA0 (bit a zero, impostazione di default) o sul pin RA4 (bit posto a 1).
In apparenza può sembrare inutile, ma mettete il caso che con un pic12F volete comunicare con due circuiti RS232? Non in contemporanea ovviamente.
Il modulo EUSART ci consente anche di selezionare una modalità Autobaud, che calcola in automatico il baudrate a seconda del dispositivo a cui si è collegati e di avere un baudrate generator a 16bit che ci consente di avere una scelta più ampia. Il registro del baudrate generator è a 16bit per cui abbiamo una parte alta (SPBRGH) e una parte bassa (SPBRGL). La formula per il calcolo del valore da assegnare al baud rate generator è diversa a seconda se sia scelta una modalità asincrona, un baud rate elevato e/o a 16bit. A partire da pag. 299 del datasheet ci sono tutte le tabelle in cui recuperare i valori e gli errori relativi.
Nel mio esempio utilizzo una normale UART asincrona (SYNC=0), il baudrate generator impostato per lavorare ad 8 bit (BRG16=0) e a velocità elevata (BRGH=1) per cui faccio riferimento a questa tabella:
Vedo che utilizzando l’oscillatore a 32MHz, per avere un baudrate di 9600bps, devo impostare il baudrate generator al valore 207. Per cui utilizzerò soltanto la parte bassa del registro (SPBRGL=207) mentre la parte alta la metto a zero (SPBRGH=0). In questo caso il baudrate generato ha un errore accettabile e non avrò giusto 9600bps bensì 9615bps.
Altra cosa importante da ricordare è quella di disattivare gli ingressi analogici sui pin da utilizzare per l’UART. Su questo pic basta agire nel registro ANSELA. La libreria allegata all’esempio comunque fa tutto da sola e disattiva la funzione analogica unicamente sui pin scelti per la comunicazione, lasciando inalterati gli altri.
Misurare il baudrate
Per sfizio ho voluto fare una prova con l’oscilloscopio misurando il baudrate ottenuto. Se volete provarci anche voi: basta misurarsi il tempo in cui viene inviato un singolo bit (usando la funzione “Cursor” su molti oscilloscopi):
Vediamo che un singolo bit viene inviato in un tempo di 104μS. In un secondo vengono quindi inviati (1/104μS) = 9615 bit! Mi meraviglio di tanta precisione!
Unsupported Part ?!
Se usate il Pickit2 potrebbe accadere che con questo pic, così come con gli ultimi nati, vi appaia il messaggio unsupported part:
Non dovete buttare il pickit2 per acquistare il 3! Basta andare sulla pagina ufficiale del pickit2 e scaricare il nuovo device file.
Ammetto, in questo caso, che abbiate già l’ultima versione del software/firmware del pickit2.
Scompattando questo archivio viene fuori un file .dat, copiatelo nella cartella dove è installato il software del pickit
C:\Program Files\Microchip\PICkit 2 v2 |
Cancellate il vecchio file:
PK2DeviceFile.dat |
e rinominate il nuovo come PK2DeviceFile.dat.
Adesso il solito pirla di turno piazzerà un bel tutorial su un altro sito per beccarsi un paio di punti. Magari prima o poi qualcuno i punti glieli da sulla testa.
Se avevate già fatto partire il programma del pickit, chiudetelo e riapritelo, la stessa cosa vale per MPLAB.
Download esempio + Libreria UART per pic12F1822/40
Il sorgente in allegato è un esempio di come impostare l’oscillatore interno a 32MHz e di come usare l’UART a 57600bps. La word di configurazione è impostata per avere MCLR “libero” e quindi usabile come normale ingresso, per cui non è necessario mettere la resistenza di pullup. Sfruttando l’oscillatore interno abbiamo a disposizione 6 I/O e il circuito è semplificato al massimo: dobbiamo solo ricordarci di mettere un condensatore da 100nF tra VDD e VSS. L’UART è impostata di default per utilizzare RA5 come RX e RA4 come TX.
NON RIDISTRIBUITE LA LIBRERIA/GLI ESEMPI ALTRIMENTI QUESTA E’ L’ULTIMA COSA CHE PUBBLICO SUI PIC! Le cose che “trovate su internet” non le state trovando in mezzo alla strada! Le ha fatte qualcuno, e se quel qualcuno esprime una volontà, bisogna rispettarla!
Eventualmente volete cambiare qualche impostazione della UART, il file da modificare è usart12f.h, alle righe:
26 27 28 29 30 31 | // comment this define if you want TX on RA0, leave uncommented for RA4 #define USE_TX_ALT // comment this define if you want RX on RA1, leave uncommented for RA5 #define USE_RX_ALT // baudrate #define BAUDRATE 57600 |
Penso che i commenti non abbiano bisogno di spiegazioni. Per usare questa libreria, che ho scritto appositamente per questo pic12F, è necessario che definiate nel main la macro _XTAL_FREQ come illustrato nel programma di esempio, questo sia per eseguire il calcolo del valore da assegnare al registro SPBRG sia per poter sfruttare le routine di ritardo incorporate nell’Hitech-C. Ho difatti notato che dopo aver eseguito tutte le impostazioni, non è sufficiente attendere la stabilizzazione dell’oscillatore ma bisogna dare un ulteriore ritardo di almeno 2mS prima di riuscire ad utilizzare l’UART correttamente. Le annotazioni nella libreria le ho scritte in inglese, non penso sia un problema.
Per il calcolo di SPBRG utilizzo la formula fornita dal datasheet ma per alcuni baudrate il valore restituito non è ottimale. Per un baudrate di 9600bps, ad esempio, il valore restituito dalla formula del datasheet è 208 mentre sarebbe più corretto il valore 207, come è anche illustrato dalle tabelle, in quanto fornisce un errore minore, mentre per altri baudrate, come ad esempio 57600bps, il valore è corretto. Eventualmente cambiate a mano i valori da assegnare a SPBRG nella funzione uart_init, bypassando il calcolo.
Esempio utilizzo UART su PIC12F1822 (776 download)