Creative Commons BY-NC-ND 2.5Questo sito e tutto il suo contenuto sono distribuiti sotto la licenza Creative Commons Attribuzione - Non Commerciale - Non opere derivate 2.5 Italia e con le condizioni d'uso definite nel disclaimer: siete pregati di leggere entrambi questi documenti prima di usufruire dei contenuti di questo sito. Per alcuni contenuti è necessaria una registrazione gratuita: non è necessario pagare e non è necessario accumulare punteggi per accedere agli articoli e scaricare i sorgenti. Basta solo essere onesti. Se volete che questo sito continui a rimanere attivo, a contribuire ogni giorno alla diffusione della cultura libera, non copiate il materiale per ripubblicarlo in altri luoghi : chi fa questo è solo un miserabile e un perdente. Se volete partecipare su settorezero e rendere le vostre idee, i vostri progetti, fruibili da tutti senza limitazioni, come dovrebbe essere in un paese civile e acculturato, potete farlo tranquillamente.

Corso programmazione PICMicro in C – Lezione 3 – Il primo programma in C: scrivere un semplice programma in C per PICMicro, impostare MPLAB e flashare il PICMicro con il PICKit2. Facciamo lampeggiare un LED!

Autore: Giovanni Bernardo | Data pubblicazione: 18 agosto 2009
Categorie: PICmicro 10/12/16

primo_programma_picmicro_in_c_flashare_con_pikcit2_circuitoFinalmente dopo le precedenti due lezioni, per lo più introduttive, eccoci alla parte pratica! In questa lezione scriveremo il nostro primo programma in C, lo compileremo e lo caricheremo sul PICMicro per vederlo in azione.

Ovviamente il primo programma è sempre qualcosa di molto molto semplice: faremo lampeggiare un diodo led. Certo non è un qualcosa di molto entusiasmante, ma bisogna partire a piccoli passi per comprendere a fondo tutto quello che c’è dietro ai programmi più complessi.

Ricordate lo schema elettrico del circuito di base presentato nella seconda lezione? Bene, andremo a collegare sul pin n° 19 (che rappresenta la porta RD0, ovvero la prima delle porte D) un diodo led, con in serie una resistenza da 330Ω (che ha la funzione di limitare la corrente che circola nel LED, in maniera tale da non farlo bruciare). Realizzeremo  quindi il seguente schema:

primo_programma_picmicro_in_c_mplab_schema_thumb

Quando andrete a montare il LED, tenete conto che il terminale più corto dei due è quello che va verso massa. Se lo montate al contrario non si accenderà. Fate una prova alimentandolo con 5 volt e con la resistenza da 330Ω: vedrete che in un senso si accenderà e dall’altro no. Anche se emette luce, si tratta pur sempre di un diodo ed è quindi capace di far circolare la corrente in un verso soltanto.

La porta RD0 è stata scelta a caso, avremmo potuto collegare il LED su qualsiasi altra porta indifferentemente: ci serve difatti unicamente la funzione di I/O digitale, che come abbiamo visto nelle lezioni precedenti, è a disposizione di qualsiasi porta.

Se state utilizzando per questi esperimenti la scheda Freedom di Mauro Laurenti, per poter utilizzare le varie porte per gli esperimenti, potete crearvi una piattina che da un lato si innesta nella scheda di sviluppo e dall’altro invece presenta uno strip da 10 contatti in linea che possiamo utilizzare facilmente per la connessione con una breadboard:

primo_programma_picmicro_in_c_adattatore_freedom_breadboard

Parte 1 – Scriviamo il programma

Dopo aver montato tutto il circuito, possiamo procedere alla scrittura del nostro primo programma. Personalmente per scrivere il programma in C, utilizzo Notepad++ (mi piace perchè è freeware, evidenzia le parole chiave con colori diversi, ha il supporto della sintassi per molti linguaggi, la numerazione delle righe ecc). Voi ovviamente potete utilizzare ciò che più vi piace, anche il blocco note di windows (anche se non lo consiglio affatto, è buono avere un editor tipo Notepad++ che evidenzia la sintassi).

ATTENZIONE!
Dato che il 90% degli italiani non ha assolutamente la sana abitudine di leggere i commenti, nè tantomeno cercare una risposta, scrivo qui una cosa che continuo a ripetere all’infinito e di cui mi sono stufato: dal momento che l’Hitech-C è stato aggiornato, alcuni nomi mnemonici non combaciano più con quelli delle vecchie versioni, per cui finito di leggere l’articolo, prima di compilare il programma VI PREGO, VI SCONGIURO di andarvi a leggere questo articolo: http://www.settorezero.com/wordpress/hitec-c-compiler-i-nuovi-nomi-mnemonici-che-causano-errori-nei-vecchi-programmi/

Questo è il primo programma che andremo a scrivere (sarà comunque possibile scaricarlo in fondo all’articolo per gli utenti iscritti: è gratis!), creiamo un file di testo vuoto, diamogli il nome “main.c” e incolliamoci all’interno il seguente codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//*************************************************
// CORSO PROGRAMMAZIONE PICMICRO
// www.settorezero.com
//
// modulo: main.c
// autore: Bernardo Giovanni
// data: 18/08/09
// descrizione: lampeggia un led su RD0
// picmicro: PIC16F877A
// clock: 20MHz
//
//*************************************************
 
#define  XTAL_FREQ 20MHZ // questo è utilizzato dalle routine di ritardo contenute in Delay.C
#include <pic.h> // contiene i nomi mnemonici di registri e porte
 
// Fuses di configurazione
__CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);
 
#include "delay.c" // routine per ritardi
#define    LED    RD0 // invece di scrivere RD0, scriverò LED, così mi è più facile ricordare
 
// funzione principale, eseguita all'avvio del picmicro
void main(void)
 {
 
 // imposto i registri tristato in maniera tale che tutte le porte siano configurate come pin di uscita
 TRISA=0b00000000;
 TRISB=0b00000000;
 TRISC=0b00000000;
 TRISD=0b00000000;
 TRISE=0b00000000;
 
 while(1) // eseguo un ciclo finito
 {
 LED=LED^1;
 DelayMs(250);
 }// Fine ciclo continuo
 
 } // Fine main

