Finalmente 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:
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:

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:
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:

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

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

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

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

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:

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:

Premiamo quindi salva, ritorneremo nella finestra precedente:

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

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

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

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:
![]()
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:

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:

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

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”:

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

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

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:

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:

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
File di supporto alla terza lezione del corso di programmazione picmicro in C (1683)» Vai all’ indice delle lezioni e delle risorse del corso di programmazione
Articoli che potrebbero interessarti
Se desiderate che settorezero continui a rimanere gratuito e fruibile da tutti, non copiate il nostro materiale e segnalateci se qualcuno lo fa

Questo sito e tutto il suo contenuto sono distribuiti sotto la licenza 








#1 da odessos il 13 gennaio 2011
FORSE NON TUTTI SANNO CHE…
Facciamo un appunto per quanto riguarda l’utilizzo della funzione
“DelayUs(x)”.
Questa funzione che crea appunto un ritardo , utilizza un ciclo “while continue” ripetuto x volte, dove x è il parametro che noi andiamo ad inserire nella funzione.
Bene, questo ciclo utilizza cinque istruzioni macchina, e se consideriamo una frequenza -Fosc- pari a 20Mhz, il PIC (16F877A) impiega 1,4 us per terminare il ciclo.
In effetti è possibile verificare l’esatto ritardo utilizzando il famoso programma di esempio del LED lampeggiante.
Tolto il tempo necessario per attivare e disattivare la porta il ritardo impostato và moltiplicato per 1,4: ciò significa che se imposto 100us in realtà il ritardo sarà di 142us. Tutto questo è verificabile utilizzando un oscilloscopio o un data-scope, ma ancora meglio il simulatore di PIC “PIC Simulator IDE v6.86″, utilissimo strumento che permette di analizzare e testare un programma step by step misurando anche il tempo di esecuzione di ogni singola istruzione.
Per quanto riguarda, invece, il valore in MHZ che si inserisce all’inizio del programma “XTAL_FREQ xMHZ”, bisogna considerare che l’algoritmo utilizza delle divisioni quindi il risultato decimale viene ignorato
In sostanza la variabile utilizzata nel ciclo “while continue” cambia di valore se impostiamo una frequenza pari o superiore a 24MHZ (raddoppio e più del valore del tempo) oppure uguale od inferiore a 6MHZ (si dimezza il valore del tempo o addirittura 1/3 del valore se impostiamo una freq pari a 4MHZ).
Sarà quindi oppurtuno in fase di progetto tenere in considerazione l’errore grossolano che questa funzione ottiene, l’errore stimato è circa del 40%
Saluti a tutti, spero di essere stato utile.
#2 da Giovanni Bernardo il 14 gennaio 2011
Utilissimo. Avevo difatti discusso di questa cosa nel forum di Sergio Fiocco. Facendo le prove con l’oscilloscopio difatti si nota chiaramente che i ritardi non sono corretti. Se invece utilizzi le routine che si trovano su microchipc (e che stanno pure qui nella sezione picmicro/librerie) i ritardi sono precisissimi, verificati con l’oscilloscopio.
#3 da Antonino il 21 gennaio 2011
Davvero molto interessante, da neofita quale sono ho trovato la lezione spiegata in modo impeccabile.
Di veloce realizzazione.
Complimenti
Antonino
#4 da flep il 25 gennaio 2011
Ho seguito l’articolo e mi sto accingendo a mettere in pratica qualcosina.
Sto usando la freedomII del buon Laurenti con a bordo un 16F877A.
Ho provato a spingermi un poco oltre il semplice esempio di questa lezione, invogliato dalla comodità offertami dalla scheda di sviluppo e dal picKIT2.
Per esempio, inizializzando lo stato degli 8 led presenti sulla scheda secondo uno schema alternato (led 1,3,5,7 accesi e led 2,4,6,8 spenti), ho constatato che il ciclo while(1), li fa basculare ON_OFF alternati producendo un piacevole effetto Supercar.
Ho tentato quindi di ottenere l’arresto della routine in questo modo:
int indice = 0;
while (indice <10)
{
LED=LED^1;
indice++;
DelayMs(250);
}
Mi aspettavo di vedere il lampeggio del led fermarsi… e invece il led continua imperterrito
Dove sbaglio?
filippo
#5 da Giovanni Bernardo il 26 gennaio 2011
sbagli dove sbagliano tutti: il programma, terminato quel ciclo, cosa deve fare? giunge al termine, il pic si resetta e ricomincia daccapo. Dopo quel while mettici un while(1) e vedi che il programma si ferma
#6 da Video Lab il 7 febbraio 2011
Grazie ! Anche io come l’altro utente ho provato a modificarlo, ma non capivo perchè continuasse a lampeggiare…
Ora è tutti chiaro !
Saluti Nino
#7 da flep il 27 gennaio 2011
Grande Giovanni!
E’ vero, funziona!!!
Quindi deduco che quel secondo “while” seguito da (1) senza nulla dopo sta a dire:
“Finchè dura la condizione per cui 1 = 1, esegui ciò che segue (cioè nulla)”
e tutto questo avviene dopo aver eseguito quanto impartito dal primo ciclo “while” cioè:
1 accendi il led e incrementa di uno “indice”
2 spegni il led e incrementa di uno “indice”
…
n spegni il led e incrementa di uno “indice” e siccome il valore di “indice” ha raggiunto 10, passa all’istruzione successiva cioè “fai nulla”.
#8 da Giovanni Bernardo il 27 gennaio 2011
L’ho già spiegato in altri commenti e mi sa che ci devo fare un articolo perchè questo problema è comune. Supponiamo di scrivere un programma in C per PC, un programma consolle. Lanciamo il programma, al termine dell’esecuzione, cosa succede? I comandi vengono restituiti alla consolle. Un programma in C sul pic cosa fa una volta terminato? A chi deve restituire i comandi se non c’è il sistema operativo? Allora la CPU fa la cosa più logica che può fare: si resetta, per cui il programma ricomincia daccapo e tu non te ne accorgi. Per questo motivo si fa in modo che il programma non termini mai e tutte le istruzioni principali, da eseguire sempre, vengono incluse in un ciclo infinito. Nel tuo caso, dopo aver eseguito il programma, questo si deve fermare e non fare piu niente, per cui nel while(1) non ci metti niente e il pic rimane in un loop infinito, il che evita che la CPU esegua il reset.
#9 da gncarlo il 1 febbraio 2011
Complimenti! Davvero un bel corso!
Sono contento di aver trovato questo sito ed in particolar modo queste lezioni sui PicMicro realizzate in modo molto comprensivo anche per chi non è proprio preparato su questo mondo.
Complimenti ancora a Giovanni Bernardo per la sua pazienza e competenza.
Ciao a tutti.
#10 da Luciano il 6 febbraio 2011
Bellissimo corso, complimenti vivissimi… ho caricato il programmino per far lampeggiare il led sulla scheda FreedomII e così pure anche sulla scheda Micro-GT dell’ing. Gottardo e su ben tre PIC 16F877A diversi ma su entrambe le schede oltre al led che lampeggia regolarmente, mi si accendono anche altri led in maniera casuale e addirittura su porte diverse, neppure citate nel programma didattico… forse bisogna specificare che i pin e le porte non usate siano sempre a “0″? Sono un newbie nella programmazione… :(
#11 da Giovanni Bernardo il 6 febbraio 2011
All’avvio le porte si trovano o in uno stato indefinito o in uno stato ben definito come specificato nel datasheet, nelle tabelle che illustrano il funzionamento delle porte. E’ ovvio che se hai altri led su altre porte e le porte non le setti, lasciandole come sono all’avvio, quei led possono essere accesi o spenti.
#12 da Luciano il 6 febbraio 2011
Chiarissimo e tempestivo… ma allora come mai sono l’unico che ha notato questo “inconveniente”? il main è pari pari quello del corso… :( Grazie comunque per il chiarimento.
#13 da Giovanni Bernardo il 6 febbraio 2011
Forse perchè quel main lo feci sulla freedom I che non ha i led
#14 da Luciano il 6 febbraio 2011
Allora: per essere sicuro di non avere pin “flottanti” ho aggiunto le cinque righe che vedi dopo il TRISE:
TRISA=0;
TRISB=0;
TRISC=0;
TRISD=0;
TRISE=0;
PORTA=0b00000000;
PORTB=0b00000000;
PORTC=0b00000000;
PORTD=0b00000000;
PORTE=0b00000000;
e non ho risolto nulla… :( una volta su due-tre che accendo la Freedom2, casualmente mi si accendono altri led… stessa prova effettuata anche sulla Micro-GT di Gottardo e lì si vede ancor meglio (visto che i led sono presenti anche sui Port B e C) la casuale accensione di altri led… evidentemente non può essere colpa dell’hardware ma di qualcos’altro…
#15 da Giovanni Bernardo il 6 febbraio 2011
Prova a disattivare il convertitore A/D:
http://www.settorezero.com/wordpress/perche-il-led-che-ho-collegato-sulla-porta-rxy-non-si-accende-disattivare-comparatore-e-convertitore-ad/
#16 da Luciano il 6 febbraio 2011
Niente… non cambia nulla… :(
#17 da Giovanni Bernardo il 6 febbraio 2011
Allora hai qualche altro problema
#18 da Lemorlenny il 13 febbraio 2011
Complimenti, ho googlato per settimane a cercare decenti tutorial in inglese e invece era qui, sottomano.
#19 da Faustino il 25 febbraio 2011
Ciao e innanzitutto complimenti sinceri, io sono alle prime armi e anzi ho comprato la fodera della spada (ICD3) ma nono ho ancora il coltellino svizzero (arriva venerdì sotto tuo suggerimennto quale) che spero che si trasformi in una spada.
Volevo chiederti riguardo questa lezione e quella passata riguardo i tristori: ho capito che i singoli pin vanno impostati a nostra scelta sia che li vogliamo Input (uno logico) o Output (0 logico).La scorsa lezione hai parlato anche del terzo stato: alta impedenza. come te lo spieghi? per spiegarmi faccio un esempio: mi aspettavo che l’input fosse alta impedenza poiché deve leggere la tensione da fuori e non dovrebbe inciderci, come ad esempio un tester in modalità di lettura tensione ha una resistenza di ingresso idealmente infinita, al contario gli output di tensione che sia 0 logico o 1 logico dovrebbero avere una resistenza di uscita idealmente a 0 essendo paragonabili a dei generarori di tensione. Spero di essermi spiegato.
Grazie
Fausto
#20 da Giovanni Bernardo il 26 febbraio 2011
Non arrivo a capire che vuoi dire o se stai ribadendo cose già dette…
Il pin quando è ingresso, sta in alta impedenza perchè non deve influire con l’esterno e deve portarsi allo stato imposto dall’esterno. Pin come ingresso = alta impedenza. Se il pin deve funzionare come uscita, lo setti a 1 o a 0 (in PORT) a seconda dello stato che gli vuoi dare.
Detto in altro modo:
Se nel registro TRIS (tristato, serve a SETTARE il terzo stato), metti zero… allora non hai settato il terzo stato e lo stato del pin lo configuri col registro PORT SCRIVENDO 1 o 0, se nel registro TRIS setti il bit, vuol dire che hai settato il terzo stato e quindi il pin va in alta impedenza funzionando cosi come ingresso e lo stato al quale verrà imposto dall’esterno te lo LEGGI dal registro PORT.
Detto in altro modo ancora:
se il bit in TRIS è 1 => porta come ingresso => PORTx lo usi in lettura
se il bit in TRIS è 0 => porta come uscita => PORTx lo usi in scrittura
Io è così che interpreto il meccanismo e il nome che hanno dato ai registri. Poi ammetto che ci sono varie scuole di pensiero e ognuno interpreta a modo suo il concetto.
#21 da vegas il 6 marzo 2011
Salve,veramente una bella idea questo Blog,fatto molto bene, con spiegazioni molto chiare adatte a chi come me , è alle prime armi con questi fantastici componenti.
Detto questo, vengo alla prima richiesta di aiuto, dal momento che prima avevo sempre preso il file .hex e lo messo dentro il PIC seza fare i passaggi da te descritti ero sempre riuscito a portare atermine l’operazione, ma, questa volta provando ausare MPLAB IDE v8.63 seguendo la tua lezione mi sono imbattuto in un Build failed! di seguito mostro il contenuto del messaggio:
Build C:\Users\BR3\Desktop\877\lampeggia_led for device 16F877
Using driver C:\Program Files\HI-TECH Software\PICC\9.80\bin\picc.exe
Make: The target “C:\Users\BR3\Desktop\877\delay.p1″ is out of date.
Executing: “C:\Program Files\HI-TECH Software\PICC\9.80\bin\picc.exe” –pass1 C:\Users\BR3\Desktop\programmazione_picmicro_01\sorgenti\delay.c -q –chip=16F877 -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”
Make: The target “C:\Users\BR3\Desktop\877\main.p1″ is out of date.
Executing: “C:\Program Files\HI-TECH Software\PICC\9.80\bin\picc.exe” –pass1 C:\Users\BR3\Desktop\programmazione_picmicro_01\sorgenti\main.c -q –chip=16F877 -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\HI-TECH Software\PICC\9.80\bin\picc.exe” -olampeggia_led.cof -mlampeggia_led.map –summary=default –output=default delay.p1 main.p1 –chip=16F877 -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”
(1273) Omniscient Code Generation not available in Lite mode (warning)
HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.80
Copyright (C) 2010 Microchip Technology Inc.
Error [237] C:\Users\BR3\Desktop\programmazione_picmicro_01\sorgenti\delay.c; 12. function “_DelayMs” redefined
********** Build failed! **********
Come dicevo sopra mi sembra di aver seguito le istruzioni correttamente ma pare che mi serva un aiutino.
Altra curiosità nella cartella che ho scaricato ci sono atri 2 files oltre al MAIN.C , potresti darmi qualche info su come si generano e la funzione che svolgono nell’ambito del programma generale.
Grazie saluti Vegas
#22 da Giovanni Bernardo il 6 marzo 2011
quando compili la seconda volta un programma che hai già compilato, usa il pulsante rebuild , che sta affianco a build. in questo modo vengono cancellati i file vecchi. Il problema penso sia dovuto al fatto che nel programma hai incluso in piu di un punto le routine di delay. includi solo delay.c nel main e basta, non lo devi mettere pure nel progetto. Gli altri files generati hanno varie funzioni, c’è un eventuale file .err che contiene gli errori, un file .as che è l’equivalente in assembler del programma che hai scritto, poi ci sono vari altri file che sono intermedi di compilazione, file che illustrano il consumo di memoria ecc… per un utilizzo amatoriale non ti servono. Ti servono se vuoi approfondire.
#23 da Giovanni Bernardo il 6 marzo 2011
se ti riferisci agli altri due files dell’esempio, sono le routine di ritardo. come si generano? Io li scrivo con il blocco note, o meglio con notepad++ cos’è un file h e cos’è un file c l’ho già spiegato
#24 da vegas il 6 marzo 2011
Grazie 1000, per quanto riguarda l’errore di compilazione non mi puoi aiutare? Saluti
#25 da Giovanni Bernardo il 6 marzo 2011
L’ho detto: hai incluso più di una volta le routine di delay, lo devo scrivere ancora? Hai incluso più di una volta le routine di delay. Di sicuro le hai messe pure nel progetto. Quando dico di includere solo main nel progetto? Le persone non so perchè includono tutti i file e poi tutti hanno sempre gli stessi errori. Ora lo scrivo a caratteri cubitali.
#26 da lublink il 11 marzo 2011
Salve sto provando da un po ma non riesco a compilare con maplab! Mi da il seguente errore:
Build C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\1led for device 16F877A
Using driver C:\Program Files\HI-TECH Software\PICC\9.81\bin\picc.exe
Make: The target “C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.p1″ is out of date.
Executing: “C:\Program Files\HI-TECH Software\PICC\9.81\bin\picc.exe” –pass1 “C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\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\HI-TECH Software\PICC\9.81\bin\picc.exe” -o1led.cof -m1led.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 (PRO Mode) V9.81
Copyright (C) 2010 Microchip Technology Inc.
Licensed for evaluation purposes only.
This licence will expire on Tue, 26 Apr 2011.
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “UNPROTECT”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “DEBUGDIS”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “WRTEN”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “DUNPROT”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “LVPDIS”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “BORDIS”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “PWRTEN”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “WDTDIS”
Error [800] C:\Users\An\Documents\Programmi c++ pic\led lampeggiante\main.c; 18. undefined symbol “HS”
********** Build failed! **********
ora non capisco quale sia il problema. Ho segiuto la guida attentamente. SOS!!
Andrea Di Filippo
#27 da Giovanni Bernardo il 11 marzo 2011
I simboli “DEBUGDIS”,”WRTEN”,”DUNPROT”,”HS” ecc ecc lo sai cosa sono? Sono i nomi mnemonici delle word di configurazione. Cosa dice l’errore? Simbolo non definito. Vedo che usi la versione di hitech-C 9.81. Se fai questa domanda vuol dire che non hai letto questo articolo: http://www.settorezero.com/wordpress/hitec-c-compiler-i-nuovi-nomi-mnemonici-che-causano-errori-nei-vecchi-programmi/
#28 da Faustino il 13 settembre 2011
Caio Giovanni,
ho scaricato la versione nuova, il v8.76 e l’hi-tech 9.82, e ho gli stessi problemi di vegas. Dato che il mio dubbio
non ho preso pari pari la tua sorgente, SENZA METTERCI MANO aggiungendo come spieghi nell’articolo la stringa
#define XTAL_FREQ 20MHZ // questo è utilizzato dalle routine di ritardo contenute in Delay.C
#define _LEGACY_HEADERS
#include // contiene i nomi mnemonici di registri e porte
#include
etc.
facendo doppio click sull’errore si apre il file delay.c dandomi errore alla prima parentesi graffa del DelayMs:
DelayMs(unsigned char cnt)
{
Hai altre idee? non vorrei che abbia settato male l’hi-tech, questo dubbio l’ho perchè quando ho scaricato MPLAB non era presente dentro la scelta dei compliatori, allora l’ho scaricato a parte, installato,e forse le impostazioni in “Set Language tool Location” non sono corrette.
Spero che tu mi dia una mano.
Grazie
#29 da lublink il 11 marzo 2011
Grazie mille ora funziona alla perfezione! Non ci avevo proprio fatto caso! Ti ringrazio per la guida veramente efficiente e per la risposta chiara e immediata. Ti vorrei domandare un’altra cosa! Dove posso trovare un’elenco di tutti i nomi mnemonici esistenti? Ti ringrazio infinitemente!
Andrea Di Filippo
#30 da Giovanni Bernardo il 11 marzo 2011
I nomi mnemonici si trovano nei file header del pic che usi. Con questa versione del compilatore dovrebbero essere uguali agli stessi che trovi anche nel datasheet. Non esiste un elenco dei nomi mnemonici: bisogna spulciarsi il file header e quando non si capisce un nome mnemonico a cosa fa riferimento, si da un occhio al datasheet. I nomi mnemonici in realtà sono delle variabili associate ai registri: vedi che affianco al nome mnemonico c’è una chiocciola e un valore: quella chiocciola sta ad indicare che la variabile (il nome mnemonico) rappresenta il contenuto della locazione di memoria specificata dopo la chiocciola. Se vedi il datasheet, nelle prime pagine c’è la mappa della memoria: li è indicato chiaramente ogni registro in quale locazione di memoria si trova.
#31 da lublink il 11 marzo 2011
Ma se non conosco i loro funzionamenti come faccio a sapere che ne ho bisogno??? grazie!
#32 da Giovanni Bernardo il 11 marzo 2011
I loro funzionamenti si leggono nel datasheet e molte cose le ho già spiegate negli articoli… di più cosa vuoi che ti posso dire? Lezioni private non ne posso fare…
#33 da a.screm il 13 marzo 2011
Ciao Giovanni, innanzitutto ti devo fare i complimenti per il corso di programmazione PIC, grazie oltre ad aver rispolverato le mie vecchie conoscenze di programmazione in C, sto imparando parecchie cose interessanti sui circuiti elettronici. Ho imbastito per la prima volta l’intero circuito partendo dall’alimentazione fino al microcontrollore tutto su breadboard.Per ringraziarti ti lascio un piccolo contributo che spero ti motivi ancor di piu’ a continuare cosi’.
Mi piacerebbe molto poter analizzare cosa succede nel mio circuito con un oscilloscopio (che purtroppo non ho)ti vorrei chiedere se secondo te è possibile progettare un piccolo oscilloscopio casalingo basato su PIC,ma forse chiedo un po’ troppo..comunque di nuovo tanti complimenti e ciao.
Alessandro
#34 da Giovanni Bernardo il 13 marzo 2011
Ciao e grazie. Un semplice oscilloscopio può sicuramente essere realizzato con un dsPic. Esistono pure progetti che utilizzano pic18 ma mi risulta difficile pensare che si tratti di qualcosa di realmente utilizzabile. Con i dsPic ci sono già alcuni progetti molto interessanti in giro, tra cui questo: http://projectproto.blogspot.com/2010/09/android-bluetooth-oscilloscope.html
#35 da Haru il 13 marzo 2011
Ciao, volevo chiedere: come mai utilizzi una libreria esterna per il delay? nel senso: ANSI C tra le funzioni integrate ha anche una istruzione __delay(x) che funziona in cicli, più una __delay_ms(x) e __delay_us(x) che contano rispettivamente in milli e microsecondi.
Ho notato anche che questa funzione, integrata direttamente nell’ansi c, è molto più precisa…
Stavo provando a calibrare un orologio con un 84A , e lo stesso valore di delay in MS con la libreria scaricata da qua impiega il doppio del tempo che fa passare la funzione integrata del compilatore.
anche confrontandola con un orologio la funzione del compilatore è più “realistica”. certo, magari non serve a molto per far lampeggiare un led, ma è comunque utile.
#36 da Giovanni Bernardo il 13 marzo 2011
Non è l’ANSI C che ha le funzioni di ritardo integrate. L’ANSI C è una serie di specifiche, non un compilatore. E’ l’Hitech-C che ha quelle funzioni. Perchè non le uso? Perchè quelle funzioni richiedono che l’argomento passato sia una costante. Cosa significa?
Se vuoi fare __delay_ms(20); lo puoi fare. Ma se vuoi fare:
unsigned char a=20;
__delay_ms(a);
non lo puoi fare.
Quindi: se nel tuo codice i ritardi sono fissi, ok puoi usare le funzioni integrate. Basta includere la macro _XTAL_FREQ. Se hai necessità che i ritardi siano variabili, non le puoi usare. Che sono imprecise lo so. Ne abbiamo discusso piu volte, introducono un ritardo di quasi il doppio di cio che si imposta. Per questo motivo ora sto usando le routine che trovi nella sezione picmicro/librerie.
#37 da Haru il 14 marzo 2011
Si, per ora utilizzo solo ritardi fissi.
Sai se la funzione __delay (e affini) lavorano via software o utilizzando i timer del pic?
perchè vorrei provare ad utilizzare il timer1 come contatore asincrono e osc esterno per creare una specie di RTC (leggasi configurare il timer0 in modo da avere un interrupt al secondo che gestisce l’orario hh:mm:ss), è possibile?
Stamattina ho dato un’occhiata ai datasheet, e su quello del 777 dice che si può fare un RTC software, con tanto di esempio ASM (che penso integrerò nel programma in C), però sul datasheet dell’887 non c’è scritto niente a riguardo. Eppure i timer dei due pic mi sembra abbiano le stesse caratteristiche.
Mi sfugge qualcosa?
(non so se è molto o poco inerente dato che ho tirato fuori il discorso delay (e mi scuso se non lo è), magari si può continuare la discussione da un’altra parte)
#38 da Giovanni Bernardo il 14 marzo 2011
Funzionano tutte con de i NOP. L’RTC software si fa utilizzando un quarzo da 32768 associato al timer1, non c’è nemmeno bisogno che lo scrivono sul datasheet. Basta leggere come funziona il Timer1. Se Dio vuole, l’utilizzo del Timer1 per un RTC sarà oggetto di un prossimo articolo.
#39 da Christian il 24 marzo 2011
Ciao Giovanni innanzitutto volevo farti i complimenti per il corso di PIC che mi sta permettendo di entrate a far parte del mondo dei PIC.
Per iniziare la mia avventura sto utilizzando il PIC16F876 ed un programmatore PICSTART Plus.
Purtroppo non sono riuscito a far lampeggiare il LED, questo rimane acceso fisso, cosi come la porta RA1 rimane nello stato basso. Di seguito il programma:
#define XTAL_FREQ 20MHZ
#include
__CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);
#include “delay.c”
#define LED RA0
#define PORTA1 RA1
void main(void)
{
TRISA=0b00000000;
TRISB=0b00000000;
TRISC=0b00000000;
while(1)
{
PORTA1=1;
LED=LED^1;
DelayMs(250);
}
}
Che errori ho commesso?
#40 da Giovanni Bernardo il 24 marzo 2011
Di non leggere questo: http://www.settorezero.com/wordpress/picmicro/perche-il-led-che-ho-collegato-sulla-porta-rxy-non-si-accende-disattivare-comparatore-e-convertitore-ad/
#41 da scuro83 il 4 aprile 2011
Ciao Giovanni, grazie per la risposta celere, il problema che ti ho posto precedentemente l’ho risolto (errore mio a non leggere i precedenti post).
Il problema che mi è sorto è quello di non riuscire a far funzionare correttamente la libreria delay.c. Mi spiego meglio; se utilizzo la funzione DelayUs(x) riesco a generare perfettamente un onda quadra (la visualizzo tramite oscilloscopio) ma utilizzando la funzione DelayMs(x) non ottengo niente(in uscita ho solamente un segnale costante). Utilizzando il simulatore ottengo il messaggio “Stack Error overflor”.
Ti sarei infinitamente grato se mi indirizzeresti nella giusta direzione.
Grazie Mille.
#42 da neuro_79 il 26 marzo 2011
Ciao, vorrei chiederti un paio questito sul tipo “bit”.
1) mi permette la dichiarazione del tipo bit solo come glogale o statica. Questo è il messaggio del compilatore
(HITECH 9.80):
“…\main.c; 48. bit variables must be global or static”
Perche?
2) ho creato la seguente funzione nel main:
bit Funzione(bit prova)
{
return 1;
}
con prototipo nel file settings. Compilando non ho nessun errore. Ma quando vado a chiamarla nel main
tempn = Funzione(1);
il compilatore dice che non riesce a “tradurre l’istruzione”. Questo è il messaggio del compilatore
(HITECH 9.80):
“…\main.c; 32. can’t generate code for this expression”
Perche?
Se alla funzione sostituisco semplicemente il tipo del parametro da bit a int funziona!!!!! Ma a me servirebbe lavorare con i bit.
#43 da Giovanni Bernardo il 26 marzo 2011
Il tipo BIT non lo puoi usare per dichiarare le funzioni nè come argomento nè come valore di ritorno, è chiaramente specificato nel manuale dell’Hitech-C
#44 da doc83 il 3 aprile 2011
Ciao Giovanni, posto qui di seguito un problema avuto con MPLAB IDE….
HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.81
Copyright (C) 2010 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Error [800] LED.as; 45. undefined symbol “UNPROTECT”
Error [800] LED.as; 45. undefined symbol “DEBUGDIS”
Error [800] LED.as; 45. undefined symbol “WRTEN”
Error [800] LED.as; 45. undefined symbol “DUNPROT”
Error [800] LED.as; 45. undefined symbol “LVPDIS”
Error [800] LED.as; 45. undefined symbol “BORDIS”
Error [800] LED.as; 45. undefined symbol “PWRTEN”
Error [800] LED.as; 45. undefined symbol “WDTDIS”
Error [800] LED.as; 45. undefined symbol “HS”
A quanto ho capito non riconosce i fuses, perchè dovrebbero a loro volta essere definiti nel file “pic.h” che viene incluso…. il problema è che il file viene incluso (dovrebbe darmi errore, altrimenti!) così vado ad aprire il file pic.h ma non trovo nulla in merito alla definizione di questi simboli…. come mai, dove sbaglio? Grazie! :)
#45 da Giovanni Bernardo il 3 aprile 2011
http://www.settorezero.com/wordpress/hitec-c-compiler-i-nuovi-nomi-mnemonici-che-causano-errori-nei-vecchi-programmi/
#46 da doc83 il 3 aprile 2011
In più volevo dirti che se utilizzo il file “delay.h” vuole che il clock venga definito correttamente non come XTAL_FREQ XXMHZ, ma come PIC_CLK XXXXX dove XXXXX è il numero in Hertz del valore del quarzo… concordi su questo?
#47 da Giovanni Bernardo il 3 aprile 2011
Dipende dalla funzione delay che utilizzi. Quelle dei primi esempi richiedono XTAL_FREQ, quelle degli ultimi PIC_CLK. Quelle fornite con l’hitech-C, che però come argomento vogliono solo una costante, richiedono _XTAL_FREQ (con l’underscore davanti).
#48 da marcobrucchietti il 12 aprile 2011
Salve,
Ho comprato lo starter kit pickit2.Insieme al programmatore mi è arrivata una scheda con il pic16f690 montato su zoccolo. In questa scheda ci sono anche 4 led con relative restenze limitatrici di corrente. Volevo iniziare con accendere e spegnere il led come proponi tu nel tuo articolo. Il tuo schema è molto chiaro, ma come faccio io con la scheda che mi è arrivata con il pickit2?. Scusa la domanda banale, se puoi darmi qualche dritta…
#49 da raminno il 21 aprile 2011
Salve,
Ho provato di compilare i file della lezione, purtroppo ho ricevuto questo messaggio di errore:
Build C:\programmazione_picmicro_01\test1 for device 16F877A
Using driver C:\Programmi\HI-TECH Software\PICC\9.81\bin\picc.exe
Make: The target “C:\programmazione_picmicro_01\delay.p1″ is out of date.
Executing: “C:\Programmi\HI-TECH Software\PICC\9.81\bin\picc.exe” –pass1 C:\programmazione_picmicro_01\programmazione_picmicro_01\sorgenti\delay.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”
Make: The target “C:\programmazione_picmicro_01\main.p1″ is out of date.
Executing: “C:\Programmi\HI-TECH Software\PICC\9.81\bin\picc.exe” –pass1 C:\programmazione_picmicro_01\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:\Programmi\HI-TECH Software\PICC\9.81\bin\picc.exe” -otest1.cof -mtest1.map –summary=default –output=default delay.p1 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.81
Copyright (C) 2010 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Error [237] C:\programmazione_picmicro_01\programmazione_picmicro_01\sorgenti\delay.c; 12. function “_DelayMs” redefined
********** Build failed! **********
Dove ho sbagliato?
Grazie mille
#50 da Giovanni Bernardo il 21 aprile 2011
Hai sbagliato nel fatto che non hai letto le prime lezioni dove dico che nel progetto devi includere SOLO il main.c e no tutti i file
#51 da Carlo il 23 aprile 2011
Perfetto! Fin qui funziona tutto, funziona il programmatore Propic2 clone (autocostruito e ripreso dal sito di Lorenzo Lutti), funziona il circuito di base del mitico Giovanni Bernardo, al quale va un encomio e tutta la mia ammirazione per lo squisito altruismo dimostrato in questo sito e per le sue grandi competenze e soprattutto, funziona il led lampeggiante!!!…….; per me, che sono un profano, è veramente una bella soddisfazione; ora andiamo avanti.
Grazie ancora Giovanni.
Carlo.
#52 da bombattone il 25 aprile 2011
Ciao sono alle prime armi penso di aver fatto tutto alla lettera usando i file scaricati dal sito come mai quando eseguo il tutto ho questo tipo di errore Build C:\Users\Claudio\Desktop\Nuova cartella\lampled for device 16F877A
Using driver C:\Program Files\HI-TECH Software\PICC\9.81\bin\picc.exe
Make: The target “C:\Users\Claudio\Desktop\Nuova cartella\main.p1″ is out of date.
Executing: “C:\Program Files\HI-TECH Software\PICC\9.81\bin\picc.exe” –pass1 “C:\Users\Claudio\Desktop\Nuova cartella\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\HI-TECH Software\PICC\9.81\bin\picc.exe” -olampled.cof -mlampled.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.81
Copyright (C) 2010 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
Error [800] lampled.as; 45. undefined symbol “UNPROTECT”
Error [800] lampled.as; 45. undefined symbol “DEBUGDIS”
Error [800] lampled.as; 45. undefined symbol “WRTEN”
Error [800] lampled.as; 45. undefined symbol “DUNPROT”
Error [800] lampled.as; 45. undefined symbol “LVPDIS”
Error [800] lampled.as; 45. undefined symbol “BORDIS”
Error [800] lampled.as; 45. undefined symbol “PWRTEN”
Error [800] lampled.as; 45. undefined symbol “WDTDIS”
Error [800] lampled.as; 45. undefined symbol “HS” di errore?
#53 da Giovanni Bernardo il 25 aprile 2011
Se solo si imparasse un po’ a cercare…
http://www.settorezero.com/wordpress/hitec-c-compiler-i-nuovi-nomi-mnemonici-che-causano-errori-nei-vecchi-programmi/
#54 da Giovanni Bernardo il 25 aprile 2011
Che poi la cosa bella qual è ? Che un paio di commenti più in alto c’era un altro con lo stesso identico problema e c’era pure la risposta
#55 da Giovanni Bernardo il 25 aprile 2011
Anzi… di domande simili ce ne sono più di una a quanto vedo.
#56 da marcello il 21 maggio 2011
ciao giovanni e intanto complimenti sei davvero grande ti devo porre un quesito sono riuscito a far lampeggiare i led o modificato il tuo programma e adattato per il pic 16f876 e funziona ho aggiunto altre porte e funziona tutto adesso però vorrei fare l’inverso cioè far lampeggiare il led con la massa cioè mandare i 5 volts diretti ai led a alternare la massa ho provato cosi ma io stesso mi rendo conto che e sbagliato poichè dico al led di invertire lo stato a massa ma siccome il ciclo comincia con la massa non ottieni nulla quindi per far cio dovrei fare cominciare a uscire dalla porta 5 volts giusto?
se ho datto una cavolata scusatemi dell’ignoranza a 15 giorni che mi sono messo a studiare questa materia e sono davvero a terra..
grazie anticipatemente per la risposta
while(1) // eseguo un ciclo finito
{
LED=LED^0;
DelayMs(250);
}// Fine ciclo continuo
} // Fine main
#57 da Giovanni Bernardo il 21 maggio 2011
Spero che hai capito cosa fa un’operazione di XOR tra due bit.
Cosa succede se faccio 1 XOR 1 ?
E se faccio 1 XOR 0? o 0 XOR 0 ?
#58 da marcello il 22 maggio 2011
piu o meno penso di aver capito inverte lo stato dei bit ogni 250 ms quindi se fai 1 xor 0 inverti lo stato che si trova 5v in massa giusto?
ma per esempio quello che non capisco e questo 0 XOR 0 non ha senso giusto non esegue nessuna funzione!
non prendermi per cretino ti prego sono proprio alle primissime armi..
e grazie per la risposta
#59 da Giovanni Bernardo il 22 maggio 2011
l’ XOR lo devi fare con 1! Se fai 1 XOR 0 ottieni 1, quindi al ciclo successivo ottieni 1, e quello successivo ancora 1… e il led sta sempre acceso. Nel codice hai fatto l’XOR con zero! E’ ovvio che non ottieni mai l’inversione di stato.
#60 da Giovanni Bernardo il 22 maggio 2011
vai qua: http://www.settorezero.com/wordpress/picmicro/articoli-propedeutici/ e leggiti le operazioni algebriche booleane e gli operatori di scorrimento. Se non capisci come si opera sui bit non puoi andare avanti
#61 da marcello il 22 maggio 2011
che pollo che sono nella porta arriva ogni 250 ms massa e ogni 250 ms corrente per questo o metto il positivo o metto il negativo su rd0 il led mi lampeggia comunque hihihihi quesito chiarito
riguardo 0 XOR 0 e come dico io non ha senso?
#62 da Giovanni Bernardo il 22 maggio 2011
difatti non ha senso, era per farti capire dove stava l’errore
#63 da Bord90 il 28 maggio 2011
Salve, innanzitutto mi voglio complimentare anch’io per il corso molto bello!
Volevo poi chiedere un piccolo aiuto.. Ho acquistato una scheda Pick kit 1 che programma pin da 8 a 14 pin, perciò sto cercando di fare le esperienze proposte sul pic 12F675. il programma che ho scritto è questo:
#define XTAL_FREQ 4MHZ // 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_ON & PWRTE_ON & BOREN_OFF & CPD_OFF & CP_OFF);
#include “delay.c” // routine per ritardi
#define LED GP0 // 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
ADON = 0;
ANSEL = 0b00000000;
CMCON = 0b00000000;
TRISIO = 0b00000000;
while(1) // eseguo un ciclo finito
{
LED=LED^1;
DelayMs(250);
}// Fine ciclo continuo
} // Fine main
ovviamente non si accende nulla.. dove sbaglio??
#64 da Giovanni Bernardo il 28 maggio 2011
Per quale motivo hai messo CMCON a zero?
#65 da Bord90 il 28 maggio 2011
ho letto il file che parla dei comparatori e dei convertitori analogici e ho seguito le istruzioni scritte li.. Inoltre ho controllato anche su alcuni tutorial simili gia presenti nel pick kit 1 è c’era questa voce..
Ho sbagliato?
#66 da Giovanni Bernardo il 28 maggio 2011
Se hai letto qui su settorezero.com ti posso assicurare che non hai letto bene, perchè da nessuna parte c’è scritto di mettere a zero CMCON.
Leggiti qua: http://www.settorezero.com/wordpress/picmicro/perche-il-led-che-ho-collegato-sulla-porta-rxy-non-si-accende-disattivare-comparatore-e-convertitore-ad/
#67 da Bord90 il 29 maggio 2011
Si è vero solo sul tutorial è uguale a zero..
Comunque adesso l’ho posto = 7 come c’è scritto ma non cambia nulla..
Inoltre osservo che sui pin GP5 e GP4 il led si accende anche se con una luminosità ridotta quindi devono essre ad un voltaggio minore..
Questo fenomeno accade solo sul programma scritto da me, se carico i tutorial no..
#68 da Bord90 il 29 maggio 2011
Ho fatto un’altra prova usando il pic16F684 che ha 14 pin.
Adesso il led si accende, tuttavia non lampeggia.
come mai?
#69 da Giovanni Bernardo il 29 maggio 2011
Lo sai cos’è il watchdog timer? Ti sei accorto di averlo abilitato?
#70 da Bord90 il 29 maggio 2011
No non so cos’è il watchdog timer, sono alle primissime armi perciò non mi rendo molto conto di certe cose.. devo disabilitarlo? come faccio?
#71 da Giovanni Bernardo il 30 maggio 2011
Continua a leggere gli articoli
#72 da Bord90 il 29 maggio 2011
OK scusa avevo dimenticato di disattivare il convertitore analogico adesso funziona!
#73 da Andrex.93 il 14 giugno 2011
Salve, sapete dirmi quali sono i registri del PIC 16F84A? Perchè io ho quello, e non voglio comprare il 16F877A.. Il programma l’ho iniziato cosi:
/* Autore: Andrea Paolucci
* Data: 14 Giugno 2011
* Descrizione: Lampeggiamento di 3 led
* Picmicro: 16F84A
* Clock: 4 MHz
*/
#define XTAL_FREQ 4MHZ
#include
__CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);
#include
/* uso i pin 8,9 e 10 per le uscite dei led */
#define LED1 RB1 /* pin 8 */
#define LED2 RB2 /* pin 9 */
#define LED3 RB3 /* pin 10 */
void main(void)
{
poi come continuo? e’ giusto cosi come ho scritto?
#74 da Giovanni Bernardo il 14 giugno 2011
I nomi mnemonici del 16F84A non sono quelli, o meglio non tutti. Come già detto altre volte: apri il file H del tuo pic per essere sicuro di non sbagliare. Il file H del tuo pic, con la nuova versione dell’Hitech-C si chiama semplicemente 16F84A.h e lo trovi in E:\Programmi\HI-TECH Software\PICC\9.81\include
Dato che il 16F84A è stravecchio hai soltato un paio di nomi mnemonici, e ovviamente periferiche quasi zero. Se vuoi imparare a fare qualcosa ti consiglio di lasciar perdere il 16F84A (ma pure il 16F877A se proprio lo devi comprare) e passare magari a un 16F88 (per rimanere su pic “piccoli”, ma almeno qui hai pure l’UART e altra roba), un 16F886 o 16F887.
Leggiti il file H che ti ho detto, perdici un po’ di tempo: è spulciando queste cose e facendo tentativi che vanno a vuoto che si impara. Io potrei darvi a tutti le soluzioni complete già belle e fatte (pure ora sono dovuto andare a vedere il percorso del file e comunque ci ho perso due minuti), ma che cosa vi insegnerei? Non vi rimarrebbe nulla. ok? ;)
#75 da Andrex.93 il 14 giugno 2011
ok, ho capito, grazie mille. Però, ora sono andato a vedere il file 16F84A.h, e ci ho trovato tutto questo:
#ifndef _AS16F84A_H_
#define _AS16F84A_H_
INDF equ 0000h
TMR0 equ 0001h
PCL equ 0002h
STATUS equ 0003h
#define CARRY STATUS, 0
#define DC STATUS, 1
#define ZERO STATUS, 2
#define nPD STATUS, 3
#define nTO STATUS, 4
#define IRP STATUS, 7
#define RP0 STATUS, 5
#define RP1 STATUS, 6
#ifndef _LIB_BUILD
#endif
FSR equ 0004h
PORTA equ 0005h
#define RA0 PORTA, 0
#define RA1 PORTA, 1
#define RA2 PORTA, 2
#define RA3 PORTA, 3
#define RA4 PORTA, 4
#ifndef _LIB_BUILD
#endif
PORTB equ 0006h
#define RB0 PORTB, 0
#define RB1 PORTB, 1
#define RB2 PORTB, 2
#define RB3 PORTB, 3
#define RB4 PORTB, 4
#define RB5 PORTB, 5
#define RB6 PORTB, 6
#define RB7 PORTB, 7
#ifndef _LIB_BUILD
#endif
EEDATA equ 0008h
EEADR equ 0009h
PCLATH equ 000Ah
#ifndef _LIB_BUILD
#endif
INTCON equ 000Bh
#define RBIF INTCON, 0
#define INTF INTCON, 1
#define T0IF INTCON, 2
#define RBIE INTCON, 3
#define INTE INTCON, 4
#define T0IE INTCON, 5
#define EEIE INTCON, 6
#define GIE INTCON, 7
#define TMR0IF INTCON, 2
#define TMR0IE INTCON, 5
#ifndef _LIB_BUILD
#endif
OPTION_REG equ 0081h
#define PSA OPTION_REG, 3
#define T0SE OPTION_REG, 4
#define T0CS OPTION_REG, 5
#define INTEDG OPTION_REG, 6
#define nRBPU OPTION_REG, 7
#define PS0 OPTION_REG, 0
#define PS1 OPTION_REG, 1
#define PS2 OPTION_REG, 2
#ifndef _LIB_BUILD
#endif
TRISA equ 0085h
#define TRISA0 TRISA, 0
#define TRISA1 TRISA, 1
#define TRISA2 TRISA, 2
#define TRISA3 TRISA, 3
#define TRISA4 TRISA, 4
#ifndef _LIB_BUILD
#endif
TRISB equ 0086h
#define TRISB0 TRISB, 0
#define TRISB1 TRISB, 1
#define TRISB2 TRISB, 2
#define TRISB3 TRISB, 3
#define TRISB4 TRISB, 4
#define TRISB5 TRISB, 5
#define TRISB6 TRISB, 6
#define TRISB7 TRISB, 7
#ifndef _LIB_BUILD
#endif
EECON1 equ 0088h
#define RD EECON1, 0
#define WR EECON1, 1
#define WREN EECON1, 2
#define WRERR EECON1, 3
#define EEIF EECON1, 4
#ifndef _LIB_BUILD
#endif
EECON2 equ 0089h
#endif
Quello che ti chiedo e’: cosa devo prendere di preciso?
( TI dico che la tua guida l’ho trovata stamattina, quindi sui pic so praticamente zero )
#76 da Giovanni Bernardo il 14 giugno 2011
Ma scusa che versione dell’Hitech-C hai? Nella nuova versione il file header comincia direttamente con le word di configurazione. Forse hai una versione vecchia, in ogni caso se fai la domanda vuol dire che non hai sfogliato tutto il file e che non sai nemmeno a cosa serve la word di configurazione, altrimenti i nomi mnemonici li avresti saputi trovare… o no? Dato che per il 16F84A ce ne sono solo 5 o 6 e hanno dei nomi che già conosci: era solo per farti capire quali devi togliere (che te ne potevi pure accorgere provando a compilare il programma: ti veniva dato errore di nomi non definiti)
#77 da Andrex.93 il 14 giugno 2011
ho la versione 8.70
#78 da odessos il 7 luglio 2011
all’accensione del PIC le porte si possono trovare per un istante al un livello del tutto casuale, cioè possono settarsi a 1 o a 0.
questo stato è del tutto casuale fino a chè non interviene il programma che le mette tutte a posto.
C’è un sistema che permete di forzare a 0 le porte all’accensione del PIC?
saluti a tutti
#79 da Giovanni Bernardo il 7 luglio 2011
Alcune si trovano in uno stato indefinito, altre in uno stato predefinito come specificato sul datasheet. La transizione quanto tempo vuoi che duri e che problemi vuoi che comporti? E’ così su qualsiasi MCU a meno che non ci sia qualche MCU che all’avvio ha tutti i pin in alta impedenza. Metti come prima istruzione l’impostazione delle porte.
#80 da odessos il 11 agosto 2011
Salve, mi è venuto un dubbio durante un programmazione: all’inizio di un qualsiasi programma, come spieghi in questo tutorial, bisogna inserire diverse direttive “#include” che icludono appunto, in fase di compilazione, alcuni file contenenti paramentri vari.
Uno di questi è “pic.h” che lo troviamo nelle librerie del compilatore. Questo file contiene, come sostieni, le direttive e l’elenco di tutti i nomi mnemonici utilizzati dal PIC in uso (i nomi dei registri ecc.).
Se però guardiamo all’interno del file, non ci sono questi elenchi, ma prevede l’inserimento con “#define” della sigla del PIC che usiamo: #define _16F887.
Solo così effettivamente il file “pic.h” inserisce la libreria riferita al PIC utilizzato.
In alternativa basterebbe inserire con #include il file de PIC utilizzato: tipo pic16f887.h
Il mio è solamente un dubbio infondato ò concordi che è così che funziona.
Premetto che tutti i miei programmi che ho scritto fino ad ora ho incluso solamente il file pic.h e funzionano regolarmente.
#81 da Giovanni Bernardo il 12 agosto 2011
Io continuando a leggere, un paio di righe più in basso, vedo che c’è scritto chiaramente: “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.” All’inizio scrivo le cose più semplici e poi approfondisco. Non si insegna a fare le cose riempiendo la testa di nozioni già dalla partenza.
Il pic.h “vede” il pic che stai usando, che alla fine è definito da una macro quando vai a creare il progetto , e include il file H che serve a te. Non si include mai l’H del pic direttamente: chi programma in C programma per poter riutilizzare il codice. Ci sono poi i programmatori della domenica che poi vogliono pure fare scuola ma di quelli non ne teniamo conto, quelli possono pure ricopiarsi tutti i nomi mnemonici del file h e incollarli nel main dato che per loro il copia incolla è uno stile di vita. Se non erro, se includi direttamente il file H ti si genera pure un warning dato che è stata messa appunto una direttiva #warning nei file H, che scatta se il file è stato incluso direttamente senza passare da htc.h o pic.h
In realtà, a voler essere più precisi, il file da includere non è nemmeno pic.h ma . Il file htc.h, controlla per quale tipo di mcu stiamo programmando, quindi a sua volta include e così via. Per i pic includere o è la stessa cosa, ma dato che, come dicevo bisogna programmare in maniera “portatile”, sarebbe meglio includere .
Un altro motivo per il quale non bisogna mai includere direttamente il file h del pic è che il nome potrebbe cambiare, quindi installando un’altra versione dell’hitech-c quel nome non sarebbe piu riconosciuto.
#82 da mrcamarium il 26 settembre 2011
volendo utilizzare il quarzo interno che è di 4Mhz nel PIC12F67 come devo fare?
#83 da Bruno il 30 settembre 2011
Vorrei fare una domanda sperando che nessuno si arrabbi per le banalità delle mie domande (sono un principiante).
Ho ritirato pickit3 con un icsp per pic da 20 pin (di quelli presenti su noti siti di vendita on line). i miei dubbi sono due:
-l’adattatore è per pickit2 ma mi è stato detto che va benissimo anche per il pickit3..è vero??
-ammesso che tutto funzioni…posso provare il mio programmino con solo questi due strumenti o dovrei fornire alimentazione dall’esterno? in caso negativo, potrei collgare un pulsante NA ad una porta output (1L) e ricollegarlo ad una porta input dove mi servirebbe?
Spero di essermi spiegato. (chiedo questo perchè ho scorato di comprare un alimentatore)…ihihihihih
Non vorrei collegarci uno da bancarella e bruciare tutto….:-)
Grazie a tutti.
#84 da Giovanni Bernardo il 30 settembre 2011
Non arrivo a capire cosa significa un ICSP per pic a 20 pin … L’ICSP dei picmicro è un connettore a 5/6 pin. Punto. Intendi una schedina alla quale connetti il pickit e sopra la schedina ci metti un pic a 20 pin? Il connettore ICSP del pickit2 è uguale a quello del pickit3 (ovviamente). Il pickit può fornire alimentazione al tuo circuito ma ovviamente non devi esagerare con la corrente.
#85 da Lombo il 3 ottobre 2011
Salve,
Ho seguito le lezioni fino a questo punto e non ho trovato particolari difficoltà nel comprendere i concetti espressi. Arrivato a questo punto però volevo chiedere delucidazioni sulla funzione “__CONFIG”: disponendo di un PIC diverso (In particolare io ho il 18F4431) come si modifica -Se si modifica- questa funzione?
A titolo informativo, se pur non credo che questo sia particolarmente influente (A meno di eventuali nomi mnemonici diversi) preciso che ho installato la versione 8.70 di MPLAB IDE e che durante il processo di installazione, al momento di installare Hitec-C, non appariva la possibilità di selezione dei compilatori anche per i PIC18 e dsPIC come indicato nella seconda lezione ma ho provveduto a scaricare dal sito Microchip l’ “HI-TECH C PRO for the PIC18 MCU Family V.9.66″ (Che non ho ancora provato a causa del dubbio sorto sulla funzione “”__CONFIG”)
#86 da Giovanni Bernardo il 4 ottobre 2011
Per i PIC serie 18 è consigliato utilizzare MPLAB C18 e non l’Hitec-C18. la macro __config è utilizzata dai compilatori Hitech e le parole chiave da inserire variano in funzione del pic: alcune possono essere uguali, altri possono averne altre diverse per cui assolutamente non puoi utilizzare la stessa macro config per due pic differenti. MPLAB C18 per la configurazione non utilizza la macro __config ma le direttive #pragma. Ti consiglio di leggerti il corso C18 step by step di Mauro Laurenti (www.laurtec.it)
#87 da Lombo il 4 ottobre 2011
Grazie. Mi scuso innanzitutto per non avevo notato che erano presenti tre pagine di commenti se non dopo aver inserito il mio: nelle richeste precedenti questa domanda era già stata fatta (Anche relativa ad altri PIC16) e ho visto, oltre al tutorial di C18 suggerito, che veniva citato anche un file in cui venivano elencati tutti i fuses di configurazione dei PIC18 (a questa pagina http://www.settorezero.com/wordpress/risorse/ ) per scaricare il quale occorre essere registrati. Ho appena fatto richiesta di iscrizione, nel frattempo mi permetto di suggerire, dato che effettivamente le richieste in tal senso sembrano essere tante, di editare l’articolo inserendo qualche nozione/collegamento in più su questa macro “__CONFIG” (Ad esempio rimandando alla citata pagina contenente l’elenco dei fuses dei PIC18 e, se esiste, dei PIC16) e di come si modifica per i vari PIC. Grazie di tutto e complimenti per il bel lavoro svolto!
#88 da Giovanni Bernardo il 4 ottobre 2011
Quel documento è dichiarato come obsoleto dalla microchip. Le parole chiave, per essere sicuri, dovrebbero essere prese dai file include del pic.
#89 da Lombo il 5 ottobre 2011
Ma la lista dei fuses, al di là del nome attribuitogli, rimane corretta giusto? Quindi una volta individuati gli eventuali cambiamenti nei vari nomi essa rimane valida…. O no?
#90 da gabrielegalli il 6 ottobre 2011
Buongiorno.
Ho provato a seguire l’intera procedura e premetto che ho letto e seguito i consigli della lezione sui nuovi nomi mnemonici.
Ho avuto successo per un pic16F84 come da esempio ma non per un pic24f
quando provo a compilare per un PIC24F ottengo il messaggio:
Error [141] G:\Progetti_Personali_Gabriele\C\PIC24\led_ON_OFF_2\main.c; 16.16 can’t open include file “pic.h”: No such file or directory
Premetto pure che utilizzo come compilatore HI_TECH C for dspic24.
Potrebbe gentilmente spiegarmi perchè.
La ringrazio preventivamente
Buon Lavoro
#91 da Giovanni Bernardo il 6 ottobre 2011
L’Hitech-C per dsPIC e PIC24 non è raccomandato da Microchip, probabilmente perchè non più supportato. La Microchip difatti ha acquisito l’Hitech-C e supporta unicamente il loro compilatore per PIC10/12/16. Il C30 tra l’altro è uno dei compilatori migliori e deriva dal GCC.
Ho pubblicato delle lezioni sui PIC24/dsPIC:
http://www.settorezero.com/wordpress/picmicro/dspic-e-pic24/
E sto sviluppando un progetto: http://www.orbit16.com che spero di terminare al più presto
#92 da Angelo il 25 ottobre 2011
Salve, volevo complimentarmi con chi (finalmente) ha deciso di prendere di petto la situazione e insegnare da zero il fantastico mondo dei pic.
Ho sistemato il codice per funzionare col pic 12f683 e senza quarzo esterno, tutto ok!
Ora ho modificato qualcosina (inserito altre uscite che si accendono ad intervalli di tempo a piacere) e mi servirebbe un aiutino poichè in fase di compilazione ricevo il seguente errore:
Error [800] progetto mide.as; 418. undefined symbol “_main”
a quanto ho capito l’errore si riferisce al file *.as alla riga 418, la quale cita
ljmp _main ;jump to C main() function
dove sbaglio?
#93 da Giovanni Bernardo il 25 ottobre 2011
L’errore sta nel fatto che nel tuo programma principale anzichè “main” avrai scritto qualche altra cosa. Devi rispettare pure le maiuscole/minuscole.
#94 da Angelo il 25 ottobre 2011
no no, è corretto. Ho fatto il copia\incolla dai files scaricati da questo dito e poi ho verificato più volte. “main” l’ho scritto minuscolo e le parentesi sono giuste, tot di apertura e tot di chiusura…
#95 da Giovanni Bernardo il 25 ottobre 2011
posta il codice se no non potrò mai capire
#96 da angelorosso il 26 ottobre 2011
include // contiene i nomi mnemonici di registri e porte
#include “delay.c” // routine per ritardi
#define FOSC_INTOSCIO
#define INCH TRISIO.GP0 // segnale di ingresso chiusura su GP0
#define INAP TRISIO.GP1 // segnale di ingresso apertura su GP1
#define OUT1 TRISIO.GP5 // segnale di uscita 1 su GP5
#define OUT2 TRISIO.GP4 // segnale di uscita 2 su GP4
#define OUT3 TRISIO.GP2 // segnale di uscita temporizzato (antipozzanghera)
int i=0; // variabile per conteggio delay
//prototipi di funzioni
int controllo_chiusura (int);
int controllo_apertura (int);
int check (int);
void main () //inizio programma
{
TRISIO =0b00000011; //tutte le porte sono OUT, tratte GP0 e GP1 che sono IN
GPIO = 0; // azzero le porte
ANSEL = 0; // disattivo i pin analogici
CMCON0 = 0; // disattivo il convertitore A\D
OSCCON = 0b01100101; // imposto il registro dell’oscillatore
int check (int) // funzione per il check iniziale delle uscite (prova il funzionamento dei relè, solo in fase dei test di progettazione
while (1)
{
if (INCH)
{ int controllo_chiusura (int) }
else if (INAP)
{ int controllo_apertura (int) }
} // endwhile
return 0;
} // endmain
int controllo_chiusura (int)
{
{ DelayMs(100); } // ritardo per antirimbalzo
if (INCH) // se non si tratta di un rimbalzo
{ for (i=12;i!=0;i–) //parte il conteggio dei 3 secondi (12 tranche da 250 ms)
DelayMs(250);
if (INCH) //se durante i 3 sec. arriva un secondo impulso
{
OUT1 = 1; //abilito OUT1
for (i=16;i!=0;i–) // parte il conteggio dei 4 secondi (16 tranche da 250 ms)
DelayMs(250);
OUT1=0; } //disabilito OUT1
}
}
int controllo_apertura (int)
{
{ DelayMs(100); } // ritardo per antirimbalzo
if (INAP) // se non si tratta di un rimbalzo
{ for (i=12;i!=0;i–) //parte il conteggio dei 3 secondi (12 tranche da 250 ms)
DelayMs(250);
if (INAP) //se durante i 3 sec. arriva un secondo impulso
{
OUT1 = 1; //attivo le 3 uscite
OUT2 = 1;
OUT3 = 1;
for (i=16;i!=0;i–) // parte il conteggio dei 4 secondi (16 tranche da 250 ms)
DelayMs(250);
OUT1=0; // disattivo le prime due uscite
OUT2=0;
for (i=24;i!=0;i–) // parte il conteggio di ulteriori 6 secondi (24 tranche da 250 ms)
DelayMs(250);
OUT3=0;} //disabilito OUT3
}
}
int check (int)
{ OUT1=1;
for (i=4;i!=0;i–)
{ DelayMs(250);}
OUT1=0;
OUT2=1;
for (i=4;i!=0;i–)
{ DelayMs(250);}
OUT2=0;
OUT3=1;
for (i=4;i!=0;i–)
{ DelayMs(250);}
OUT3=0;
for (i=4;i!=0;i–)
{ DelayMs(250);}
OUT1=1;
OUT2=1;
OUT3=1;
for (i=4;i!=0;i–)
{ DelayMs(250);}
}
#97 da angelorosso il 27 ottobre 2011
Provo a risponderti per punti…
- ho messo la funzione “check” nel main poichè ho messo anche le altre (controllo_chiusura e controllo_apertura). Quindi come la prima è funzione nella funzione…lo sono anche le altre, no?
- ho dichiarato le funzioni all’inizio e le ho esplicate dopo il main. Pensavo che nel main si richiamassero in quel modo. Sull’uso del tipo di dato (void, char, int, ecc..) penso di sapere le cose basilari, ho messo nell’argomento e nel tipo di dato d’uscita “int” proprio perchè le tre funzioni da me create manipolano la variabile “i” di tipo int, ecco perchè l’ho fatto.
- a dire il vero non mi è passato per la mente mettere < anzichè != , ma questo immagino sia l'ultimo dei mali!
Grazie per le correzioni!
#98 da Giovanni Bernardo il 27 ottobre 2011
Una cosa è richiamare la funzione e un’altra è dichiararla… come le avevi scritte non si capisce se la stavi dichiarando o richiamando.
#99 da giorivals il 27 ottobre 2011
ciao giovanni volevo farti una domanda ma nello scriverla mi son dato la risposta. per cui approfitto di ringraziarti ancora per il lavoro che stai facendo per noi neofiti. ciao giorivals
#100 da angelorosso il 27 ottobre 2011
Ho provato a sistemare come mi hai detto ma ricevevo sempre l’errore del main. Rileggendo gli errori di compilazione (ricordo d’aver cambiato “int main (int)” in “void main (int)” ) dove mi si diceva che la funzione main di tipo void non poteva ritornare valori ho provveduto a togliere lo zero da “return 0;” e finalmente il codice è stato compilato!!!
#101 da brunor il 28 ottobre 2011
Salve,
ringrazio intanto per aver messo a disposizione la vostra esperienza,
vorrei chiedere se è possibile avere un aiuto per capire come utilizzare il clock interno al posto di quello esterno.
il pic che stò utilizzando è il 16F690
Grazie
#102 da Giovanni Bernardo il 28 ottobre 2011
Ci sono tanti esempi di come fare. Uno degli ultimi articoli sul 12F1822 pure utilizza il clock interno. Se leggi l’articolo sul simple clock, pure faccio uso dell’oscillatore interno. Insomma basta sfogliare un po’ il sito.
#103 da simone il 3 novembre 2011
Ciao! complimenti per il corso!
Volevo chiederti se è possibile inserire come argomento della funzione __CONFIG () direttamente il numero binario corrispondente alla configurazione invece del nome mnemonico (per esempio __CONFIG (010011etch…).
Te lo chiedo perchè sto provando a programmare un pic diverso da questo e nn so come ricavare i nomi mnemonici che mi servono per configurarlo, dunque speravo di poter inserire i valori binari presi direttamente dal datasheet, grazie in anticipo!
#104 da Giovanni Bernardo il 4 novembre 2011
Certo che si
#105 da mrcamarium il 29 novembre 2011
#define XTAL_FREQ 4MHZ
#define Blu GPIO3 // Led Blu
#define Rosso GPIO4 // Led Rosso
#define Verde GPIO5 // Led Verde
#define Luce AN0 // Foto Resistore
#include // Pic 12F675
#include “delay.c”
__CONFIG (FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & BOREN_OFF & PD_OFF & CP_OFF);
// Funzione principale, eseguita all’avvio del picmicro
void main(void)
{
// imposto il registro tristato in maniera tale che tutte le porte siano configurate come pin di uscita
TRISIO=0b00000000;
while(1) // eseguo un ciclo finito
{
Rosso=1;
Verde=1;
Blu=1;
DelayMs(1000);
Blu=0;
DelayMs(1000);
Blu=1;
Verde=0;
DelayMs(1000);
Blu=0;
DelayMs(1000);
Rosso=0;
Verde=1;
Blu=1;
DelayMs(1000);
Blu=0;
DelayMs(1000);
Verde=0;
DelayMs(1000);
Blu=1;
DelayMs(1000);
}// Fine ciclo continuo
} // Fine main
vorrei utilizzare un comparatore interno per avviare il mio programma come faccio?
#106 da Gabriele.Barbaraci il 29 novembre 2011
salve a tutti, per favore potrest di rmi come imparare a programmare i pic con il micro c pro della mikroeòektronika?
grazie a tutti
#107 da Giovanni Bernardo il 29 novembre 2011
La tua richiesta equivale a quella di uno che entra in un negozio CocaCola e chiede una Pepsi
#108 da ivandido il 18 gennaio 2012
#109 da ivandido il 18 gennaio 2012
Gentilissimo Giovanni/Staff di settorezero, voglio esprimere un sincero ringraziamento al lavoro che state svolgendo, grazie a i vostri tutorial mi sto addentrando nella programmazione dei PIC dopo una breve esperienza passata con i micro BS2 della Parallax.
Non disponendo di un 16Fxxx ma bensi’ di un 12f675, mi accingo a far flashare un LED sulla porta GPIO0 utilizzando l’oscillatore interno…
Vengo al dunque, il mio problema è che “quando riesco a programmarlo” con il PICKIT3, la sua logica FUNZIONA, però 9 volte su 10 la programmazione NON va a buon fine e mi genera il seguente errore:
MPLAB ver 8.83
Programming…
The following memory regions failed to program correctly:
Program Memory
Address: 00000004 Expected Value: 00002bbc Received Value: 00002b80
Programming failed
Erasing…
Erase device complete
Tenete presente che il valore ricevuto a volte cambia (00001fff) ed ho cercato un po ovunque tali errori ma ovviamente senza esito.
Sapreste indicarmi di che errore si tratta ed eventualmente dove reperire questi errori?
L’errore mi è apparso dopo 4-5 programmazioni andate a buon fine.
Serve che vi POSTI il codice sorgente?
Spero di non essermi dilungato troppo e grazie ancora per il lavoro.
Ciao Ivan
#110 da F98 il 29 gennaio 2012
Buon giorno,
innanzitutto i complimenti per il notevole e chiaro lavoro che è stato fatto per questo corso.
E’ da poco che mi sono rimesso a fare qualcosa con i PICmicro …Ma non ho mai programmato in C …
Solo una domada, sicuramente di poco conto, ma alla quale non riesco a trovare risposta.
Venuto il momento di collegare il PIckit2 al circuito, c’è scritto di “ricordarsi di non alimentare il circuito, anzi di staccare i fili dall’alimentazione” ma nel mio applicativo c’è un sacco di altre cose collegate al +5V, se io stacco l’alimentazione esterna, tutto quanto viene alimentato dal +5V del PIcKit2, che ovviamente non ce la farà perchè dalla USB del PC non credo si possa avere più di un centinaio di mA. Sul sito di Microchip, nella User Guide del PicKit2 c’è un disegno dove il +5V dell’alimentazione dell’applicativo è collegato assieme al +5V del PicKit2 (pag. 31 del file 51553E.pdf di Microchip).
Quindi la domanda è: come mi devo comportare? Devo sezionare il +5V del PICmicro in modo da scollegarlo dal resto del mio circuito quando lo programmo? Così facendo il PICmicro sarà alimentato dal PicKit2.
E’ anche però vero che facendo come dice Microchip e cioè collegando insieme il +5V dell’applicativo al +5V del PicKit2 è molto probabile che i due +5v non siano perfettamente identici e quindi ci potrebbe essere della corrente (sicuramente molto bassa tanto le due alimentazioni sono più vicine come valore) che scorre da una alimentazione all’altra. Questa cosa potrebbe creare problemi?
Grazie a tutti per l’attenzione.
Saluti
Dino
#111 da Giovanni Bernardo il 29 gennaio 2012
Puoi pure rimanere attaccata l’alimentazione esterna, il pickit si accorge della situazione e stacca la sua.
#112 da Manzoni83 il 30 gennaio 2012
Salve Giovanni e complimenti per il grande lavoro che sta svolgendo!!!
Sono già tre mesi che seguo questi tutorial per imparare la programmazione dei pic e devo dire che sono veramente ben fatti!!!
Volevo chiederle un aiuto perchè ho un problema con la gestione delle porte RE0 RE1 RE2 di un PIC16f877.
Ho realizzato un termometro digitale che legge dall’ingresso analogico AN1 un segnale proveniente da un LM35.
Sto cercando di implementare altre operazioni utilizzando le porte RE0 RE1 ed RE2 come uscite digitali, queste però non si comportano come voglio! Se le setto alte riamangono basse etc..
Allora questo è il settaggio dei registri tristato:
TRISA=0b00010010; // la porta RA1 è un ingresso analogico, mentre la porta RA4 è un ingresso digitale
TRISB=0; //tutte configurate come uscite
TRISC=0; //tutte configurate come uscite
TRISD=0; //tutte configurate come uscite
TRISE=0b00000000; //tutte configurate come uscite
mentre questo è il settaggio delle impostazioni del convertitore AD
ADCON0=0b10001000; //settato: fosc32, analoginput AN1, convertitore AD Off
ADCON1=0b10000100; //settato:risultato giustificato a destra, fosc32, AN0 AN1 AN3 INGRESSI ANALOGICI,AN2 AN4 AN5 AN6 AN7 INGRESSI DIGITALI
infatti Impostando i bit PCFG3:PCFG0 del registro ADCON1 a 0100 dovrei avere AN0 AN1 AN3 come ingressi analogici, mentre AN2 AN4 AN5(RE0) AN6(RE1) AN7(RE2) come I/O digitali in base anche al settaggio dei registri tristato.
Questo però non succede perchè (per fare una prova al volo) ho provato semplicemente ad attivare le tre uscite in questione (RE0=1; RE1=1; RE2=1;) e l’unico pin che si porta alto è RE2.
Non so davvero più dove sto sbagliando, perciò le chiedo se ha qualche suggerimento da darmi.
Grazie ancora
#113 da damosound il 3 febbraio 2012
salve.
sto provando a compilare il primo firmware per il pic16f877 con mplab, ho fatto tutti i passaggi, come nella tua lezione.
al momento della compilazione, mplab mi da degli errori:
Error [800] test.as; 45. undefined symbol “UNPROTECT”
Error [800] test.as; 45. undefined symbol “DEBUGDIS”
Error [800] test.as; 45. undefined symbol “WRTEN”
Error [800] test.as; 45. undefined symbol “DUNPROT”
Error [800] test.as; 45. undefined symbol “LVPDIS”
Error [800] test.as; 45. undefined symbol “BORDIS”
Error [800] test.as; 45. undefined symbol “PWRTEN”
Error [800] test.as; 45. undefined symbol “WDTDIS”
Error [800] test.as; 45. undefined symbol “HS”
********** Build failed! **********
cosa devo fare, il file è il main.c di esempio sulla lezione .
ti ringrazio!
#114 da Giovanni Bernardo il 3 febbraio 2012
Il blog ha una funzione di ricerca.
http://www.settorezero.com/wordpress/hitec-c-compiler-i-nuovi-nomi-mnemonici-che-causano-errori-nei-vecchi-programmi/
#115 da damosound il 4 febbraio 2012
salve.
io ho scritto un semplice programmino, per verificare il corretto funzionamento della mia programmazione.
lo posto:
// 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 RC0
#define LED2 RA5
// 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;
LED1=0;
LED2=0;
while(1) // eseguo un ciclo finito
{
LED1=LED1^1;
DelayMs(50);
LED2=LED2^1;
DelayMs(50);
}// Fine ciclo continuo
} // Fine main
ora i due led, sia su porta “a” e su porta “c”, dovrebbero lampeggiare entrambi.
osservo che il led della porta “c “lampeggia, mentre il led della porta “a” rimane fisso.
ho seguito tutte le istruzioni per la compilazione o anche provato a reinstallare la versione vecchia di mplab(la 8.6), ma il problema persiste lo stesso, con entrambe le versioni.
non vorrei che vada in conflitto qualcosa, dato che uso window7 .
mi sapete dare delle spiegazioni? grazie!
#116 da Giovanni Bernardo il 4 febbraio 2012
http://www.settorezero.com/wordpress/perche-il-led-che-ho-collegato-sulla-porta-rxy-non-si-accende-disattivare-comparatore-e-convertitore-ad/
#117 da Giovanni Bernardo il 29 maggio 2011
Non esistono i pin “a voltaggio minore”
#118 da Bord90 il 29 maggio 2011
Infatti sembra strano anche a me eppure se collego il led a quelle 2 porte si illumina anche se molto poco.
A cosa può essere dovuto?
#119 da Giovanni Bernardo il 14 giugno 2011
Forse la versione 8.70 è quella di MPLAB (che è L’IDE ovvero l’AMBIENTE DI SVILUPPO), NO Hitech-C (leggasi: HITECH-C ovvero il COMPILATORE).
_CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF);
Ora che hai la config pronta, leggi, e leggi bene prima di continuare
#120 da Andrex.93 il 14 giugno 2011
scusa, ho fatto confusione. HITECH-C ho la versione 9.81
#121 da Giovanni Bernardo il 14 giugno 2011
E allora non hai aperto il file che ti ho detto io. Leggi il nome del file che ho scritto e vedi che quello che hai aperto tu non si chiama così.
#122 da Giovanni Bernardo il 5 ottobre 2011
Non ti saprei dire, se quella lista è stata dichiarata obsoleta vuol dire che potrebbero avere intenzione di cambiare il sistema, come hanno fatto con l’Hitech-C dalla 9.81 in poi, e quindi alcuni nomi potrebbero non essere più validi
#123 da Giovanni Bernardo il 26 ottobre 2011
Hai fatto un macello… All’interno del main c’è una funzione int check (int)… hai scritto una funzione nella funzione..
#124 da Giovanni Bernardo il 26 ottobre 2011
E poi le funzioni si richiamano così? int controllo_chiusura (int) ????
Ma io negli esempi ho scritto cose del genere?
QUando dichiari la funzione, l’int davanti ce lo metti per dire che quella funzione restituirà un signed int. QUando la richiami, l’int davanti non ci va messo!
Poi quando la dichiari, come argomento ci puoi pure mettere int…. se gli devi passare un signed int come argomento, ma quando la richiami li ci devi mettere un valore numerico.
Mi sa che non hai chiaro a che serve mettere void, int, char ecc davanti e dentro la funzione, giusto?
#125 da Giovanni Bernardo il 26 ottobre 2011
Poi: se il primo che mette !=0 come controllo del ciclo, mai visto, ok funziona ma occupa piu spazio in memoria che mettere <0.
Poi quelle 3 funzioni non restituiscono niente e non vogliono niente come argomento, perchè ci hai messo int, int? Andavano dichiarate come void funzione(void)