iot

Partire da zero con un microcontrollore in alcuni casi può essere più veloce rispetto all'utilizzo di schede già predisposte per la sperimentazione come Arduino, Mbed-Nucleo ecc.. e aiuta ad acquisire le basi per una conoscenza approfondita della materia.

 pic1

In questo primo post vediamo come creare l'ambiente di lavoro, come scegliere il microcontrollore, come effettuare la prima configurazione hardware di base e come verificare che tutto sia funzionante facendo lampeggiare un led.

Scelta del microcontrollore

Non mi soffermo sui motivi che portano alla scelta di un determinato produttore di microcontrollori; supponiamo di dover utilizzare i microcontrollori della famiglia Microchip PIC. Per la scelta del micro più adatto vengono coinvolti diversi fattori, non ultimi il prezzo e la reperibilità. Rimanendo su motivazioni tecniche, per soddisfare le esigenze esposte nei successivi post abbiamo bisogno di:

  • Comunicare via RS232.
  • Comunicare via I2C.
  • Abbondante memoria dati e di programma.
  • Bassi consumi.
  • Elevato clock.

Microchip mette a disposizione un tool per la selezione del micro più adatto, si trova nella pagina microchip design center, da cui è possibile selezionare la voce "PIC MCU Search". Si accede a una pagina come quella esposta in figura nella quale si possono specificare dei filtri per selezionare i PIC più vicini alle proprie esigenze.

pic search

Con le caratteristiche sopra esposte è facile verificare la necessità di ricorrere a un chip della famiglia PIC18, in quanto PIC di famiglie inferiori non dispongono delle necessarie porte di comunicazione. Considerato anche il livello di reperibilità e prezzo ho selezionato il PIC18LF24K40/SP (le ultime due lettere indicano il tipo di package che nel caso specifico è SPDIP ovvero con i piedini necessari all'utilizzo in una breadboard, mentre la lettera L specifica il modello a bassa tensione da 1,8V a 3,6V).

Allestimento banco di prova

Sono necessari pochi componenti:

  • Una breadboard con cavetti.
  • Un alimentatore da 5VDC 500mA, oppure due pile stilo da 1,5V collegate in serie.
  • I componenti elencati nello schema.

Trovare l'ispirazione per effettuare i collegamenti elettrici necessari non è difficile, basta consultare il datasheet scaricabile dalla pagina del prodotto al capitolo "Guidelines for getting started". Nello schema elettrico lo stabilizzatore per ottenere 3,3V è necessario solo se si usa l'alimentatore da 5V altrimenti collegare direttamente la serie delle due pile stilo alla VDD del micro.

sch tut1b 

Il pin 1 è quello preposto al reset del micro. Sui circuiti di produzione va opportunamente filtrato per rendere il microcontrollore immune da eventuali disturbi elettrici ad esempio causati dall'accensione o lo spegnimento di un tubo ad incandescenza (il cosiddetto neon). Per il nostro scopo è sufficiente collegarlo all'alimentazione con una resistenza da 10K, in quanto è attivo basso.

Sui pin VDD e VSS è presente una capacità di bypass (sempre per eliminare eventuali disturbi). Per la messa in produzione un solo condensatore non basta, su questo argomento apriremo un capitolo apposito.

Sulla porta RB3 colleghiamo il led con la resistenza (470R), il tipo di collegamento suggerisce che lo accenderemo portando il valore della porta a zero.

Infine ci sono i collegamenti necessari alla programmazione del micro (ICSP); vediamo di seguito come avviene.

Programmazione PIC

Le più comuni schede di sviluppo hanno a bordo un chip destinato alla programmazione del micro, partendo dal solo microcontrollore è necessario procurarsi un programmatore esterno. Per i PIC il mercato offre programmatori per tutte le tasche, da progetti open source che ti permettono di costruirtelo, a programmatori forniti dalla stessa Microchip al costo di circa 50€ fino a quelli più performanti per cui occorre spendere qualche centinaio di euro.

Io utilizzo MPLAB ICD3 che permette di scaricare sul microcontrollore tramite un'apposita applicazione (IPE), oppure direttamente dall'IDE di sviluppo (MPLABX) il file .hex generato dal compilatore.

Qualunque sia il programmatore utilizzato è necessario identificare i pin per poterli collegare opportunamente sulla breadboard. Utilizzando ICD3 la disposizione dei pin sul cavetto di collegamento (RJ11) è la seguente: 

RJ11 ICD3

Sarebbe il caso di verificare la comunicazione con il micro utilizzando il tool di programmazione. Utilizzando IPE si ha la possibilità di vedere se il programmatore riconosce il microcontrollore effettuando una connessione e verificando l'id del dispositivo. E' sufficiente selezionare il modello di microcontrollore ed effettuare la connessione.

Scrittura del programma

Per lo svolgimento di questo progetto utilizzerò il compilatore Microchip MPLAB-XC e l'ambiente di sviluppo MPLAB-X-IDE, sono scaricabili gratuitamente. E' anche possibile utilizzare l'ambiente di sviluppo cloud MPLAB Xpress che permette di evitare di scaricare e installare ide e compilatore. Tramite la registrazione è possibile disporre di un ambiente di sviluppo remoto che conserva i codici sviluppati e li rende accessibili da qualsiasi postazione.

Non mi addentro nelle procedure di installazione in quanto sono procedimenti praticamenti automatici. L'unica cosa che mi sento di suggerire è l'installazione di MPLAB Code Configurator che in questa fase iniziale permette di raggiungere immediatamente lo scopo sviluppando un codice professionale e dando una traccia utile per strutturare il programma. Questo programma viene installato come plugin di MPLAB-X-IDE (tools -> plugins-> available plugins -> install).

Cominciamo con un pizzico di teoria. Normalmente il lampeggio del led per un microcontrollore corrisponde al programma "Hello World" per un linguaggio di programmazione. Paradossalmente tutte le volte che viene divulgato questo primo passo viene fatto uso della funzione delay() nel loop principale per determinare il tempo di accensione e spegnimento del led. Niente di più diseducativo. Se c'è un principio fondamentale da tatuarsi addosso è quello che il microcontrollore non può disperdere le sue limitate risorse per contare le pecore mentre un led rimane acceso. Per chi è vecchio come me è un po' come tornare ai tempi di MS-DOS in cui si bloccava un intero computer per formattare un dischetto.

Ci sono quattro modi per far lampeggiare un led:

  1. Utilizzare il delay() all'interno del loop principale (diseducativo, già detto). 
  2. Utilizzare il watchdog; ma sarebbe più diseducativo del delay().
  3. Contare i cicli del programma e al raggiungimento di un determinato numero invertire lo stato della porta.
  4. Fare uso di timer ed eventualmente anche di interrupt.

La terza opzione lascia libere le risorse del micro mentre il led soggiorna in uno dei due stati per cui è una pratica consigliabile, ma la quarta opzione fa uso di uno dei sette timer di cui è fornito il PIC18LF24K40 e ci permette di sfruttare in modo proprio l'hardware che abbiamo a disposizione.

Per approfondire l'argomento ci giunge in aiuto il datasheet che va sempre considerato come unica fonte di informazione. Prima di decidere come impostare il timer occorre decidere a quale frequenza facciamo girare il micro: muoviamo i primi passi con il tool MCC.

Utilizzando l'IDE creiamo un nuovo progetto vuoto: New project -> Microchip Embedded -> Standalone Project

Schermata 2017 11 24 alle 15.59.00 Schermata 2017 11 24 alle 15.59.41 Schermata 2017 11 24 alle 16.00.18 

Disponiamo adesso di un progetto vuoto. Selezioniamo l'icona MCC e attendiamo qualche istante fino all'apertura della seguente finestra:

Schermata 2017 11 24 alle 16.04.20

Questa è una conquista abbastanza recente che ci permette, attraverso una interfaccia grafica, di impostare le periferiche del micro senza addentrarci nell'inizializzazione dei registri.

La finestra centrale ci accoglie con un promettente tab dalla dicitura "Easy Setup", utilizziamola impostando l'oscillatore selezionato su HFINTOSC 64MHz (ovvero oscillatore ad alta frequenza interno). Adesso conosciamo la velocità del cuore del nostro micro.

Schermata 2017 11 24 alle 16.40.47

Sotto la finestra centrale, dove c'è l'elenco dei pin impostiamo il Package su PDIP28. Il nostro led è collegato alla porta RB3, clicchiamo sul lucchetto all'intersezione della riga GPIO output con la colonna Port B 3 in questo modo viene opportunamente configurato il registro per far agire il pin della porta come un'uscita.

Schermata 2017 11 24 alle 16.41.01

Se clicchiamo nel riquadro in alto a sinistra la voce "Pin module" possiamo vedere che nel tab "Easy Setup" viene raffigurata l'attuale impostazione del pin RB3. Siccome ci interessa l'uscita digitale del pin leviamo la spunta al box "Analog", inoltre siccome il nostro led è attivo basso all'avvio del programma affinchè il led sia inizialmente spento occorre mettere il segno di spunta all'opzione "Start High".

Schermata 2017 11 24 alle 16.36.17 

Adesso è la volta del timer. Dal riquadro a sinistra "Device Resources" scorriamo fino all'opzione "timer" apriamo il menù a discesa e clicchiamo due volte su TMR0.

Nel tab "Easy Setup" dalla list box "Clock Source" è possibile scegliere tra varie sorgenti il clock che darà il tempo al timer. Escludendo le ultime tre opzioni, che sono clock esterni, possiamo scegliere tra High Precision Internal Oscillator, Low Power Internal Oscillator e FOSC/4 che è 1/4 della frequenza di sistema. Selezionando quest'ultima, considerato che la frequenza di sistema è 64MHz il timer incrementerà il proprio valore con una frequenza di 16MHz ovvero ogni 62,5 nsec. Non utilizzeremo un interrupt per verificare quando il timer scade, c'è un modo più semplice: il timer0, se è impostato a 16bit,  setta il flag T0IF a uno tutte le volte che raggiunge il valore 0xFFFF; questo vuol dire che il timer va in overflow ogni  

62,5e-9 x 65535 = 4msec (circa).

Se vogliamo far lampeggiare il led ogni secondo dobbiamo utilizzare il prescaler o il postscaler per dividere la frequenza di lavoro del timer. Scriviamo a mano il valore "1s" nel campo "Requested Period" (vedremo il significato di questo parametro nel prossimo post) poi impostiamo i valori come in figura.

Schermata 2017 11 25 alle 17.21.00

In alto a sinistra c'è il bottone "Generate" premendo il quale otterremo la generazione dei files di configurazione necessari a impostare il micro come da nostre scelte. Premiamo l'icona MCC per chiudere il plugin, l'elenco dei files generati compare in figura. E' stato anche creato il file main.c.

Schermata 2017 11 25 alle 17.27.01

Vedremo nel corso dei prossimi tutorial di comprendere i vari files. Al momento ci interessa sapere che MCC ha creato per noi nel file tmr0.c la funzione TMR0_HasOverflowOccurred() per verificare se il timer ha raggiunto il valore massimo, inoltre nel file pin_manager.c abbiamo la macro/funzione IO_RB3_Toggle() che ci permette di pilotare il led.

Aggiungiamo nel loop principale del programma (main.c) le istruzioni per verificare l'avvenuto overflow del timer e per cambiare di stato la porta RB3 su cui è collegato il LED; possiamo vedere che una volta configurato il PIC il programma principale è di sole tre righe.

Schermata 2017 11 25 alle 17.40.11

Non resta che compilare e scaricare il programma sul PIC per avere il LED che cambia di stato una volta al secondo.

download project