Analizziamo quindi il programma. Quello che si trova dietro il doppio backslash (//) sono semplici annotazioni, verranno ignorate dal compilatore, servono soltanto al programmatore a “ricordarsi” cosa succede. E’ sempre buona norma mettere all’inizio del programma un’intestazione con le date ecc, e che specifica autore, scopo del programma e quant’altro vogliamo, se non altro ci aiuterà tra qualche anno quando dovremmo rimettere mano a un codice per modificarlo o migliorarlo.

14
#define  XTAL_FREQ 20MHZ

Le righe che iniziano con il cancelletto (#) sono direttive inviate al compilatore, ovvero non si tratta di vere e proprie istruzioni di programma, ma di istruzioni inviate al compilatore e che non occuperanno spazio in memoria programma. In questa riga in particolare, l’istruzione define dice al compilatore che quando all’interno del programma troverà la scritta “XTAL_FREQ”, la dovrà sostituire con il valore “20MHz”. Non si tratta affatto dell’assegnazione del valore ad una variabile, stiamo soltanto definendo un nome alternativo per un valore, il che ci aiuta molto a ricordare. Questa riga in particolare è utilizzata da una routine (che vedremo in seguito) che serve a generare ritardi.

15
#include <pic.h>

è un’altra direttiva (vedete? c’è il cancelletto): stiamo dicendo al compilatore di includere in quel punto, il file “pic.h”.  In pratica tale direttiva leggerà il contenuto di quel file e lo inserirà in quel punto. Questo è un buon modo per scrivere codice “portabile”: una volta scritta una porzione di codice riutilizzabile, non ci sarà bisogno di riscriverla sempre nei nostri programmi, basterà “includerla”. Quando tale direttiva include un file contenuto nella cartella “include” dell’installazione del compilatore, tale file va scritto tra < e >, quando invece il file da includere si trova in un altro percorso, allora va incluso tra virgolette ” ” (in particolare se tra virgolette indichiamo unicamente il nome del file, il compilatore assume che tale file da includere si trovi nello stesso percorso del file principale, ovvero main.c).

Il file pic.h in particolare, che già si trova nella cartella “include” di installazione dell’Hitec-C, contiene tutte le definizioni dei nomi delle porte e dei registri dei vari picmicro. In pratica non dovremo ricordarci tutti gli indirizzi di memoria (che sono numerici!) del nostro PICMicro: basterà ricordarsi i nomi “mnemonici”, molto più facili da ricordare perchè i loro nomi rispecchiano in un certo qual modo le funzioni dei registri. Impareremo man mano a utilizzare i nomi mnemonici quando ne avremo bisogno. In particolare il file pic.h includerà a sua volta un altro o più file con estensione .h a seconda del PICMicro che sceglieremo durante la compilazione del programma.

Quando programmerete in C, incontrerete essenzialmente due tipi di file di testo, con estensione .c (che  contengono funzioni, programmi principali) e con estensione .h. h sta per Header, ovvero “intestazione”, si tratta in genere di files ausiliari che contengono settaggi, prototipi di funzioni ecc, necessari per il funzionamento delle funzioni principali, si tratta in pratica di una convenzione e buona pratica di programmazione. Ovviamente noi potremmo scrivere tutto il nostro codice in un unico file, ma avere il file principale, soprattutto se si tratta di programmi complessi, suddiviso in più files c e h ci aiuterà molto a concentrarci su una parte di programma e ci permetterà di rendere il nostro programma, o le nostre funzioni, riutilizzabili in altri ambiti anche totalmente differenti da quelli per cui sono stati progettati.

Date una sbirciatina nella cartella “include” del compilatore (C:\Programmi\HI-TECH Software\PICC\PRO\9.65) : vedete? Ci sono un sacco di files .h, ognuno che contiene vari #define a seconda del picmicro che andremo a scegliere. Il file pic.h è quello generico, che si accorgerà di quale pic abbiamo scelto (durante l’operazione di compilazione che vedremo dopo) e che provvederà a includere il file .h adatto: in particolare per il PIC16F877 sarà incluso il file pic1687x.h.

Andiamo avanti con la spiegazione del programma:

18
__CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);

Questa parte qui è un po’ più complicata… Si tratta in pratica di una funzione (chiamata appunto “__CONFIG” definita nel file pic.h) che serve a settare i FUSES (o fusibili) di configurazione del picmicro e di cui abbiamo già accennato qualcosina nelle precedenti lezioni. Ogni picmicro ha un suo registro di configurazione con i propri valori (vedete pag. 144 del datasheet del PIC16F877A) e che serve per impostare le modalità di funzionamento. I valori che si trovano tra parentesi (ovvero gli argomenti della funzione) sono nomi mnemonici (ogni parola, tipo HS è in realtà un valore numerico, definito da vari #define contenuti nei file h del picmicro scelto), che vengono combinati tramite AND logici per ottenere la word di configurazione adatta. In particolare questo settaggio dice:

HS (High Speed) = intendiamo utilizzare un oscillatore al quarzo ad alta frequenza.

WDTDIS (Watch Dog Timer DISabled) = disabilitiamo il Watch Dog Timer: si tratta di un timer che ha la funzione di resettare il pic se il programma si blocca e quindi far ripartire il programma daccapo, noi per ora (e forse mai) non utilizzeremo questo timer, dobbiamo programmare bene per fare in modo che il programma non si blocchi!! In realtà tale funzione a volte è utile, ma noi probabilmente non la useremo.

PWRTEN (PoWeRup Timer ENabled) = il pic aspetta alcuni microsecondi all’accensione prima di avviare il programma, in maniera tale da far stabilizzare la tensione e l’oscillatore.

BORDIS (Brown Out Reset DISabled) = il brown out è una funzione che permette di resettare il pic se la tensione di alimentazione scende al di sotto di un dato valore, tale funzione non ci serve, quindi la disattiviamo.

LVPDIS (LowVoltage Programming DISabled) = disabilitiamo la programmazione a bassa tensione (abbiamo visto nelle lezioni precedenti di cosa si tratta).

DUNPROT (Data UNPROTected) = la memoria dati non sarà protetta

WRTEN (WRite ENabled) = scrittura memoria flash abilitata

DEBUGDIS (DEBUG DISabled) = funzioni di debugging disabilitate, il debug non è disponibile con il pickit2

UNPROTECT = non protegge la memoria programma

Questi sono i settaggi ideali per gli esperimenti: proteggere la memoria dati, programma, eeprom, disattivare la scrittura, potrebbe difatti renderci impossibile riprogrammare il PIC una seconda volta, quindi se sbagliamo, il pic sarà da buttare! Quindi non proteggiamo assolutamente nulla!

20
#include "delay.c"

Stiamo includendo il file delay.c (scaricabile insieme a tutto il progetto in fondo all’articolo, per gli utenti iscritti) che si trova nello stesso percorso del file principale. Tale file include delle routine per creare ritardi (delay). Includendo questo file avremo a disposizione nel nostro programma due funzioni: DelayMs(n) che ci permetterà di eseguire ritardi di n millisecondi (con n da 0 a 255) e DelayUs(n) che ci permetterà di eseguire ritardi di n microsecondi. I ritardi sono funzioni molto importanti nei programmi.

21
#define    LED    RD0

Ancora un’altra direttiva! Stiamo dicendo al compilatore che quando leggerà la parola “LED” all’interno del programma, gli dovrà sostituire il valore RD0 (ricordate lo schema? Abbiamo collegato il led alla porta RD0, è più facile ricordarsi LED, sapendo che li cè collegato un led, piuttosto che RD0, vi pare?). La parola (o forse meglio il SIMBOLO) RD0 è a sua volta definito in uno di quei file h che abbiamo incluso all’inizio e contiene l’indirizzo di memoria che “mappa” la porta RD0, non ci dovremo preoccupare a quale indirizzo si trova la porta RD0, tanto abbiamo già tutti i nomi mnemonici già definiti per il nostro pic (definiti da pic.h, incluso all’inizio). Quindi come c’è RD0, ci sarà anche RA1, RB3 ecc ecc, comodo no?

Finalmente inizia il programma vero e proprio:

24
25
void main(void)
 {

Chiariamo innanzitutto una cosa, qui stiamo scrivendo una funzione, questa funzione si chiama “main” (scritto minuscolo!, ricordate che il C è case-sensitive! Ovvero fa distinzione tra maiuscole e minuscole!). La funzione chiamata main è quella che viene eseguita all’accensione del picmicro, per cui tutti i nostri programmi avranno sempre una funzione chiamata così.

Il “void” scritto all’inizio indica che tale funzione non restituisce valori (void=vuoto), il void scritto tra parentesi dopo main, indica che tale funzione non accetta valori in ingresso. La funzione main difatti non può nè deve accettare/restituire valori. Ci saranno altre funzioni che potranno accettare valori per eseguirci su dei calcoli e quindi restituire un valore, altre che restituiranno un valore ma non accetteranno niente in ingresso, altre ancora che accetteranno valori in ingresso ma non restituiranno niente.

Una cosa del genere ad esempio:

int somma(int a, int b)

definisce una funzione chiamata “somma”, che restituisce un numero intero (int), e accetta in ingresso due variabili (a e b) interi anch’essi. L’int messo davanti (al posto del void) specifica appunto un intero, int è uno specificatore del tipo di dato. Fate riferimento alla pagina 83 del file “manual.pdf” contenuto nella cartella docs del compilatore (C:\Programmi\HI-TECH Software\PICC\PRO\9.65\docs) per vedere quali sono i tipi di dato disponibili in C. Qui vi riporto un estratto:

tipi_di_dato_hitec_c

Ricordate inoltre: tutto ciò che deve essere eseguito dalla funzione, deve trovarsi tra parentesi graffe! Per cui: ricordiamoci di chiudere le parentesi dopo che le abbiamo aperte. E’ sempre buona norma mettere sempre prima entrambe le parentesi (aperta e chiusa) e quindi successivamente scriverci tutto all’interno.

Ovviamente qui qualcuno andrà nel pallone non trovando le parentesi graffe sulla tastiera. Le parentesi graffe si inseriscono tenendo premuto ALT (quello a sinistra, NO ALT GR) e quindi digitando in sequenza 1-2-3 sul tastierino numerico (ho detto sul tastierino! Non funziona con i numeri sopra alle lettere!) e quindi rilasciando il tasto ALT per la parentesi aperta, stessa cosa ma digitando 1-2-5 per la parentesi chiusa, e così anche per tutti gli altri caratteri che non trovano posto sulla tastiera.

Proseguiamo nella lettura del programma con qualcosa di più interessante:

28
29
30
31
32
TRISA=0b00000000;
TRISB=0b00000000;
TRISC=0b00000000;
TRISD=0b00000000;
TRISE=0b00000000;

I registri TRIS (regisatri tristato, ve ne ho accennato nella lezione 2) ci sono per ogni gruppo di porte (TRISA è il registro tristato delle porte A, e… TRISB ?). Notate innanzitutto che dopo l’uguale abbiamo uno 0b, questo zero-bi indica al compilatore che il numero che segue è in formato binario, se avessimo messo 0x (zero-ics) voleva dire che il numero che seguiva era scritto in esadecimale, invece senza notazione alcuna sarebbe stato scritto in decimale). Vi rimando ad un mio precedente articolo sulla numerazione binaria ed esadecimale, imparare queste cose non fa mai male. Sempre a pagina 83 del manuale dell’Hitec-C troviamo un’altra tabella con i prefissi da usare per specificare la base con cui scriviamo i numeri:

tipi_di_formato_numerico_hitec_c

Scrivendo

TRISA=0b00000000;

Stiamo dicendo che tutti i bit del registro tristato delle porte A, devono essere impostati su ZERO. Cosa significa? Impostare nel registro tristato un bit a zero equivale a impostare quella porta (quel pin) come USCITA (Output, per aiutarvi a memorizzarlo ricordate la somiglianza tra lo zero e la lettera O di Output…), impostare un bit a 1 equivale rendere quella porta (quel pin) un ingresso (Input, 1 somiglia alla lettera I, giusto? ;) ). In particolare il bit più significativo (ovvero l’ottavo bit) è quello più a sinistra: quello più vicino alla lettera b, andando verso destra troviamo il bit 7, 6 ecc fino ad arrivare al bit1 che viene detto bit meno significativo. Il bit1 mappa la porta 0, il bit2 mappa la porta 1 e così via. In pratica se noi scriviamo:

TRISA=0b00000010;

Diremo al PICMicro che la porta RA1 dovrà essere una porta di ingresso (abbiamo messo l’uno sul secondo bit, che mappa la seconda porta, ovvero la RA1) mentre tutte le restanti porte dovranno essere pin di uscita. Abbastanza semplice non trovate? Per questo motivo il settaggio delle porte lo scrivo in binario, così visivamente mi accorgo di quale porta sto impostando come ingresso e quale come uscita, ovviamente nulla mi vietava di scrivere 0×2 (notazione esadecimale) oppure 2 (notazione decimale) al posto di 0b00000010 … (usate la calcolatrice di windows in modalità scientifica per capire che ho detto se non ci siete arrivati…).

Ovviamente alcuni banchi di porte non disporranno di tutti e 8 i bit: ricordate l’immagine del datasheet del PIC16F877? Osservate: Le porte A sono soltanto 6 (da RA0 a RA5), quando vorremo settare questa porta, è buona norma per noi mettere comunque tutti e 8 i bit, ovviamente i bit 7 e 8 li metteremo a zero, tanto pure se li mettiamo a 1 non avranno effetto perchè le porte RA6 e RA7 su questo PIC non esistono… (per non parlare delle porte E che sono soltanto 3… Qui avremo a disposizione soltanto i bit 1, 2 e 3, gli altri bit da 4 a 8 li metteremo sempre a zero perchè tali porte non esistono).

Bene, abbiamo quindi settato tutte quante le porte del nostro PIC16F877 come uscita!

Quando nel nostro circuito rimarranno pin non utilizzati, è sempre bene impostare tali porte come uscite, perchè se le impostiamo come ingressi e non vengono utilizzate, potrebbero captare disturbi di natura elettromagnetica che dobbiamo sempre evitare come la peste.

Proseguiamo:

34
35
while(1) // eseguo un ciclo finito
 {

Qui abbiamo un ciclo while (vi rimando all’ottima lettura TrickyC presente nell’area risorse del sito, pagina 79, per capire come funzionano i 3 tipi di cicli disponibili in C) che verrà eseguito all’infinito perchè vi abbiamo messo 1 come condizione, che è sempre vera. All’interno di questo ciclo troviamo la parte interessante:

36
37
LED=LED^1;
DelayMs(250);

Qui stiamo accendendo e spegnendo il led!! Ma come? Iniziamo col dire che DelayMs(250) esegue una pausa di 250 millisecondi (ricordate le funzioni DelayMs incluse nel file delay.c di cui abbiamo parlato più in alto?), in pratica il led rimarrà acceso 250 ms e spento altri 250ms per poi ricominciare daccapo. L’accensione e lo spegnimento del led vengono eseguiti dall’istruzione LED=LED^1. Chiariamo innanzitutto che il simbolo ^ in C non è l’elevamento a potenza ma rappresenta la funzione di XOR, in pratica quando su un bit viene eseguito l’XOR con 1, viene invertito lo stato del bit: diventerà 1 se era 0 e viceversa.

Fate riferimento a questo nostro articolo per conoscere come si effettuano le operazioni di algebra booleana.

Scrivere LED=1 significa “dare tensione” a quel pin (ricordate? LED=RD0), quindi se scrivo LED=1 la porta RD0 si porterà in condizione di livello logico alto, ovvero da quel pin usciranno 5volt, per cui il led si accenderà, scrivere LED=0 porterà la porta RD0 in stato logico basso, per cui da quel pin usciranno zero volt (massa) e il led si spegnerà, scrivere LED=LED^1 significa semplicemente invertirne lo stato… Dal momento che dopo viene una pausa, si avrà l’effetto di vedere il led accendersi e spegnersi ogni 250ms (se avete la fortuna di avere un oscilloscopio, vedrete su tale pin un’onda quadra con la frequenza di 2Hz).

Difatti per portare un’uscita a livello logico alto (far uscire 5 volt), basta impostare tale porta a 1, per renderla bassa, si imposta a zero. Non dovrebbe risultare complicato.

Ci tengo a far notare che tutte le istruzioni devono terminare con un punto e virgola, altrimenti si verificheranno errori strani e incomprensibili durante la compilazione, e spesso gli errori vengono segnalati in una parte di programma che non c’entra nulla quando mancano il punto e virgola o non viene chiusa una funzione.

Abbiamo infine la chiusura del ciclo while e quindi della funzione main:

38
39
40
}// Fine ciclo continuo
 
} // Fine main

