Questa pagina contiene materiale obsoleto - Vai al tutorial relativo all'ambiente MPLAB X e XC8
Scrivere il primo programma in C per il PIC18F14K50 non è difficile ma è necessario avere qualche nozione di base sul C e un'idea di quale è la struttura del microcontrollore.
Sono sempre da tenere a portata di mano:
Il programma qui presentato accenderà sequenzialmente i quattro led presenti sulla scheda dimostrativa del PICkit 2 (effetto supercar: qualcuno si è lamentato della "banalità" dell'esempio proposto per l'integrato FT2232H).
L'hardware utilizzato è particolarmente semplice: quattro LED e relative resistenze collegate a quattro PIN della porta di ingresso/uscita indicata come PORTC: RC0, RC1, RC2 e RC3 (rispettivamente i PIN numero 16, 15, 14, e 7 se usate il circuito integrato DIP).
Un progetto è costituito da vari file di configurazione inseriti in una struttura piuttosto articolata. Il modo migliore per partire è utilizzare l'apposito maghetto presente nel menù Project → Project Wizard di MPLAB IDE. Occorre selezionare il microcontrollore che si vuole utilizzare (PIC18F14K50) per permettere la corretta configurazione dei vari strumenti.
Occorre poi scegliere il compilatore che si intende utilizzare (MPLAB C18 se volete proseguire nella lettura di questa pagina). I nomi delle directory e dei file sono precompilati. Occorre specificare solo il nome del progetto che si intende scrivere e la cartella che lo conterrà. A volte, in particolare dopo un aggiornamento del software, potrebbe essere necessario impostare a mano alcune directory nel caso di errori di linker del tipo "could not find file xxx" (Project→ Build Options→ Project).
Il progetto appena creato appare vuoto.
In breve i passi da fare:
Una volta che il PIC è stato programmato, l'esecuzione del codice è indipendente dal PC e la scheda può anche essere staccata dal PICkit2.
I file che costituiscono il primo progetto sono visibili nella struttura di seguito riportata:
Il codice sorgente (File → New) è un normale programma C.
Di seguito alcuni commenti, in aggiunta a quelli già presenti direttamente nel codice sorgente, che vi prego di scorrere prima di proseguire nella lettura di questa pagina.
#include <p18f14k50.h>
#include <delays.h>
Queste due linee includono i due header file già citati.
Le linee seguenti (#pragma config) definiscono una serie di parametri di funzionamento del processore. Non sono istruzioni, nel senso che non sono convertite in istruzioni macchina, ma servono al programmatore per impostare una serie di bit (i cosiddetti Configuration bits) prima dell'esecuzione del programma. Il significato, richiamato nel commento, è descritto nel manuale del PIC ma non è strettamente necessario comprenderne subito il funzionamento. In alternativa è possibile utilizzare la voce di menu Configure → New per impostare gli stessi parametri.
#pragma config FOSC = IRCCLKOUT // Internal RC
oscillator (F/4 to OSC2)
// #pragma config FOSC = IRC // Internal RC oscillator
Le due linee precedenti (alternative tra loro) impostano il generatore di clock interno al PIC. La prima può essere a volte utile per il debug sul componente fisico.
Le due linee seguenti permettono l'uso come normali pin di I/O dei due pin LVP e MCLRE, altrimenti riservati ad usi specifici.
#pragma config LVP = OFF // Disable Low Voltage
Programming
#pragma config MCLRE = OFF // Disable MCLR
Il programma inizia obbligatoriamente con la funzione main():
L'istruzione seguente imposta la velocità del clock interno (la descrizione dettagliata è sul manuale del PIC). Nel codice allegato è commentata, quindi per renderla efficace occorre eliminare gli // iniziali. Se non lo si fa, semplicemente il programma verrà eseguito a minore velocità.
// OSCCON = 0x70; // Select 16 MHz internal clock (default 1MHz)
Spesso i numeri interi sono indicati nel codice in esadecimale (come in questo caso, quando preceduti da 0x) o in binario (quando preceduti da 0b, estensione C non standard). Invece di 0x70 si poteva scrivere, esattamente con lo stesso significato, 0b0111000 (un po' scomodo da leggere, ma è questione di gusti personali) oppure 112 (sicuramente poco efficace quando si lavora con i bit).
L'istruzioni seguente impostano la porta C del PIC come porta di uscita affinché sia possibile accendere o spegnere i LED ad essa collegati. Anche in questo caso la descrizione è sul manuale del PIC, cercando TRISC. Il nome dei registri è sempre scritto in maiuscolo. Si noti che sulla schedina PICkit2 sono presenti solamente 4 LED, quelli corrispondenti allo zero esadecimale di destra: i bit da scrivere quindi sarebbero, in binario, XXXX0000, cosa non possibile con un linguaggio di programmazione come il C.
TRISC = 0x00; // Set PORTC as Output
Infine troviamo il loop infinito che accende i LED in sequenza.
for(;;)PORTC non è una normale variabile in memoria ma una delle interfacce fisiche del PIC verso il mondo reale: scrivere un 1 significa applicare una tensione alta ad un filo elettrico e quindi, in questo caso, accendere il LED ad esso collegato. Scrivere uno 0 significa ovviamente spegnere il LED.
L'istruzione PORTC = 0x01; scrive contemporaneamente 8 bit (questa è la dimensione fisica dell'interfaccia). Il numero, che corrisponde al binario 0b00000001, provoca l'accensione di un solo LED, quello collegato al pin RC0 cioè il pin fisico numero 16 (se state usando il PIC18F14K50 in contenitore DIP20).
La funzione Delay1KTCYx(100) è tipica del compilatore usato e, in questo programma, genera un ritardo di 400 ms che diminuisce all'aumentare della frequenza di clock del PIC.
Per leggere lo stato di un segnale esterno al PIC occorre configurare un pin di una porta come ingresso. Sulla scheda del PICkit2 è presente un interruttore che, quando premuto, fornisce uno zero logico al pin RA3; quando rilasciato, fornisce un uno logico.
Per poterlo usare in un programma occorre configurare la porta PORTA come ingresso (operazione inutile, nello specifico e come caso particolare, quando si usa RA3) :
TRISA = 0xFF; // Set PORTA as input (RA3 is always input if MCLR disabled)La lettura di tutti gli otto bit associati alla porta viene fatta semplicemente leggendo la variabile PORTA (in realtà solo i sei bit meno significativi sono fisicamente presenti). Se si vuole leggere il solo bit associato al bit 3 della porta, nel nostro caso quello a cui è collegato l'interruttore, è possibile usare la sintassi seguente:
while (!PORTAbits.RA3); // Loop if pin 3 of PORTA is 1 (SW1 not pressed)Il loop precedente in pratica interrompe l'esecuzione del programma quando RA3 vale 1, altrimenti prosegue. Il codice lo trovate a fondo pagina, basta togliere i commenti alle due righe appena descritte.
Due informazioni utili per usare RA3 con il PICKit2, un po' nascoste nel manuale:
La programmazione del PIC è fatta con l'apposita funzione del menù (Programmer → Program), ovviamente dopo aver selezionato come programmatore il PICkit 2. Per l'esecuzione fisica del programma occorre selezionare Programmer → Release_from_Reset. E' comodo impostare la programmazione e l'esecuzione automatica del programma dopo la compilazione.
Una volta che il programma è stato memorizzato sul PIC, la sua esecuzione è possibile anche staccando il PICkit2 e alimentando la scheda con una tensione continua di 3,3 V.
Appunti di elettronica
- PIC18F14 in C - OBSOLETO - Versione 1.0 - Ottobre 2014
Copyright 2010-2012, Vincenzo Villa (https://www.vincenzov.net)
Quest'opera stata rilasciata con licenza Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported.