PIC12F675

1° progetto con PIC12F675 led lampeggianti

Iniziamo con il primo progetto di una serie studiati per prendere confidenza con i PIC, capire come funzionano e cosa ci possiamo fare. Nel 1° progetto tutorial ho incominciato utilizzando un piccolo microcontrollore a 8 pin il PIC12F675. La scelta è ricaduta su questo microcontroller in quanto ne cercavo uno molto piccolo, che avesse pochi pin, che non avesse bisogno di quarzi esterni e che fosse molto economico. Di fatto ho trovato un offerta nel negozio online dove solitamente mi fornisco e visto il costo davvero abbordabile, parliamo di 1,20€ circa ho deciso di prenderne un set da 5.
La prima operazione da fare prima di iniziare è cercare sul sito della Microchip il datasheet del PIC e studiarselo: PIC12F629/675 Data Sheet.
La prima cosa che guarderemo sono le caratteristiche del PIC, studieremo il diagramma dei pin per vedere quali sono i Pin di alimentazione, quali i pin di programmazione e quali i pin che si possono usare come periferiche di input/output analogiche o digitali.
In teoria tutta questa serie di analisi dovrebbe essere fatta al momento dell’acquisto in quanto dovremmo aver già un idea del tipo di PIC che dobbiamo prendere per sapere quante periferiche libere avremo per il nostro progetto!
La cosa più importante è capire se è nostra intenzione programmare il PIC su zoccolo apposito con nulla attaccato o fare la programmazione con tutti i componenti del progetto collegati. La prima semplifica la programmazione in quanto collegati i PIN ci basta eseguire il caricamento del codice con il Programmatore senza temere che qualche componente (condensatore, resistenza o altro) possa creare errori. La seconda ha il vantaggio che una volta preparato il progetto non dovremo ogni volta staccare il PIC dalla scheda o dalla breadborad per aggiornarlo. Ottima soluzione se prevediamo frequenti aggiornamenti.
Semplifichiamoci le vita e per ora prepariamo i collegamenti per caricare il codice, quindi andremo a collegare i pin che ci serviranno per collegare nel mio caso il PicKit3!

Schema collegamento Programmatore PicKit3 con PIC12F675
Nello schema sopra è illustrato come collegare il PicKit3 al microcontrollore Pic12F675.
Per comodità il collegamento l’ho realizzato su una breadboard.
Ora dobbiamo scrivere il programma da caricare sul microcontrollore. Io ho utilizzato la suite della Microchip MPLAB X IDE usando il compilatore XC8.
A questo punto quindi creo un nuovo progetto e seguendo il wizard, imposto il PIC che programmeremo, il compilatore che useremo e che programmatore useremo. Verrà visualizzato nell’esplora risorse della suite le varie cartelle in cui vengono salvati i vari file che dovremmo creare.
La logica di programmazione del programma prevede che si creino dei file di risorsa, di configurazione di intestazione, di impostazione, ma non si è obbligati a farlo. In questo progetto creerò un file chiamato main.c. Sicuramente per progetti più complessi sarà una necessità ricorrere alla suddivisione in file del nostro codice.
Io purtroppo mi approccio per la prima volta al linguaggio di programmazione C e in particolare al XC8, quindi mi sono scaricato e studiato il documento informativo messo a disposizione dalla Microchip, lo trovate qui(PDF).
Vediamo insieme il programma in XC8:

//*****************************************************************************/
// DUE LED LAMPEGGIANTI
// www.mdn75.it
//
// modulo: main.c
// autore: MDN75
// data: 27/12/2012
// descrizione: Lanterne di fine convoglio lampeggianti
// picmicro: PIC12F675
// clock: interno a 4 MHz
//
//*****************************************************************************/

/******************************************************************************/
/* Files to Include */
/******************************************************************************/
#if defined(__XC)
 #include <xc.h> /* XC8 General Include File */
#elif defined(HI_TECH_C)
 #include <htc.h> /* HiTech General Include File */
#endif

#include <stdint.h> /* For uint8_t definition */
#include <stdbool.h> /* For true/false definition */
#include "system.h" /* System funct/params, like osc/peripheral config */
#include "user.h" /* User funct/params, such as InitApp */

/******************************************************************************/
/* Configurazione del PIC12F675 per il nostro programma! */
/******************************************************************************/
#pragma config MCLRE = OFF, CP = OFF, CPD = OFF, BOREN = OFF, WDTE = OFF
#pragma config PWRTE = OFF, FOSC = INTRCIO
#define _XTAL_FREQ 4000000

/******************************************************************************/
/* User Global Variable Declaration */
/******************************************************************************/
int i = 0;
/* i.e. uint8_t <variable_name>; */

/******************************************************************************/
/* Main Program */
/******************************************************************************/

void init_ports(void) /* Funzione di iniziazione delle porte */
{
 TRISIO = 0; /* Imposto tutte le porte in uscita */
 ANSEL = 0; /* Imposto tutte le porte come digitali */
}

void LedOn(void)
{
 GPIO2 = 1;
 GPIO4 = 1;
}

void LedOff(void)
{
 GPIO4 = 0;
 GPIO2 = 0;
}

void Led1(void) /* Programmo il lampggio per il LED1 */
{
 GPIO2 = 1; /* Accendo il Led1 che ho collegato sul porta 2 */
 __delay_ms(30); /* inserisco una pausa, il Led1 rimane acceso */
 GPIO2 = 0; /* Spengo il Led1*/
}