Ok… Abbiamo scritto il nostro primo programma (ok l’abbiamo copiato oppure scaricato!), abbiamo capito (si spera) come funziona… Non ci resta che compilarlo, caricarlo sul PICMicro e vedere come funziona!

Parte 2 – Compiliamo il programma

Abbiamo questa situazione: in una cartella ci sono i files: main.c, delay.c e delay.h scaricati in fondo all’articolo. Avviamo MPLAB IDE, Selezioniamo Project -> Project Wizard

primo_programma_picmicro_in_c_mplab_01

Comparirà la finestra del wizard (ovvero la procedura guidata) :

primo_programma_picmicro_in_c_mplab_02

Clicchiamo su Avanti, ci verrà chiesto di selezionare il dispositivo (il PICMicro) che intendiamo utilizzare per questo progetto:

primo_programma_picmicro_in_c_mplab_03

Scorriamo la lista e troviamo PIC16F877A, premiamo quindi Avanti. Ci verrà mostrata la finestra nella quale dobbiamo scegliere quale suite di linguaggio intendiamo utilizzare:

primo_programma_picmicro_in_c_mplab_04

Dal menù Active Toolsuite selezioniamo HI-TECH Universal ToolSuite come nella figura (l’abbiamo installato nella lezione 2, ricordate?), premiamo quindi Avanti, dovremo dare un nome al nostro progetto:

primo_programma_picmicro_in_c_mplab_05

Premiamo sul tasto Browse e andiamo a trovare la cartella in cui abbiamo salvato main.c e tutto il resto, nella casella nome file mettiamo un nome facile da ricordare: lampeggia_led, come in figura:

primo_programma_picmicro_in_c_mplab_06

Premiamo quindi salva, ritorneremo nella finestra precedente:

primo_programma_picmicro_in_c_mplab_07

Clicchiamo su Avanti, ci verrà chiesto di aggiungere dei files al progetto:

primo_programma_picmicro_in_c_mplab_08

Selezioniamo soltanto main.c e premiamo sul tasto Add>> per aggiungerlo al progetto, premiamo quindi Avanti. Sarà mostrata una finestra di riepilogo:

primo_programma_picmicro_in_c_mplab_09

Possiamo quindi premere Fine, verremo riportati alla finestra principale di MPLab:

primo_programma_picmicro_in_c_mplab_10

Vedete sulla sinistra c’è una finestra più piccola in cui è evidenziato il nostro codice sorgente main.c, anche se non abbiamo incluso gli altri file nel progetto durante il wizard, funzionerà tutto lo stesso perchè saranno inclusi dal compilatore grazie alle direttive #include che abbiamo scritto nel programma. Possiamo passare a compilare il programma. Vedete nella barra degli strumenti ci sono due tasti: uno nero e uno rosso:

primo_programma_picmicro_in_c_mplab_11

Quello nero è per compilare la prima volta, quello rosso è per RI-compilare nel caso avessimo già compilato e modificato qualcosa (verranno cancellati dei file “di appoggio” e ricompilato tutto daccapo). Premiamo il tasto nero. La compilazione prenderà generalmente meno di un minuto (dipende da tanti fattori) e se tutto è andato per il meglio, sarà presentata una finestra di riepilogo con le operazioni di compilazione e una scritta BUILD SUCCESSFUL alla fine:

primo_programma_picmicro_in_c_mplab_12

Vedete in questa finestra ci sono molte informazioni: quanta memoria programma abbiamo utilizzato (lo 0.9%, ma ricordate che stiamo utilizzando la versione LITE che non ci permette di utilizzare tutta la memoria programma disponibile ma ha un limite di 2000h words, con una versione PRO lo spazio a disposizione è molto di più, inoltre con la versione pro viene abilitata una funzione, chiamata Omniscient Code Generation, che permette di risparmiare ulteriore spazio, fino al 52% in meno, dal momento che ottimizza ancor più il codice compilato).

Quando qualcosa andrà storto, ci sarà invece scritto BUILD FAILED, con l’elenco dei numeri di riga che hanno dato l’errore, in questo caso dovremo individuare l’errore, correggerlo e ricompilare (premendo il tasto rosso anzichè quello nero). Errori tipici dei principianti sono:

  • dimenticanza del punto e virgola alla fine di una riga che lo prevede
  • dimenticanza della chiusura di una o più parentesi graffe
  • dimenticanza che il C è case sensitive, per cui se abbiamo dichiarato una “VarIABILE” e la richiamiamo come “variabilE”, non sarà riconosciuta, stessa cosa per le funzioni e per tutto il resto: rispettate maiuscole e minuscole!

Andiamo a controllare la cartella dove avevamo messo main.c, vedete, ci sono un sacco di altri file, a noi ne interessa in particolar modo uno soltanto: lampeggia_led.hex, quello con estensione HEX! E’ questo qui che dobbiamo caricare nel PICMicro? Come?

Parte 3 – Carichiamo il programma compilato nel PICMicro

Colleghiamo il PICKit2 alla porta USB del computer e innestiamolo nel connettore ICSP del circuito (ricordatevi di non tenere alimentato il circuito, anzi staccategli proprio i fili dell’alimentazione quando lo programmate).

Per sapere come va collegato il PICKit2 ai vari tipi di PICmicro (e anche alle memorie EEPROM), può esservi utile questo nostro articolo: Adattatore multizoccolo per PICKit2.

Avviamo il programma PICKit2:

primo_programma_picmicro_in_c_flashare_con_pikcit2_01

Dovrà essere presente il messaggio “PICkit2 found and connected” come in figura, dal menù “Device”, dove c’è scritto “-Select Part-”, scorriamo fino a scegliere PIC16F877A

Se PIC16F877A non è presente nell’elenco potrebbe essere necessario andare sul menù “Device Family” e selezionare Midrange -> Standard

primo_programma_picmicro_in_c_flashare_con_pikcit2_02

Come vedete cambia il valore di Configuration (che è il valore che sarà assegnato al registro di configurazione, non curiamoci di quello che esce scritto in questa fase, dal momento che il programma non l’abbiamo ancora caricato) e il valore di Checksum. Il Checksum in particolare è un valore che in un certo qualmodo identifica il programma che abbiamo caricato, quando faremo piccole o grandi modifiche a uno stesso programma, vedremo che tale valore cambierà, quindi due programmi perfettamente uguali avranno lo stesso checksum, è un buon modo per identificare un programma.

Andiamo avanti, dobbiamo caricare il nostro programma in memoria. Dal menù File selezioniamo “Import Hex”:

primo_programma_picmicro_in_c_flashare_con_pikcit2_03

Cerchiamo la cartella con il programma e selezioniamo “lampeggia_led.hex”:

primo_programma_picmicro_in_c_flashare_con_pikcit2_04

Premiamo quindi Apri, il file Hex sarà importato in memoria e cambieranno tutti i valori nell’interfaccia:

primo_programma_picmicro_in_c_flashare_con_pikcit2_05

In particolare cambierà il valore di configuration, che per i nostri esperimenti sarà sempre 2F02. Vedete che il campo program memory adesso contiene tanti valori, quei valori rappresentano appunto il nostro programma compilato: ovvero convertito da codice sorgente (comprensibile per gli esseri umani) a linguaggio macchina (comprensibile per il dispositivo).

Avete collegato il PICKit2 al circuito vero? Bene… Premiamo il tasto Write:

primo_programma_picmicro_in_c_flashare_con_pikcit2_06

Attendiamo un po’ che il nostro fido programmatore carichi nella memoria del PIC tutto il necessario: configurazione e programma. Dopodichè, se tutto va per il meglio, deve apparire la magica scritta:

primo_programma_picmicro_in_c_flashare_con_pikcit2_07

Ovviamente c’è un certo senso di soddisfazione: adesso il programma che abbiamo scritto è memorizzato all’interno del microcontrollore! Non ci resta che staccare il programmatore, e dare alimentazione al circuito. Il risultato che otterremo è questo:

Certo non è molto entusiasmante, ma avete visto quanto mi ci è voluto per insegnarvelo? Spero che abbiate capito tutto. Lasciate commenti e se potete, supportate il sito e chi ci lavora per passione. Nella prossima puntata cercheremo di fare di meglio ;)

Downloads

Nota: i programmi di esempio sono stati sviluppati con una versione precedente dell’Hitec-C Compiler, per cui compilati con la nuova versione, restituiscono errori. Fate riferimento a questo articolo per maggiori informazioni su come adattare i vecchi programmi. Consiglio spassionato se volete davvero imparare a programmare: non utilizzate l’include legacy headers, ma imparate a cambiare i nomi mnemonici.

File di supporto alla terza lezione del corso di programmazione picmicro in C (2794)
L'articolo ti è piaciuto o ti è stato utile per risolvere un problema? SettoreZero è realizzato soltanto contenuti originali: tutti gli articoli sono curati con passione dagli autori e nulla viene copiato da altri siti. Supporta e mantieni in vita SettoreZero con una donazione: basta soltanto un caffè o una birra. Puoi supportare SettoreZero anche con uno dei progetti elencati nella sezione servizi o partecipare anche tu con un tuo articolo/progetto personale.

Se desiderate che SettoreZero continui a rimanere gratuito e fruibile da tutti, non copiate il nostro materiale e segnalateci se qualcuno lo fa.

Puoi andare alla fine dell'articolo e lasciare un commento. I trackback e i ping non sono attualmente consentiti.

  1. #1 da damosound il 5 febbraio 2012

    ciao giovanni,
    mi devi scusare se ti disturbo continuamente, ma non riesco a venire fuori con questi piccoli problemi con il pic.
    ho fatto questo programma per il pic16f877. e semplicissimo, ma alla fine non funzione. ti posto il sorgente:

    // test per pic 16f877a
    #define XTAL_FREQ 4MHZ
    #include
    // Fuses di configurazione
    __CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);

    #include “delay.c” // routine per ritardi
    #define LED1 RA0
    #define LED2 RA1
    #define LED3 RA2
    #define BTN RD0
    #define BTN2 RD1

    // funzione principale, eseguita all’avvio del picmicro
    void main(void)
    {

    TRISA=0b00000000;
    PORTA=0;
    TRISB=0b00000000;
    PORTB=0;
    TRISC=0b00000000;
    PORTC=0;
    TRISD=0b00000000;
    PORTD=0;
    TRISE=0b00000000;
    PORTE=0;
    ADON=0;
    ADCON1=0b00000110;
    RBPU=0; //pool up interne non attivate
    GIE=0; // INTERRUPT GENERICHE nonATTIVATE
    PEIE=0; //INTERRUPT ESTERNE non ATTIVATE
    INTE=0;
    RBIE=0;
    LED1=0;
    LED2=0;
    LED3=0;

    while(1) // eseguo un ciclo finito
    {
    LED3=LED3^1;
    DelayMs(30);

    }
    }
    a questo punto il Led 3 dovrebbe lampeggiare da solo, mentre il risultato della programmazione è il lampeggiamento del led3 ed del led1….cosa può essere.
    tra l’altro ho provato anche a programmare il pic, con il tuo programma(per sicurezza, per vedere se almeno il tuo funzionava) in cui i led si azionano tramite i pulsanti, ma praticamente non funziona nulla, i led lampeggiano entrambi da soli, ma non sentono l’intervento dei pulsanti (vorrei precisare che ho settato il registro ADCON1per dare precedenza alle uscite digitali, uso matlab8.60 e il pickit2 su window7)
    ti ringrazio!

  2. #3 da Danyele il 9 febbraio 2012

    Ciao Gianni, complimenti per le lezioni, ben strutturate e chiare, ho un piccolo problema a cui non trovo soluzione:

    Ho effettuato prima di procedere con questa prova, una semplice accensione LED con PIC16F628A, che utilizzero per tutti i miei esperimenti, e il seguente codice funziona:

    #include
    #define LEDR RB0
    #define LEDG RB3

    void main(void)
    {
    TRISA=0b00000000;
    TRISB=0b00000000;
    LEDR=0;
    LEDG=1;
    }

    una volta compilato questo codice (senza fuses) ho provveduto ad impostare i fuses mediante il “Bit Configuration” ed Esportato in un nuovo file .HEX, quest’ultimo, caricandolo mi funziona correttamente.

    Subito dopo ho provato a far lampeggiare alternativamente i due led, mediante questo codice, ho inserito tutti i file in un’unica cartella, include le funzioni delay.c e .h:

    #define XTAL_FREQ 4MHZ
    #include
    #include “delay.c”

    void main(void)
    {
    TRISA=0b00000000;
    TRISB=0b00000000;
    while(1)
    {
    PORTB=0b00001000;
    DelayMs(250);
    PORTB=0b00000001;
    DelayMs(250);
    }
    }

    Stesso procedimento per i fuses, carico il file .HEX ma non funziona nulla…in cosa sbaglio? :( non riesco a venirne a capo, eppure il codice mi sembra sia corretto…

    • #4 da Danyele il 9 febbraio 2012

      ho risolto :)))) mi è bastato scrivere la configurazione dei FUSES, scrivendo la seguente riga:

      __CONFIG (FOSC_XT & WDTE_OFF & PWRTE_ON & MCLRE_ON & BOREN_OFF & LVP_OFF & CPD_OFF & CP_OFF );

      i fuses da screre li ho presi direttamente nel file pic16f628a.h presente in HITEC C :)

  3. #5 da patrick87 il 11 marzo 2012

    Ciao Giovanni,
    complimenti per le lezioni, sono veramente ben fatte. Sono un principiante e sto seguendo le tue lezioni, ma proprio per la compilazione di questo codice ho trovato problemi. Utilizzo MPLABX con un PIC16LF1507. La configurazione dei fuses non l’ ho scritta proprio nel programma perchè non me la riconosce per via della versione aggiornata di HI-TECH C. Quando faccio partire il programma lampeggia ma non con la velocità che mi aspettavo 250 ms. Ho provato anche solo ad accendere il Led senza farlo lampeggiare settando ad ’1′ logico la porta dove è collegato il led ma continua a lampeggiare sempre alla stessa velocità. Dimenticavo di dirti che utilizzo il PICKIT 3 con una breadboard. Non riesco a capire perchè lampeggia sempre…

    • #6 da Giovanni Bernardo il 11 marzo 2012

      Se non metti la word di configurazione come vuoi che ti funzioni il programma? Oddio si può anche non mettere se uno ha bene a mente quali sono i settaggi di default, ma se già partiamo da questo presupposto che uno non usa la word di configurazione… si parte col piede sbagliato. Se poi hai scritto il nuovo programma che mette solo a 1 logico, ma il led continua a lampeggiare… vuol dire che il pic non l’hai programmato! Non hai ricompilato il programma e stai caricando sempre lo stesso hex.

  4. #7 da patrick87 il 11 marzo 2012

    Innanzitutto grazie per la celere risposta. Comunque anche io pensavo che non lo stessi programmando perciò ho preso un altro pic uguale nuovo e l’ho programmato mettendogli il programma dove ho settato la porta del LED = ’1′ logico. Ma continua a lampeggiare. Tu dici che il fatto che lampeggi ad intervalli non voluti oppure lampeggi anche se lo programmo che deve solo accendersi possa dipendere dal fatto che non ho configurato i fuses?

    • #8 da patrick87 il 14 marzo 2012

      Alla fine ho risolto. Ho configurato le word di configurazione che ho letto sul datasheet e tutto ok. Grazie!!

  5. #9 da LelloGi il 16 marzo 2012

    Salve,
    ho eseguito alla lettera l’installazione di MPLAB versione 8.60 che c’era sul dischetto allegato al PicKit2 e ho provato a compilare il sorgente main.c allegato a questa lezione con il compilatore Hi-Tech versione 9,83.
    Ho inserito, come consigliato la macro “_legacy_headers” ma mi da questa serie di errori:

    HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.83
    Copyright (C) 2011 Microchip Technology Inc.
    (1273) Omniscient Code Generation not available in Lite mode (warning)
    Error [800] led _lampeggiante.as; 45. undefined symbol “UNPROTECT”
    Error [800] led _lampeggiante.as; 45. undefined symbol “DEBUGDIS”
    Error [800] led _lampeggiante.as; 45. undefined symbol “WRTEN”
    Error [800] led _lampeggiante.as; 45. undefined symbol “DUNPROT”
    Error [800] led _lampeggiante.as; 45. undefined symbol “LVPDIS”
    Error [800] led _lampeggiante.as; 45. undefined symbol “BORDIS”
    Error [800] led _lampeggiante.as; 45. undefined symbol “PWRTEN”
    Error [800] led _lampeggiante.as; 45. undefined symbol “WDTDIS”
    Error [800] led _lampeggiante.as; 45. undefined symbol “HS”

    ********** Build failed! **********

    Come editor uso Notepad++ versione 5.9.8
    Mi dava errori anche prima di inserire la macro.
    Dove ho sbagliato?
    Mi manca qualche settaggio su MPLAB

  6. #11 da LelloGi il 17 marzo 2012

    Salve,
    queste sono le prime righe del file “main.c”.

    //#include
    #define XTAL_FREQ 20MHZ // questo è utilizzato dalle routine di ritardo contenute in Delay.C
    #include // contiene i nomi mnemonici di registri e porte

    // Fuses di configurazione
    __CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);

    #include “delay.c” // routine per ritardi
    #define LED RD0 // invece di scrivere RD0, scriverò LED, così mi è più facile ricordare

    Non avendo dimestichezza con questo linguaggio ho preso alla lettera lo scritto

  7. #12 da LelloGi il 18 marzo 2012

    Salve,
    inserita questa riga, come consigliato:
    #define _LEGACY_HEADERS
    prima di #include ho compilato regolarmente il file.

  8. #13 da marco89lisa il 13 aprile 2012

    Prima di tutto Grazie per il suo lavoro e per la sua dedizione!! oggi mi sono messo a “giocare” con un 16f684 è ho cercato di accendere 2 uno su RC2 l’ altro su RC3. il mio main iniziale è stato
    TRISA=0;
    TRISC=0;
    while (1)
    {
    led1=1;
    DelayMs (500);
    led2=1;
    DelayMs (500);
    led1=0;
    led2=0;
    DelayMs (1000);
    }

    di fatto però solo un led si accende e si spegne mentre l’altro no; stessa cosa ma al contrario se scambio le prime 2 righe per accendere i led.
    Ora sono riuscito a risolvere utilizzando PORTC=…… però non riesco a capire perché il codice in origine è sbagliato.
    Mi illumini. Grazie

    • #14 da Giovanni Bernardo il 13 aprile 2012

      DelayMS accetta un char come parametro. Ergo non ci puoi mettere nè 500 nè 1000 ma massimo 255.
      Secondariamente: non utilizzate più queste funzioni di ritardo, obsolete e imprecise ma sfruttate le routine di ritardo incluse in hitech-c
      __delay_ms(valore) basta definire __XTAL_FREQ (valore in Hz), senza includere nulla

      • #15 da marco89lisa il 13 aprile 2012

        La ringrazio per il suo tempo;
        quindi per i ritardi uso i comandi che ha scritto cambiando ovviamente il valore??

      • #16 da Jvb il 15 novembre 2013

        In XC8 è errato scrivere __XTAL_FREQ. La parola (simbolo) giusto è _XTAL_FREQ, ovvero con un solo underscore (_). Invece le funzioni __delay_ms() e __delay_us() vogliono il doppio underscore.
        Saluti

  9. #17 da LelloGi il 13 aprile 2012

    Salve,
    ho preparato questo listato nella speranza di vedere accendere in sequenza i led sulla Freedom II ma mi rimane sempre e solo acceso il primo Led e non riesco a capire dove sbaglio.
    L’Hitech-C lo compila senza errori.
    Il listato e’ questo:
    #define _LEGACY_HEADERS
    #include
    #define XTAL_FREQ 20MHZ // questo è utilizzato dalle routine di ritardo contenute in Delay.C
    #include “delay.c” // routine per ritardi

    // Fuses di configurazione
    __CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);

    //#define LED(a) PORTD=1<7; a++)
    {
    LED(a); // shift a sinistra di una posizione ogni 200mS
    DelayMs(200);
    }

    } // Fine ciclo continuo

    }
    //———— fine——————————-

    Saluti

    Lello

  10. #19 da LelloGi il 14 aprile 2012

    Ha ragione, nella fretta del fare “copia” /”incolla” mi sono perso delle righe del listato.
    Ho provato ad alternare i due “#define LED(a)………., ma il risultato e’ sempre identico.
    Provero’ la riga di programma che mi ha consigliato.
    Quello corretto e’ questo:
    #define _LEGACY_HEADERS
    #include
    #define XTAL_FREQ 20MHZ // questo è utilizzato dalle routine di ritardo contenute in Delay.C
    #include “delay.c” // routine per ritardi

    // Fuses di configurazione
    __CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);

    //#define LED(a) PORTD=1<7; a++)
    {
    LED(a); // shift a sinistra di una posizione ogni 250mS
    DelayMs(250);
    }
    } // Fine ciclo continuo
    }

    Saluti

  11. #21 da LelloGi il 14 aprile 2012

    Non e’ spam e non e’ colpa mia se facendo copia e incolla dal programma “Notepad++” mi crea questo inconveniente.
    Adesso ho copiato solo la parte centrale che e’ questa:
    CMCON=0b00000111; // Disabilito i comparatori e i convertitori
    PORTD=0b00000000; // Setto porte D a livello basso
    TRISD=0b00000000; // Imposto i registri tristato come uscite
    char a=0;
    while(1) // eseguo un ciclo finito
    {
    PORTD=1;
    DelayMs(100);
    for (a=0; a>7; a++)
    {
    LED(a); // shift a sinistra di una posizione ogni 250mS
    DelayMs(250);
    }
    } // Fine ciclo continuo

    } // Fine main
    Prima di premere il rasto “inserisci un cimmento” che si trova in fondo alla vostra pagina vedo tutto il listato completo, quando viene evidenziato dal vostro sito sperisce una parte, non so cosa dire…
    Se la cosa crea disturbo, vado altrove

  12. #28 da LelloGi il 18 aprile 2012

    Ok! adesso mando il vecchio file via email.
    Saluti

    Lello

  13. #29 da hernan il 2 maggio 2012

    ho cercato di compilare il sorgente giusto per fare una prima prova, però non ci sono riuscito, mi sapresti dire perchè gentilmente? ho MPLAB v8.84 e HI-TECH v9.83 , grazie per questo bellissimo corso, cercherò di donare qualcosa il prima possibile…

    Make: The target “C:\Users\Ruben\Desktop\elettronica hernan\projectos en c\projecto1\main.p1″ is up to date.
    Executing: “C:\Program Files\HI-TECH Software\PICC\9.83\bin\picc.exe” -oled.cof -mled.map –summary=default,-psect,-class,+mem,-hex –output=default,-inhx032 main.p1 –chip=16F877A -P –runtime=default,+clear,+init,-keep,+osccal,-download,-resetbits,-stackcall,+clib –opt=default,+asm,-debug,-speed,+space,9 –warn=0 -D__DEBUG=1 –double=24 –float=24 –addrqual=ignore -g –asmlist “–errformat=Error [%n] %f; %l.%c %s” “–msgformat=Advisory[%n] %s” “–warnformat=Warning [%n] %f; %l.%c %s”
    HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.83
    Copyright (C) 2011 Microchip Technology Inc.
    (1273) Omniscient Code Generation not available in Lite mode (warning)
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “UNPROTECT”
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “DEBUGDIS”
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “WRTEN”
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “DUNPROT”
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “LVPDIS”
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “BORDIS”
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “WDTDIS”
    Error [800] C:\Users\Ruben\AppData\Local\Temp\spg.; 45. undefined symbol “HS”

    ********** Build failed! **********

  14. #31 da zavvy il 12 maggio 2012

    Ciao… sono Andrea…
    Dopo ore e ore di prove non andate a buon fine mi rivolgo a voi esperti.
    Sto provando a far funzionare il programmino di questo articolo con un PIC16F1826 (ho solo questo a disposizione).

    Vi allego il programma…
    #define XTAL_FREQ 20MHZ // questo è utilizzato dalle routine di ritardo contenute in Delay.C
    #include // contiene i nomi mnemonici di registri e porte

    // Fuses di configurazione
    __CONFIG (FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_ON & FCMEN_ON);
    __CONFIG (WRT_OFF & PLLEN_ON & STVREN_ON & BORV_LO & LVP_ON);

    #include “delay.c” // routine per ritardi
    #define LED RB3

    // funzione principale, eseguita all’avvio del picmicro
    void main(void)
    {

    // imposto i registri tristato in maniera tale che tutte le porte siano configurate come pin di uscita
    TRISA=0b00000000;
    TRISB=0b00000000;

    while(1) // eseguo un ciclo finito
    {
    LED=LED^1;
    DelayMs(200);
    }// Fine ciclo continuo

    } // Fine main

    Sull’uscita RB3 vedo sempre 3.1Volt (Tensione di alimentazione del PIC

    Cosa sbaglio??

    Grazie in anticipo.

    Ciao

  15. #33 da mrbitume il 14 maggio 2012

    Salve, ho un piccolo dubbio riguardo le varie frequenze di esecuzione sul PIC.
    Definendo il circuito base come il suo, con un clock da 20MHz ho provato a misurare la frequenza con cui vengono eseguite le istruzioni sul PIC16F877A, usando l’istruzione:
    while(1){
    RC6^=1;
    }
    Secondo la teoria il pin dovrebbe commutare da un valore alto ad un valore basso, e viceversa, con una frequenza di 5MHz (20MHz / 4). Mi aspetto quindi che la commutazione avvenga in 200 nanosecondi. Invece, effettuando misurazioni con l’oscilloscopio, trovo che la commutazione avviene in 1 microsecondo (ovvero alla frequenza di 1 MHz). Come è possibile?
    Premetto che ho impostato il FUSE in HS.

    • #34 da Giovanni Bernardo il 14 maggio 2012

      Beh questo è normale. Non può provare la frequenza dei cicli istruzione con un’operazione del genere. Cerco di farle capire: il compilatore cerca di ridurre le istruzioni scritte in C in assembler. La bontà di un compilatore sta proprio in questo: cercare di farlo nella maniera più efficiente possibile (ed efficiente non necessariamente equivale a minor numero di istruzioni). L’XOR viene tradotto in istruzioni assembler, così come il while(1) che viene tradotto come un goto. Capisce quindi che la sua istruzione, che lei ha scritto in una sola riga, viene in realtà tradotta come una sequenza di più istruzioni, quindi è normale che all’oscilloscopio non risulta la frequenza che si aspetta.
      Per verificare la frequenza reale dovrebbe fare una cosa del tipo:

      PORTC=0b01000000;
      PORTC=0;
      PORTC=0b01000000;
      PORTC=0;
      PORTC=0b01000000;
      PORTC=0;
      PORTC=0b01000000;
      (ripetuto all’infinito)

      Non può nemmeno fare semplicemente RC6=1; RC6=0; ecc perchè anche questo viene tradotto con una serie di istruzioni che prevedono la lettura e riscrittura di tutto il banco di porte C.

  16. #35 da phobos79 il 2 agosto 2012

    Salve Giovanni,
    Ho alcuni problemi con il mio PicKit3, ho provato a collegarci un 16F876 ma non riesco a farglielo vedere in MPLAB IDE mi dice sempre che devo collegare un dispositivo al pickit3 e poi ho un’altro problema con alcuni files che delay.c va a cercarsi quando provo a compilare il programma semplicissimo del led che lampeggia…
    non mi trova questi files
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    Non so come devo fare per farglieli trovare e dove cercarli sopratutto, aiutami per favore, sono anni che non metto mano su qualche pic, ho cominciato con il programmatore di Sergio e poi ho abbandonato tutto in quanto il pc con la parallela ha cominciato a dare problemi…
    Grazie.
    Stefano.

    • #36 da Giovanni Bernardo il 2 agosto 2012

      Il pic deve essere alimentato per poter essere riconosciuto. Scegli prima il pic: Configure -> Select Device poi puoi alimentarlo: Programmer -> Settings -> Selezioni scheda power, voltage dovrebbe gia stare a 5.000, spunti la casella “Power target circuit from pickit3″

      Per il resto non so dirti, wordpress cancella la roba. se si tratta di files tra apici (maggiore e minore), hai qualche problema col compilatore oppure hai digitato male i nomi.

  17. #37 da phobos79 il 3 agosto 2012

    Grazie Gianni, domani mattina farò la prova con le spunte nella sezione power e vediamo se risolvo…
    Il 16f876 che ho è vecchiotto e non riscordo se è funzionante o meno, cmq domani mattina vado a prenderne degli altri per studiarci un pò sopra…
    Per quanto riguarda i files che il compilatore non mi trova, dove devo farglieli cercare?
    C’è una cartella in Hitech-c da passargli per farglieli trovare?
    Files del tipo pic.h, delay.c, delay.h, common.h ecc ecc
    Ho visto nelle lezioni che tu utilizzi un programma chiamato pickit2 per flashare i pic con il file .hex, per il pickit3 esiste lo stesso programma o la programmazione si può fare solo tramite mplab?
    Grazie ancora dell’aiuto.
    Stefano.

    • #38 da Giovanni Bernardo il 3 agosto 2012

      pic.h va messo tra maggiore e minore (apici), perchè è un file da cercare nel percorso del compilatore. delay.c va messo tra virgolette perchè lo cerchi nello stesso percorso di dove si trova il main. Se usi le routine che si trovano qui, devi includere solo delay.c. common.h pure va messo tra apici. Il pickit3 non ha l’applicazione standalone ufficiale come il pickit2, ne ha una demo che si trova nel forum della microchip ma non funziona bene al 100%. L’hex lo puoi caricare anche col pickit3 da dentro mplab. Quando hai selezionato il pic e hai dato tensione, dal menu file scegli import e il file hex viene caricato i memoria, quindi premi il pulsante program.

      • #39 da phobos79 il 3 agosto 2012

        Allora…
        All’interno di delay.c ci sono gli include dei files che hitec-c dovrebbe trovarsi da solo e sono tra tipo common.h desc.h irq.h printk.h ecc ecc ma quando vado a compilare in mplab mi da sempre l’errore che non trova il file e precisamente dice:
        delay.c; 41.19 can’t open include file “common.h”: No such file or directory e se elimino per provare il file common.h mi da gli errori sugli altri files, non trova nessuno dei files con estensione .h che dovrebbe trovarsi in automatico all’interno del compilatore… gli devo passare qualche path in particolare per farglieli trovare?
        Sto diventando pazzo!
        Il pic funziona perchè alimentandolo con la spunta come dicevi tu adesso non mi da l’errore di connessione al pic…
        Grazie Gianni della pazienza! :)
        Stefano.

        • #40 da phobos79 il 3 agosto 2012

          Chiedo scusa Gianni ma avevo sbagliato a linkare il file delay.c che non era lo stesso che utilizzi tu negli esempi… Sorry…
          L’unica cosa che non va è che se compilo con il delay.c che è in questa pagina insieme ai file di esempio il compilatore mi da il seguente errore e non mi compila: delay.c; 12. function “_DelayMs” redefined
          Se al posto di delay.c gli passo delay.h compila il tutto ma il led rimane acceso fisso…
          Grazie ancora.

  18. #41 da phobos79 il 4 agosto 2012

    Ok tutto risolto…
    Ora funziona alla perfezione e il pic oscilla alla grande : )
    Devo solo scrivere un appunto che magari può essere utile per qualcun’altro e cioè di non aggiungere altri files oltre al main.c nel progetto in quanto se si aggiunge il file delay.c il compilatore restituisce l’errore seguente:
    delay.c; 41.19 can’t open include file “common.h”: No such file or directory
    Quindi basta inserirlo solo all’interno del codice come #include e il compilatore lo trova da solo senza errori.

    Un’ultima domanda Gianni, ho comprato un 16F876/A stamattina e se provo a programmarlo mi da un errore strano con le memorie del pic che purtroppo ora non ho alla mano perchè al momento sto scrivendo con un’altro pc… il circuito è lo stesso del pic che funziona, ho tolto quello che va ed ho inserito quello nuovo per provarlo e non si riesce a programmarlo…
    Sarà difettoso o non riesco perchè è un /A mentre l’altro non lo è? (in teoria non dovrebbe esserci differenza, giusto?)
    Me lo faccio sostituire?

    Grazie ancora Gianni.
    Stefano.

  19. #42 da merloindiano il 15 agosto 2012

    buongiorno a tutti e buon ferragosto!
    vi devo ringraziare e devo ringraziare Lei Giovanni perche dopo un annetto di tentativi ho deciso di approfittare delle ferie per provare a fare qualcosa con il pickit2 acquistato un anno, o più, fa.
    l’adattamento del codice di questa semplice lezione al mio 16F690 è stato per me un po arduo.. devo ancora lavorare per imparare le cose basilari.
    oggi proverò a capire perche il programma come l’avete scritta voi
    LED=LED^1;
    DelayMs(250);
    mentre invece
    LED=1;
    DelayMs(250);
    LED=0;
    DelayMs(250);
    che è la stessa cosa si…
    ora voglio provare a confrontare i due file generati dal compilatore…
    e poi a cercare di capire perche il simulatore incluso in MPlab non mostra lo stato della porta cambiare mentre programmando il pic il led lampeggia!

    so che è una stupidata.. per me è un rompicapo… prima di usare un display touch che comunica con una scheda remota tramite qualche interfaccia complessa mi ci vorrà un po!

    grazie a tutti quelli che lavorano su questo sito per gli articoli che mi hanno aiutato sia per l’aiuto morale a provare ed imparare.

    Saluti, mirco

  20. #43 da I.LOVE.NAPLES il 30 agosto 2012

    Ciao, volevo essere illuminato su una cosa: fino a qualche giorno fa non mi era chiara l’impostazione dei fuses di configurazione. Leggendo i datasheets mi è parso di capire che oltre a configurarli nel modo in cui li configuri tu, è possibile anche un altro “modo”, ovvero tramite bit. Per capirci meglio, è vero che scrivere:

    __CONFIG= 11111100110010;

    equivale a scrivere:

    __CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);

    ??? Giusto? (tutto ciò nell’ambito del PIC 16F877A)

    • #44 da Giovanni Bernardo il 30 agosto 2012

      Se stiamo ancora a questo penso che hai saltato qualche paragrafo. Ovvio che si! se metti 0b(tutti zeri e uni) hai scritto in binario, se metti 0x(numero) hai scritto in esadecimale, se scrivi un numero semplice senza 0(lettera) hai scritto in decimale, se usi i nomi mnemonici, hai scritto delle parole che rappresentano numeri. I “modi” sono sempre la stessa cosa, cambia la maniera in cui rappresenti un numero, al compilatore non importa niente di come lo scrivi, lui vede sempre e solo lo stesso numero, in qualsiasi modo tu lo scriva. L’utilizzare nomi mnemonici è ovviamente più semplice per il programmatore, perchè legge a cosa si riferiscono ed è una notazione “portabile”, nel senso che un nome mnemonico può significare lo stesso per due pic diversi sebbene QUEL bit si trovi in posizione diversa: ergo la stessa word di configurazione scritta con nomi mnemonici può andare bene per due pic, dal momento che i nomi mnemonici sono associati col file H del pic in questione, cosa non necessariamente vera se usi la notazione binaria.

      • #45 da I.LOVE.NAPLES il 30 agosto 2012

        Chiarissimo… Ovviamente non manca l’errore da parte mia perchè scrivendo in binario, dovevo anteporre alla sequenza, il prefisso “0b”. Quindi non:

        “__CONFIG= 11111100110010;”

        ma

        “__CONFIG= 0b11111100110010;”

        La domanda era per avere una conferma in quanto l’avevo capito da me leggendo qua e là… Grazie 1000!!!

        • #46 da Giovanni Bernardo il 30 agosto 2012

          e continui a sbagliare in quanto __config è una macro e non una variabile a cui assegnare un valore, quindi non devi assegnargli un valore [__config=numero] ma passargli un parametro [__config(numero)]

          • #47 da I.LOVE.NAPLES il 30 agosto 2012

            Quindi dato che il parametro che voglio passare alla macro è un numero binario dovrei scrivere precisamente così:
            __CONFIG(0b11111100110010);
            Giusto?
            Mi scuso per la mia ignoranza ma la mia voglia di imparare e più forte della voglia di dire “lasciamo perdere” xD
            In ogni caso io prima avevo provato a compilare un programma settando i fuses in questo modo:
            __CONFIG= 11111111110011;
            ma il compilatore non mi ha dato alcun errore creando il file .hex con successo…

  21. #48 da mrcamarium il 9 settembre 2012

    #define _XTAL_FREQ 4000000
    #include
    #include

    // configurazione
    __CONFIG (FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF);

    // Connessioni
    #define Led1 GP2 // GP2 -> SIN
    #define Led2 GP1 // GP1 -> LAT
    #define Led3 GP0 // GP0 -> CLK
    #define Led4 GP3 // GP0 -> CLK
    #define OUT GP4 // GP0 -> CLK

    // funzioni
    void main(void)
    {
    while(!HTS); // Stabilizza oscilatore interno
    CMCON=7; // Disabilita Comparatore.
    ADCON0 = 0; // Disabilita convertitore A/D
    TRISIO = 0b00000000; // Tutti i pin in out
    {
    // Programma
    int indice = 0;
    while(1) (indice <10)
    {
    LED=1;
    indice++;
    DelayMs(0,0625); // 16-27KHz
    LED=0;
    }
    }
    } // \main
    dopo finito i dieci cicli vorrei che il programma incrementasse il valore del delay come posso fare?

  22. #49 da ngen il 4 novembre 2012

    Salve,
    complimenti per la guida (sarà la milionesima volta che viene detto è davvero è una bella guida !!!:)) Stavo realizzando questo piccolo progettino su una breadboard l’unica differenza è che uso un quarzo da 33KHz (sopra c’è scritto T033.100) vorrei gentilmente sapere innanzitutto nella cartella sorgente che ho scaricato in quale file e dove devo modificare la frequenza?? inoltre ho provato così ma non succede niente al led ho controllato il circuito oltre 10 volte ho cambiato il quarzo e niente da fare non si accende proprio

    Ringrazio in anticipo

    Ngen

    • #50 da Giovanni Bernardo il 5 novembre 2012

      Ciao.
      Credo sia da 33,1 KHz, ma su due piedi non ti saprei dire se è possibile utilizzare questo tipo di quarzi sul 16F877. Ho dei dubbi. Ad ogni modo quello che è importante è la word di configurazione, nella quale va impostato il tipo di quarzo (High Speed HS, “normale” XT). Riguardo alla frequenza, questa serve solo per la gestione dei ritardi ma non al funzionamento del pic stesso, in questo caso specifico del programma cambi la variabile xtal_freq. Dato che in questo esempio si fa uso dei vecchi nomi mnemonici, leggiti questo: http://www.settorezero.com/wordpress/hitec-c-compiler-i-nuovi-nomi-mnemonici-che-causano-errori-nei-vecchi-programmi/

    • #51 da ngen il 5 novembre 2012

      Ciao si nella guida 2 che hai fatto sia alla pagina 145 del datasheet del pic16f877A c’è scritto per 32KHz devo usare 2 condensatori da 33pf che difatto ho montato secondo la guida che mi hai lincato sui nomi nuovi io ho usato il nome nuovo per tutte le fuses risulatato ho semplicemente modificato il file che hai gentilmente messo per il downlad:

      #define XTAL_FREQ 32KHZ // questo è utilizzato dalle routine di ritardo contenute in Delay.C
      #include // contiene i nomi mnemonici di registri e porte

      // Fuses di configurazione
      __CONFIG ( FOSC_LP & WDTE_OFF & PWRTE_ON & LVP_OFF & LVP_OFF & CPD_OFF & WRT_OFF & DEBUG_OFF & CP_OFF);

      #include “delay.c” // routine per ritardi
      #define LED RD0 // invece di scrivere RD0, scriverò LED, così mi è più facile ricordare

      // funzione principale, eseguita all’avvio del picmicro
      void main(void)
      {

      // imposto i registri tristato in maniera tale che tutte le porte siano configurate come pin di uscita
      TRISA=0b00000000;
      TRISB=0b00000000;
      TRISC=0b00000000;
      TRISD=0b00000000;
      TRISE=0b00000000;

      while(1) // eseguo un ciclo finito
      {
      LED=LED^1;
      DelayMs(250);
      }// Fine ciclo continuo

      } // Fine main

      nella config ho utilizzato FOSC_LP perchè è a bassa frequnza il csristallo e ho utilizzato i nuovi nomi mnemonici perchè uso la nuova versione di hitec… per gli altri 2 file delay.h e delay.c li ho cambiato così: delay .c

      /*
      * Delay functions
      * See delay.h for details
      *
      * Make sure this code is compiled with full optimization!!!
      */

      #include “delay.h”

      void
      DelayMs(unsigned char cnt)
      {
      #if XTAL_FREQ 32KHZ
      unsigned char i;
      do {
      i = 4;
      do {
      DelayUs(250);
      } while(–i);
      } while(–cnt);
      #endif
      }

      e delay.h

      /*
      * Delay functions for HI-TECH C on the PIC
      *
      * Functions available:
      * DelayUs(x) Delay specified number of microseconds
      * DelayMs(x) Delay specified number of milliseconds
      *
      * Note that there are range limits: x must not exceed 255 – for xtal
      * frequencies > 12MHz the range for DelayUs is even smaller.
      * To use DelayUs it is only necessary to include this file; to use
      * DelayMs you must include delay.c in your project.
      *
      */

      /* Set the crystal frequency in the CPP predefined symbols list in
      HPDPIC, or on the PICC commmand line, e.g.
      picc -DXTAL_FREQ=32KHZ

      or
      picc -DXTAL_FREQ=33KHZ

      Note that this is the crystal frequency, the CPU clock is
      divided by 4.

      * MAKE SURE this code is compiled with full optimization!!!

      */

      #ifndef XTAL_FREQ
      #define XTAL_FREQ 32KHZ /* Crystal frequency in KHz */
      #endif

      #define MHZ *1000L /* number of kHz in a MHz */
      #define KHZ *1 /* number of kHz in a kHz */

      #if XTAL_FREQ >= 10KHZ

      #define DelayUs(x) { unsigned char _dcnt; \
      _dcnt = (x)*((XTAL_FREQ)/(10KHZ)); \
      while(–_dcnt != 0) \
      continue; }
      #else

      #define DelayUs(x) { unsigned char _dcnt; \
      _dcnt = (x)/((10KHZ)/(XTAL_FREQ))|1; \
      while(–_dcnt != 0) \
      continue; }
      #endif

      extern void DelayMs(unsigned char);

      la mia domanda è perchè se il circuito lo ho montato bene (presumo) il led non lampeggia cioè voglio capire se l’errore sta nella programmazione o meno ricrdo che il cristallo che uso è da 33100 Hz e onestamente non saprei nemmeno dove andare per cambiare questa impostazione cioè il file che hai messo in upload è per per una clock di 20 MHz io che uso una da 33100 Hz dovrei pure cambiare qualcosa no??

      Grazie ancora
      ngen

      • #52 da Giovanni Bernardo il 5 novembre 2012

        Allora….
        Non modificare assolutamente i due file di delay, lasciali così come li hai scaricati: i define e gli if servono proprio a questo, eseguono delle scelte in base a quello che dichiari nel main.
        Solo nel main, al posto di #define XTAL_FREQ 20MHZ, metti #define XTAL_FREQ 33KHZ.
        Poi tutto il resto dovrebbe funzionare a scanso di problemi sul circuito. Se stai usando una breadboard, il problema al 99% è la breadboard. Monta tutto su una millefori.
        Se sulla millefori continui ad avere il problema, il potrebbe essere un problema di librerie: pare difatti che quelle routine di delay non siano precise al di fuori di un certo range di frequenze dei quarzi… ad ogni modo per vedere solo lampeggiare un led dovrebbero funzionare!

        In questo caso utilizzi le routine di delay integrate nell’Hitec, in pratica non devi fare null’altro che fare queste modifiche:

        #define _XTAL_FREQ 33000

        (vedi che c’è un underscore : _XTAL_FREQ e NO XTAL_FREQ, e la frequenza espressa in HERTZ)

        e le funzioni di ritardo diventano:

        __delay_ms(x) invece di DelayMs(x)
        __delay_us(x) invece di DelayUs(x)

        Unico contro: il valore di ritardo deve per forza essere un valore costante e non una variabile. In questo caso va bene. Fai queste modifiche, ma ripeto: se usi una breadboard è tutto inutile, perchè le capacità parassite influenzano il comportamento dell’oscillatore e in più le breadboard causano sempre falsi contatti.

  23. #53 da ngen il 5 novembre 2012

    purtroppo niente ho settato main.c così

    //*************************************************
    // CORSO PROGRAMMAZIONE PICMICRO
    // http://www.settorezero.com
    //
    // modulo: main.c
    // autore: Bernardo Giovanni
    // data: 18/08/09
    // descrizione: lampeggia un led su RD0
    // picmicro: PIC16F877A
    // clock: 20MHz
    //
    //*************************************************

    #define _XTAL_FREQ 33000 // questo è utilizzato dalle routine di ritardo contenute in Delay.C
    #include // contiene i nomi mnemonici di registri e porte

    // Fuses di configurazione
    __CONFIG (FOSC_LP & WDTE_OFF & PWRTE_ON & LVP_OFF & LVP_OFF & CPD_OFF & WRT_OFF & DEBUG_OFF & CP_OFF);

    #include “delay.c” // routine per ritardi
    #define LED RD0 // invece di scrivere RD0, scriverò LED, così mi è più facile ricordare

    // funzione principale, eseguita all’avvio del picmicro
    void main(void)
    {

    // imposto i registri tristato in maniera tale che tutte le porte siano configurate come pin di uscita
    TRISA=0b00000000;
    TRISB=0b00000000;
    TRISC=0b00000000;
    TRISD=0b00000000;
    TRISE=0b00000000;

    while(1) // eseguo un ciclo finito
    {
    LED=LED^1;
    __delay_ms(250);
    }// Fine ciclo continuo

    } // Fine main

    e i file delay lo ho lasciati così come hai detto e ancora niente chissà quando sarò che vedro luce :)!!!! comunque sia uso una breadboard e quasi quasi rimpiango di averle comprate considerando che già avevo sentito questo problema se non hai qualche altra dritta da darmi allora proverò sulla millefori!! ..

    • #54 da Giovanni Bernardo il 5 novembre 2012

      Se usi le routine di delay dell’Hitech, le routine in delay.c non ti servono, quindi puoi pure eliminare l’include relativo. Se così non ti funziona… mi dispiace, ma è la breadboard quasi sicuramente, quei quarzi di frequenza così bassa, poi, ne risentono assai. Prova a toccare il quarzo con le mani per vedere se qualcosa succede.

      • #55 da ngen il 6 novembre 2012

        Va bene oggi proverò a cambiare circuito.
        giusto per curiosità ma la mclr è obbligatoria connetterla a +5v ( cioè e obbligatorio creare il circuito di reset??)

        ngen

        • #56 da Giovanni Bernardo il 6 novembre 2012

          Sui PIC in cui MCLR può essere un ingresso… ovviamente non è obbligatorio a patto di impostare MCLR nella word di configurazione. Sugli altri pic… ovvio che deve stare a +5V altrimenti il pic non funziona. Dalla tensione sul pin MCLR dipende la modalità di funzionamento del pic: per i pic a 8bit, mclr a 5V/3.3V mette il pic in modalità esecuzione programma, mclr a 13V mette il pic in modalità programmazione, mclr a GND mette il pic in reset.

  24. #57 da Glauco il 15 novembre 2012

    Al momento di caricare il programma nel picMicro attraverso pickit2 compare come da indicazioni la scritta “Pickit 2 found and connected”
    ma in “device” non compare nessun menu a tendina e al posto di “Select Part” compare la scritta “Unsupported part (ID=FFFF)”.
    Risolvo il problema (lo dico per chi avesse la stessa difficoltà) andando in “Programmer” e selezionando “Manual device select”
    Poi importo il file lampeggia_led.hex con successo. Dopo aver collegato il PICKit2 al circuito e premuto il tasto Write compare la scritta “No device detected”. Ho ricontrollato i collegamenti fra pickit e il controllore e sembra tutto a posto. Provo a trasferire tutto da breadboard a
    millefori o pensate che possano esserci altri problemi?
    Un grazie a tutti
    Glauco

    • #58 da Giovanni Bernardo il 18 novembre 2012

      Il problema è la Breadboard

      • #59 da Pasquale il 28 febbraio 2013

        Ciao Giovanni e saluti a tutti coloro che leggono. Mi aggiungo, ovviamente, al coro di coloro che ti ringraziano e che apprezzano ENORMEMENTE il tuo lavoro. Ho visto che molti trovano dei malfunzionamenti che, presumibilmente sono dovuti a problemi con i circuiti o le Breadboard, volevo far notare che lo MPLAB ha al suo interno un simulatore che potete attivare e far girare, una volta compilato, andando a vedere come cambiano i registri, in tal modo si ha la possibilità di verificare se è il programma che non gira, oppure è il nostro circuito ” hardware” che fa le bizze. La procedura è estremamente semplice e, poiché ho paura che sia già stata pubblicata sul sito, (non ho avuto modo di leggere tutti i commenti e tutte le lezioni e non voglio essere OT), non sto qui ad illustrarla. Se richiesto sarò ben felice di esporla . Distinti Saluti a tutti

  25. #60 da clauz67 il 27 novembre 2012

    salve a tutti, sono un novizio, e ho provato ad inserire il programma main e compilarlo ma mi esce questo errore:

    Build C:\Users\Studio\Desktop\test\lamp1 for device 16F84
    Using driver C:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe

    Make: The target “C:\Users\Studio\Desktop\test\main.p1″ is out of date.
    Executing: “C:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe” –pass1 C:\Users\Studio\Desktop\test\main.c -q –chip=16F84 -P –runtime=default –opt=default -D__DEBUG=1 -g –asmlist “–errformat=Error [%n] %f; %l.%c %s” “–msgformat=Advisory[%n] %s” “–warnformat=Warning [%n] %f; %l.%c %s”
    Error [192] C:\Users\Studio\Desktop\test\main.c; 30.1 undefined identifier “TRISC”
    Error [192] C:\Users\Studio\Desktop\test\main.c; 31.1 undefined identifier “TRISD”
    Error [192] C:\Users\Studio\Desktop\test\main.c; 32.1 undefined identifier “TRISE”
    Error [192] C:\Users\Studio\Desktop\test\main.c; 36.1 undefined identifier “RD0″
    Warning [361] C:\Users\Studio\Desktop\test\main.c; 37.1 function declared implicit int

    ********** Build failed! **********

    Da cosa puo dipendere?

    Grazie

    • #61 da Giovanni Bernardo il 27 novembre 2012

      Cerca l’articolo “i nuovi nomi mnemonici che causano errore”. Qui sul sito, barra di ricerca in alto a destra.

      • #62 da clauz67 il 27 novembre 2012

        Grazie per l’aiuto,
        ma non trovo soluzioni per questi errori:

        Error [192] C:\Users\Studio\Desktop\test\main.c; 30.1 undefined identifier “TRISC”
        Error [192] C:\Users\Studio\Desktop\test\main.c; 31.1 undefined identifier “TRISD”
        Error [192] C:\Users\Studio\Desktop\test\main.c; 32.1 undefined identifier “TRISE”
        Error [192] C:\Users\Studio\Desktop\test\main.c; 36.1 undefined identifier “RD0″

  26. #64 da matteolus.93 il 3 dicembre 2012

    Ciao grazie mille per l’utilissimo corso di programmazione!
    tuttavia vorrei chiedere il motivo della comparsa dell’errore:

    (1273) Omniscient Code Generation not available in Lite mode (warning)

    nel seguente contesto cercando di compilare la tua versione del programma …

    Build D:\PROGRAMMAZIONE\programmazione_picmicro_01\sorgenti\lampeggia led 2 for device 16F877A
    Using driver C:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe

    Make: The target “D:\PROGRAMMAZIONE\programmazione_picmicro_01\sorgenti\main.p1″ is out of date.
    Executing: “C:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe” –pass1 D:\PROGRAMMAZIONE\programmazione_picmicro_01\sorgenti\main.c -q –chip=16F877A -P –runtime=default –opt=default -D__DEBUG=1 -g –asmlist “–errformat=Error [%n] %f; %l.%c %s” “–msgformat=Advisory[%n] %s” “–warnformat=Warning [%n] %f; %l.%c %s”
    Executing: “C:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe” “-olampeggia led 2.cof” “-mlampeggia led 2.map” –summary=default –output=default main.p1 –chip=16F877A -P –runtime=default –opt=default -D__DEBUG=1 -g –asmlist “–errformat=Error [%n] %f; %l.%c %s” “–msgformat=Advisory[%n] %s” “–warnformat=Warning [%n] %f; %l.%c %s”
    HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.83
    Copyright (C) 2011 Microchip Technology Inc.
    (1273) Omniscient Code Generation not available in Lite mode (warning)
    Error [800] lampeggia led 2.as; 45. undefined symbol “UNPROTECT”
    Error [800] lampeggia led 2.as; 45. undefined symbol “DEBUGDIS”
    Error [800] lampeggia led 2.as; 45. undefined symbol “WRTEN”
    Error [800] lampeggia led 2.as; 45. undefined symbol “DUNPROT”
    Error [800] lampeggia led 2.as; 45. undefined symbol “LVPDIS”
    Error [800] lampeggia led 2.as; 45. undefined symbol “BORDIS”
    Error [800] lampeggia led 2.as; 45. undefined symbol “PWRTEN”
    Error [800] lampeggia led 2.as; 45. undefined symbol “WDTDIS”
    Error [800] lampeggia led 2.as; 45. undefined symbol “HS”

    ********** Build failed! **********

    ( so che gli altri errori sono determinati dai diversi nomi nn supportati dalla nuova versione ma l’altro errore nn lo capisco :( )
    grazie anticipate per l’aiuto.

  27. #65 da Ivo il 17 gennaio 2013

    Buongioro Giovanni Bernardo
    Ho fatto una piccola donazione per un buon caffè.
    complimenti per l’ottimo lavoro svolto in questo sito.
    Saluti
    Ivo

  28. #66 da Luigi76 il 3 febbraio 2013

    Ciao Giovanni
    BEH!! dirti grazie è il minimo sindacale. Vorrei configurare il Conf. Word Register per un PIC16F690 ma credo che i nomi mnemonici che ha hai usato per il 16F877A forse non vanno bene poichè ricevo questi errori durante la compilazione con MPLAB

    Error [223] C:\Users\Davidello\Desktop\LAMPEGGIA\main.c; 9. digit out of range
    Error [800] LAMPEGGIA.as; 45. undefined symbol “DEBUGDIS”
    Error [800] LAMPEGGIA.as; 45. undefined symbol “WRTEN”
    Error [800] LAMPEGGIA.as; 45. undefined symbol “DUNPROT”
    Error [800] LAMPEGGIA.as; 45. undefined symbol “LVPDIS”

    ********** Build failed! **********

    Potresti darmi una dritta?

    • #67 da Luigi76 il 3 febbraio 2013

      Ciao Giovanni
      forse ho risolto sotto MPLAB menu>configure>configuration bit, si trovano i vari codici mnemonici. Spuntando l’opzione
      “Configuration bit sets in code” possiamo evitare di editare la direttiva CONFIG nel programma principale. PROCEDURA RISCHIOSA!!!! vedremo :-)

  29. #68 da Antonio Mattioli il 5 marzo 2013

    Ciao Giovanni,

    dopo un periodo di varie sfortune ho ripreso a ‘robottare’ e, insieme ai mille progetti che popolano la mia mente, ho deciso di imparare ad usare i PICMicro e di decidermi a passare all’ANSI C.
    Con schiettezza ti confesso che sto seguendo sia i tuoi tutorial, sia quello di Mauro Laurenti, sia Let’s Go Pic del Prof. Gottardo sbirciando (per il momento posso permettermi solo questo) il sito di Guido Ottaviani.
    Con altrettanta schiettezza e senza problemi sono a farti SINCERI COMPLIMENTI per l’opera che svolgi con una passione che si intravvede in ogni riga che scrivi.
    Professionale, preciso e mai dispersivo.
    Più volte mi hai strappato un sorriso nelle tue raccomandazioni:” ….Vi prego, vi scongiuro, prima di…. andate a leggervi…..!”……
    Non ti nascondo l’imbarazzo di riconoscermi una grandissima ignoranza generale che mi riscontro mano a mano che leggo con avidità il tuo eccellente tutorial.
    Credo che la Centaur che mi hai regalato troverà la sua giusta collocazione in un mio prossimo robot però questa volta PICMicro based, che a questo punto ti dedicherò come parziale contributo di quanto tu abbia fatto con il tuo sito.
    Non ultimo voglio ringraziare tutti gli Utenti di SettoreZero che con il loro post completano e arricchiscono il sito con la divulgazione delle loro esperienze e tutorial.
    Non mancherò di segnalare (come è giusto che sia!) la provenienza del mio apprendimento sia su Robot Italy Forum, sia su Roboitalia forum.
    Potevo mandarti una p.m. ma mi sono sentito di complimentarmi pubblicamente come piccolo ‘acconto’ di quanto con il tempo spero di restituire.

    Con Stima

    Antonio Mattioli

    (Caronte)

    • #69 da bistefo70 il 25 marzo 2013

      Ciao giovanni come dalle tue spiegazioni del tuo articolo nuovi nomi memonici con gli header legacy,poiche il compilatore mi restituisce un errore di questo tipo alla funzione delay.c; 12. function “_DelayMs” redefined
      {
      #if XTAL_FREQ 2MHZ
      unsigned char i;
      do {
      i = 4;
      do {
      DelayUs(250);
      } while(–i);
      } while(–cnt);
      #endif
      }

      • #70 da bistefo70 il 25 marzo 2013

        Ho risolto il problema finalmente.
        in pratica rispetto a prima nel progetto “Project Wizard,ho incluso solo il Main.c,escludendo il delay.c e gli header allegati che sono rimasti nella cartella del progetto menu.
        Adesso funziona,anche se non ho capito la differenza di procedimento del compilatore,tra includere tutti i file insieme,oppure allegare solo il main.c.

        • #71 da Francesco il 8 aprile 2013

          Ciao,

          il file main.c, alla linea 20, contiene la direttiva
          #include “delay.c”.
          In fase di compilazione, il precompilatore sostituisce tale linea con l’intero contenuto del file delay.c, per cui tale file è, praticamente, già contenuto nel progetto.
          Quando lo includi esplicitamente con il “Project Wizard”, creii una duplicazione del codice contenuto in delay.c e in particolare della definizione della funzione DelayMs, di qui il messaggio di errore del compilatore “DelayMs redefined” (in C un oggetto può essere dichiarato più volte, ma deve essere definito esattamente una volta sola).

  30. #72 da Jack90 il 12 maggio 2013

    salve sono nuovo del sito…e un po che scrivo programmi in C,ultimamente scrivo i miei programmi con mplab x ide v1.70 ed uso il nuovo compilatore messo a disposizione dalla stessa microchip mplab xc8…Il problema che mi presenta continuamente è il seguente:
    newmain.c:12: error: can’t open include file “delay.h”: No such file or directory
    ho provato ad includere la cartella delay.h nel header file ma niente il problema sussiste non riesco a venirne a capo ho provato anche a copiare la cartella delay nella cartella del compilatore xc8 ma niente..Ho scritto diversi programmi ma non riesco a compilarli sempre per lo stesso identico errore
    cosa può essere?

  31. #73 da marco84 il 21 maggio 2013

    ciao ho realizzato praticamente lo stesso progetto e il mio LED non lampeggia ma rimane acceso….sapete per caso aiutarmi???
    ho inserito correttamente il file delay.c !!!

  32. #74 da chip_x il 14 ottobre 2013

    Salve, dopo aver compilato e programmato il pic, il tutto è partito al primo colpo! quello che non riesco a fare, e che invece facevo in picbasic modificando solo il tempo di ritardo nel listato, è cambiare il tempo di lampeggiamento da 250ms a 1 sec.
    Ho provato a modificare il tempo di 250 ms nel main.c e delay.c ma niente da fare.
    Grazie.
    chip_x

  33. #76 da Ezio il 21 ottobre 2013

    Salve, sto utilizzando MPLAB IDE v.8.88 per creareun programma semplice per il pic 16F628A. Volevo utilizzare il clock interno e nei “fuses di configurazione ho messo la seguente striga:
    // Fuses di configurazione
    __CONFIG (FOSC_INTOSC & PWRTEN & BORDIS & LVPDIS & UNPROTECT);

    Quando lo vado a compilare mi da questo errore:
    Error [800] led_singolo.as; 45. undefined symbol “FOSC_INTOSC”.
    Ho letto le note dei nuovi nomi mnemonici ma non ho trovato niente al riguardo, mentre non so come interpretare e scrivere le informazioni lette sul dataSheet a pagina 96.

  34. #77 da Jvb il 15 novembre 2013

    Jvb :
    In XC8 è errato scrivere __XTAL_FREQ. La parola (simbolo) giusta è _XTAL_FREQ, ovvero con un solo underscore (_). Invece le funzioni __delay_ms() e __delay_us() vogliono il doppio underscore.
    Saluti

  35. #78 da sgrillus09 il 11 dicembre 2013

    salve sono nuovo…ho ripreso dopo un po la programmazione e questo sito mi è stato utilissimo!!!!
    ma ho un problemino nella fase di programmazione del pic, quando vado su midrange/standard configuration mi da questo messaggio “pickit2 vpp voltage level error. check target andretry operation”.
    da cosa puo dipendere?

  36. #79 da sgrillus09 il 23 dicembre 2013

    sgrillus09 :
    salve sono nuovo…ho ripreso dopo un po la programmazione e questo sito mi è stato utilissimo!!!!
    ma ho un problemino nella fase di programmazione del pic, quando vado su midrange/standard configuration mi da questo messaggio “pickit2 vpp voltage level error. check target andretry operation”.
    da cosa puo dipendere?

    ho risolto il problema del voltaggio(errore nel disegnare il circuito), ma ora ne ho un altro: quando seleziono midrange/standard non mi permette di selezionare il pic, e mi diche “no device detected”.
    grazie mille in anticipo.

  37. #80 da lucap il 4 gennaio 2014

    Salve sono iscritto da un po, e trovo questo sito eccezionale in chiarezza e contenuti. Da poco ho iniziato a programmare i pic solo che programmati la prima volta riesco a leggerli, lo porto sulla basetta lo alimento e dopo lo riporto per leggerlo e qui arriva il problema, il pic risulta all protect e ad un altra lettura no device detected. Questa e la mia config word su pic16f628a ( hs, wdtdis,pwrten,bordia, lvpdis, unprotect)

    Ho omesso le and per semplicità di scrittura.

    Per favore qualcuno può aiutarmi? Grazie in anticipo.

  38. #81 da Glauco il 11 maggio 2014

    Salve, in un primo momento ero riuscito a far lampeggiare il led, poi il pickit ha cominciato a darmi ” No device detected” al momento di scrivere il programma sul pic16f877a.
    Ho provato a seguire le indicazioni del troubleshooting -PICMicro che non vengono più riconosciuti dal PICkit? L’errore “No Device Detected” – ma quando premo Erase dopo aver selezionato “Use VPP First Program Entry” mi dà ancora “No Device Detected”. La logica dei collegamenti è corretta altrimenti non sarei riuscito a programmare il pic la prima volta e ho testato tutti i collegamenti con una sonda. Che posso fare?
    Cordiali saluti
    Glauco

  39. #83 da Dario92 il 17 maggio 2014

    Salve, ho provato a modificare il programma di accensione del led (giusto per capire delle cose) cercando di fargli fare prima dei lampeggi di un secondo e poi lampeggi da 250 millisecondi tramite 2 cicli for. Sono un po’ arrugginito con il C, ma non credo che ci siano dei problemi nel programma, ma comunque il led continua a lampeggiare come il file della guida, nonostante abbia cancellato il “vecchio” programma e inserito questo:

    #define XTAL_FREQ 20MHZ

    #include

    __CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);

    #include “delay.c”

    #define LED RD0

    void main(void)
    {

    TRISA=0b00000000;
    TRISB=0b00000000;
    TRISC=0b00000000;
    TRISD=0b00000000;
    TRISE=0b00000000;

    int i,j;

    while(1){
    for(i=0;i=5;i++){
    LED=LED^1;
    DelayMs(1000);
    }
    for(j=0;j=10;j++){
    LED=LED^1;
    DelayMs(250);
    }
    }
    }

    Il compilatore non da nessun errore quindi genera anche il file .hex. Sto utilizzando un pic16f877a. La ringrazio in anticipo per la risposta.

  40. #84 da FrancoSid il 27 maggio 2014

    Salve io ho fatto un semplice programma che quando premo un pulsante mi da’ un uscita alta se no bassa. Quando ho programmato il micro mi leggeva l’ingresso che avevo appena accendo la scheda e l’uscita rimaneva uguale qualunque cosa facessi. Ho provato a simularlo su mplab e mi fa la stessa cosa e mi compare il messaggio che devo dare un impulso sincrono. Non riesco a capire cosa devo fare, ho provato a cambiare versione di mplab e compilatore ma niente. Anche il mio prof di sistemi ha provato a risolvere questo problema e non ci è riuscito, sapete dirmi cosa posso fare?

Devi essere collegato per lasciare un commento.

settorezero.com e il logo Zroid™ ©2007÷2013 Giovanni Bernardo - E' vietata la copia e la distribuzione anche parziale dei contenuti di questo sito web senza l'esplicito consenso dell'autore.
I contenuti di settorezero.com sono distribuiti sotto una licenza Creative Commons Attribuzione-Non Commerciale-Non Opere derivate 2.5 Italia a cui vanno aggiunte le condizioni d'uso definite nel disclaimer.
settorezero.com e tutti i suoi contenuti sono tutelati dalla legge sul diritto d'autore per cui i trasgressori sono perseguibili a norma di legge.
Creative Commons BY-NC-ND 2.5
Il tema di questo sito è basato sul tema Fusion per wordpress, realizzato originariamente da digitalnature e fa uso del plugin Wassup per il computo delle statistiche. Per contattare l'autore siete pregati di utilizzare la sezione contatti.
Per essere aggiornato con tutte le novità di settorezero.com seguici anche anche su Facebook Twitter Tumblr Blogspot Youtube.