void Led2(void) /* Programmo il lampggio per il LED2 */
{
 GPIO4 = 1; /* Accendo il Led1 che ho collegato sul porta 4 */
 __delay_ms(30); /* inserisco una pausa, il Led1 rimane acceso */
 GPIO4 = 0; /* Spengo il Led1 */
}

void main(void)
{
 /* TODO <INSERT USER APPLICATION CODE HERE> */
 init_ports();

 while(1)
 {
 Led1();
 __delay_ms(850);
 Led2();
 __delay_ms(950);
 Led1();
 __delay_ms(950);
 Led2();
 __delay_ms(850);
 Led1();
 __delay_ms(850);
 Led2();
 __delay_ms(750);
 Led1();
 __delay_ms(750);
 Led2();
 __delay_ms(650);
 Led1();
 __delay_ms(650);
 Led2();
 __delay_ms(550);
 LedOn();
 __delay_ms(30);
 LedOff();
 __delay_ms(750);
 }
}

Analizziamo il codice che ho creato.
Innanzitutto come in altri molti linguaggi è opportuno inserire i commenti per comprendere meglio il codice. Questi possono essere inseriti a blocchi con un inizio caratterizzato dai simboli “/*” e una fine “*/”, oppure si può gestire le linee, inserendo la doppia barra “//” all’inizio della riga da commentare. Quindi come vedete la prima parte del nostro programma, sono una serie di commenti con varie annotazioni, fino a quando viene introdotta la prima parte vera e propria in cui vengono definiti i file da includere con “#include”.
In pratica segnalo al compilatore quali file voglio utilizzare nel mio progetto in quanto userò funzioni contenuti in essi. Ad esempio vorrò includere tutte le funzioni di default di XC8 con il file <xc.h>. Essendo questo il file generale di inclusione della libreria XC8, risulta inutile richiamare poi la libreria specifica del nostro PIC in quanto lo fa in automatico il compilatore prendendolo dalle proprietà del progetto. L’altro file <htc.h> richiama le funzioni per compatibilità con la vecchia versione del compilatore HI_TEC_C che è stato di fatto assorbito da Microchip e rivisto nell’attuale XC8.
In questo codice il programma include anche due file, “user.h” e “system.h”, ma che di fatto non vengono utilizzati e si possono escludere.
Non so quanti di voi si sono accorti, ma se avete guardato bene il codice, l’inclusione dei file è stata effettuata in due posizioni diverse! Il file con i simboli “<“ e “>” sta a significare che sono file della cartella “include” di default del compilatore, mentre il file fra le doppie virgolette “user.h” è un file presente nella cartella locale del progetto che abbiamo definito con il wizard all’inizio.
Analizziamo ora la sezione della configurazione in cui troviamo “#pragma config”  con una serie di parametri divisi  dalla virgola, impostati in OFF nel nostro caso, ma che potrebbero essere in ON in altri progetti. Non sto a spiegare in questo momento il significato di tutti i vari parametri, ma faccio notare  che l’unico a differire è il parametro FOSC = INTRCIO, che stabilisce l’uso interno dell’Oscillatore. Uno dei motivi per cui ho scelto questo PIC.

Infine con “#define _XTAL_FREQ” vado a definire la frequenza che nel nostro caso è di 4Mhz, quella del PIC12F675. Da notare che questo PIC viene calibrato da Microchip e si può trovare il parametro con il valore di programmazione in memoria che è possibile modificare con le apposite istruzioni. Non è il nostro caso in quanto diamo per certo che sia calibrato e manterremo il valore inserito in fabbrica.
Creiamo la funzione init_ports, servirà per impostare le porte in uscita e in digitale. Per semplicità e comodità ho impostato tutte le porte nello stesso modo, ma con i valori binari o esadecimali, possiamo definire quali porte usare in entrata e quali in uscita e quali in analogico e quali in digitale. Questa cosa la vedremo in un secondo momento.
Ora per comodità creo la funzione Led1 in cui vado a creare il lampeggio e cioè accendo il led1, creo una pausa in cui il led rimane accesso e infine lo spengo. Guardando il codice dovrebbe risultare molto semplice.
Faccio la stessa cosa per il Led2 e passo alla funzione main inserisco il codice che andrà in esecuzione di fatto e quindi inizializzo le porte richiamando la funzione init_ports, faccio andare in loop con l’istruzione “while(1)”, il Led1 richiamado la funzione, io ho inserito una pausa fra i due lampeggi e faccio accendere il Led2.

Bene ora verifichiamo la correttezza del nostro codice, compilandolo (simbolo del martello) e se è tutto ok, possiamo caricare il nostro programma sul PIC, assicurandoci che il programmatore e il PIC siano collegati e alimentati o dal circuito o dal programmatore. Clicchiamo sul simbolo di caricamento del codice e aspettiamo finché in basso nella cronologia eventi verrà visualizzata la scritta “Programming/Verify complete” A questo punto se il PIC è già nel circuito i led lampeggeranno!

Lampeggiatore Led Blu con PIC12F675

Dopo molto tempo, sono riuscito a rimettere le mani sul PIC e sul codice. Ho rinstallato tutta la suite MPLAB X IDE con XC8  nell’ultima  versione : ora i __delay_ms() e il __delay_us() sembrano funzionare con valori piccoli, se si usano numeri grandi vanno in overlord e quindi è meglio utilizzarli in un loop “for” .

Se avete qualche dubbio sul progetto che vi ho presentato  contattatemi!

Se questo articolo vi è sembrato interessante e vi è stato d’aiuto, condividetelo.
Aiutami a mantenere online il sito con un piccolo aiuto:  paypal.
Grazie di cuore 🙂

Fermodellismo Elettronica Pesca e tanto altro…