fisertek_300
 
Lezione 2 
 
Led & pulsanti
 
 
barra rossa2 
 
Moltissimi di voi, con la lezione 1, siete riusciti ad accendere i led con un PIC. Cosa che non siete mai riusciti a fare, neanche leggendo libri sulla programmazione del PIC. Ciò è segno che il metodo e la forma con cui ho esposto la lezione 1 funziona benissimo e lo dimostrano le numerosissime mail di ringraziamenti.  
A gran voce avete chiesto un seguito alla cosa. Così ho deciso di sviluppare le mie demoboard modulari per evitare di dover rifare tutte le basette sperimentali da capo e risparmiando parecchi soldini. Oltre a ciò, alla fine, ci ritroveremo con dei moduli sempre riutilizzabili ed un sistema di sviluppo non da poco.  
Mi auguro che voi impariate sempre di più da queste pagine e solo le vostre mail me lo potranno confermare.
 
barra rossa2 
 
 
Led_pul_cic_600
 
 
 
Per cominciare….. 
 
In questa lezione dovrete collegare il modulo LED alle porte B del 16F84 e il filo del negativo và collegato al bus del negativo dell'alimentatore. Il modulo PULSANTI và collegato alle prime 4 porte A del PIC (RA0,RA1,RA2,RA3) e i fili di alimentazione vanno collegati in modo che il filo comune ai tasti sia collegato al positivo dell'alimentatore e il filo comune alle resistenze sia collegato al negativo. In seguito sostituiremo la base 16f84 con la base 16f877 e proveremo lo stesso programma che stiamo per sviluppare.
 
Si parte con la seconda lezione 
Dopo aver sviluppato il programma SEMAFORO, non sarà male riprendere da lì per proseguire in questa lezione.In pratica propongo di cominciare a far funzionare i Led, poi aggiungere i pulsanti, sviluppando il programma per gradi, in modo che tutto possa essere chiaro.Questa volta posso spiattellarvi subito la base del programma, se avete seguito la lezione del Semaforo, dovreste già comprenderla. 
 
/****************************\ 
* led in sequenza * 
\****************************/ 
#include<pic.h> 
main(void) 
PROGRAMMA DA SCRIVERE 
 
Questa è la base del programma da cui cominciare a sviluppare il tutto. Dobbiamo ora vedere un attimo cosa abbiamo intenzione di fare e, di conseguenza operare le opportune aggiunte. 
Il nostro obiettivo iniziale è far accendere in sequenza gli 8 led, quindi avremo bisogno di settare le porte B del PIC come uscite con il comando TRISB, usare il comando PORTB per accendere i led ed introdurre delle pause tra l'accenzione di un led e l'altro. 
Ciò implica che dovremo aggiungere la direttiva che richiama la routine di ritardo delay.c presente nella cartella bin del PICLITE. 
Aggiungiamo quanto appena detto e arriviamo a questo: 
 
/****************************\ 
* led in sequenza * 
\****************************/ 
#include<pic.h> // compila per il PIC generico 
#include"delay.c" // richiama la routine di ritardo per poter usare le pause 
main(void) //l'inizio del programma 
{ // graffa di apertura del programma 
TRISB = 0; // setta le porte B del PIC come uscite 
} // fine del programma 
 
Fatto questo, dovremo rispolverare la tabella dello stato logico delle porte che avevo esposto nella lezione del semaforo. Ve la ripropongo, così non andate troppo in giro per il sito (che ormai è abbastanza trafficato). 
 
NUMERO PORTA
RB7
RB6
RB5
RB4
RB3
RB2
RB1
RB0
STATO LOGICO
0
0
0
0
0
0
1
0
 
Da questa tabella, potremo ricavare il numero binario da passare a PORTB in modo da poter accendere il relativo led a nostro piacimento. Per esempio PORTB = 0b00000010; accende il secondo led della fila da 8 (RB1).Decido ora che i led dovranno accendersi in sequenza da RB0 a RB7 (ricordate che le porte si leggono come i numeri, da destra verso sinistra). 
Otteniamo così il seguente listato: 
 
/****************************\ 
* led in sequenza * 
\****************************/ 
#include<pic.h>                  // compila per il PIC generico 
#include"delay.c"              // richiama la routine di ritardo per poter usare le pause 
main(void)                          //l'inizio del programma 
{                                          // graffa di apertura del programma 
TRISB = 0;                        // setta le porte B del PIC come uscite 
PORTB = 0b00000001;    //accende il led collegato a RB0 
PORTB = 0b00000010;    //accende il led collegato a RB1 e spegne RB0 
PORTB = 0b00000100;    //accende il led collegato a RB2 e spegne RB1 
PORTB = 0b00001000;    //accende il led collegato a RB3 e spegne RB2 
PORTB = 0b00010000;    //accende il led collegato a RB4 e spegne RB3 
PORTB = 0b00100000;    //accende il led collegato a RB5 e spegne RB4 
PORTB = 0b01000000;    //accende il led collegato a RB6 e spegne RB5 
PORTB = 0b10000000;    //accende il led collegato a RB7 e spegne RB6 
}                                          // fine del programma 
 
Notate sempre i punti e virgola alla fine di ogni istruzione, è facile dimenticarli e dovete prestare attenzione. 
Abbiamo steso il listato che serve ad accendere tutte e 8 i led in sequenza ma, non basta per avere una sequenza decente. 
In realtà il PIC eseguirebbe il programma troppo velocemente e i nostri occhi non sono abbastanza veloci da vedere la sequenza. (se volete provare a compilare e vedere il risultato fate pure). 
Dobbiamo inserire una pausa tra l'accensione di un led e l'altro, in modo che la sequenza sia più o meno veloce e regolabile a nostro piacimento con il minor sforzo possibile nel programmare. 
Per fare questo, dobbiamo inserire una pausa con una variabile definita tra un comando di accensione a l'altro. 
Per prima cosa aggiungiamo la definizione della variabile e gli assegnamo un valore, poi aggiungeremo il comando Delay nel listato. 
 
/****************************\ 
* led in sequenza * 
\****************************/ 
#include<pic.h>                    // compila per il PIC generico 
#include"delay.c"                // richiama la routine di ritardo per poter usare le pause 
#define asp 20                     //definisce che asp è uguale a 20 
main(void)                            //l'inizio del programm
{                                            // graffa di apertura del programma 
TRISB = 0;                          // setta le porte B del PIC come uscite 
PORTB = 0b00000001;      //accende il led collegato a RB0 
DelayMs(asp);                    // ritardo di valore asp (ora è definito a 20) 
PORTB = 0b00000010;      //accende il led collegato a RB1 e spegne RB0 
DelayMs(asp); 
PORTB = 0b00000100;      //accende il led collegato a RB2 e spegne RB1 
DelayMs(asp); 
PORTB = 0b00001000;      //accende il led collegato a RB3 e spegne RB2 
DelayMs(asp); 
PORTB = 0b00010000;      //accende il led collegato a RB4 e spegne RB3 
DelayMs(asp); 
PORTB = 0b00100000;      //accende il led collegato a RB5 e spegne RB4 
DelayMs(asp); 
PORTB = 0b01000000;      //accende il led collegato a RB6 e spegne RB5 
DelayMs(asp); 
PORTB = 0b10000000;      //accende il led collegato a RB7 e spegne RB6 
DelayMs(asp); 
}                                           // fine del programma 
 
Eccoci arrivati al programma completo, però non è finito.  
Il PIC eseguirebbe una volta soltanto il programma e ci farebbe vedere la sequenza una volta soltanto.(in questo caso specifico il pic a fine programma ricomincerebbe da capo all'infinito e quello che sto per dire dopo è per introdurre il cliclo while). 
Se vogliamo che il PIC ripeta all'infinito il programma, dobbiamo inserire il blocco di istruzioni in un ciclo while e, per fare questo, dobbiamo aggiungere anche le relative parentesi graffe. 
Qui sotto riporto il listato completo che serve ad avere una sequenza infinita di accensione dei led, tenete conto che le istruzioni possono essere scritte anche sulla stessa riga, purchè ci sia sempre il punto e virgola. 
 
/****************************\ 
* led in sequenza * 
\****************************/ 
#include<pic.h>                                            // compila per il PIC generico 
#include"delay.c"                                        // richiama la routine di ritardo per poter usare le pause 
#define asp 20                                             //definisce che asp è uguale a 20 
main(void)                                                    //l'inizio del programma 
{                                                                    // graffa di apertura del programma 
TRISB = 0;                                                  // setta le porte B del PIC come uscite 
while(1)                                                        // istruzione per il ciclo senza fine 
{                                                                    // parentesi di inizio ciclo 
PORTB = 0b00000001; DelayMs(asp);    //accende il led collegato a RB0 
PORTB = 0b00000010; DelayMs(asp);    //accende il led collegato a RB1 e spegne RB0 
PORTB = 0b00000100; DelayMs(asp);    //accende il led collegato a RB2 e spegne RB1 
PORTB = 0b00001000 ;DelayMs(asp);    //accende il led collegato a RB3 e spegne RB2 
PORTB = 0b00010000; DelayMs(asp);    //accende il led collegato a RB4 e spegne RB3 
PORTB = 0b00100000; DelayMs(asp);    //accende il led collegato a RB5 e spegne RB4 
PORTB = 0b01000000; DelayMs(asp);    //accende il led collegato a RB6 e spegne RB5 
PORTB = 0b10000000; DelayMs(asp);    //accende il led collegato a RB7 e spegne RB6 
}                                                                   //parentesi di fine ciclo 
}                                                                   // fine del programma 
 
Ora possiamo andare a compilare e a programmare il nostro PIC.Dobbiamo, però, stare molto attenti al fatto che nel nostro caso tutte le porte RB del PIC sono collegate ai led e due di queste porte servono a programmare il PIC. 
Quando programmiamo il PIC, dobbiamo staccare momentaneamente i led, altrimenti la programmazione fallirà a causa dell'interferenza dei led stessi.  
Ricordatevi che sia il programmatore che la demoboard devono essere accesi, anche durante la programmazione, e che dopo la programmazione è opportuno staccare il cavo ICP dalla demo. (altrimenti, se spegnete il programmatore, la demoboard non potrà funzionare). 
Ricordatevi anche che il tasto RESET della demoboard NON deve mai essere premuto durante la programmazione del PIC,pena la probabile rottura del transistor di MCRL del programmatore (solo durante la programmazione). 
Se avete seguito attentamente questa lezione, e quella del semaforo, dovreste essere in grado di invertire l'ordine di accensione dei led e di inventare sequenze vostre, semplicemente cambiando la sequenza dei numeri passati a PORTB. 
Potete anche cambiare la velocità della sequenza cambiando il numero passato a asp (tra 1 e 255).Fate le vostre prove, vi porterà pratica ed esperienza e poi andremo avanti.  
Dopo aver fatto il programma per la sequenza dei led, possiamo affrontare la gestione dei pulsanti. 
Se volete sentire subito il cicalino, basta staccare i led dalla demoboard e inserire il filo positivo del cicalino ad una delle porte B del pic appena programmato con il programma precedente e il filo negativo al negativo dell'alimentatore . Sentirete il cicalino emettere un suono intermittente.Avete appena scoperto come usare un cicalino attivo. Si usa come un led solo che ,invece di emettere luce, emette suono. Rimettiamo a posto il cicalino, rimontiamo il pettine dei led e andiamo avanti con la lezione. 
Passiamo ad analizzare cosa vogliamo fare con i pulsanti ed i led. 
Direi che sarebbe interessante fare 4 sequenze di accensione diverse per i led, assegnare le sequenze ai 4 pulsanti e, ad ogni pressione dei pulsanti, parta la sequenza corrispondente al tasto premuto. 
Per prima cosa dovremmo settare le porte A del pic come entrate e, per fare questo, è sufficiente scrivere TRISA=1 nel programma. 
Otterremo di poter stendere un inizio di programma che sarà così: 
 
/****************************\ 
* led in sequenza * 
\****************************/ 
#include<pic.h>        // compila per il PIC generico 
#include"delay.c"    // richiama la routine di ritardo per poter usare le pause 
#define asp 20         //definisce che asp è uguale a 20 
main(void)               //l'inizio del programma 
{                               // graffa di apertura del programma 
TRISA = 15;          // setta le prime 4 porte A del PIC come entrate 
TRISB = 0;            // setta le porte B del PIC come uscite 
 
Settate le porte A del pic, dovremo trovare un comando che soddisfi le nostre esigenze per gestire i tasti.In pratica vorrei che il PIC aspettasse la pressione di uno dei tasti e poi eseguisse la sequenza associata, fino alla fine della sequenza e poi tornasse ad aspettare la pressione dei tasti. 
In rete, trovo due possibilità operative per poter fare la stessa cosa, la prima è usare il costrutto IF- else, cioè porre delle condizioni e fare il salto al verificarsi della condizione. (salto condizionato). 
La seconda soluzione è usare il costrutto switch che, a seconda dello stato logico letto sulla porta A del pic, esegue il relativo blocco di programma. 
Esso và usato in questo modo: (Attentissimi alla punteggiatura usata, solo da li capite la struttura) 
 
switch (PORTA)                         //decido quali porte leggere 
{                                                  //graffa di apertura di switch 
case 1:                                       //se si verifica lo stato 1 esegue il blocco successivo, 
                                                  // altrimenti salta a case successivo 
istruzione1;istruzione2; etc;     //blocco che esegue se si avvera il case 1 
break;                                       //fine del case 1 e esce dal ciclo switch 
case 2:                                       //se si verifica lo stato 2 esegue 
istruzione1;istruzione2; etc; 
break; 
 
Per spiegarla meglio, direi che questo pezzo di programma si comporta così: 
Se le porte A del pic presentano il numero binario 0b0001 (decimale 1), viene eseguito il blocco di programma che fa capo a case 1, fino al comando break, e poi esce dal ciclo switch. Altrimenti salta al secondo case che, se legge il valore binario 0b0010 (decimale 2), egegue il suo blocco fino al suo break, e via così fino alla fine. 
Il tutto dovrebbe essere inserito in un ciclo while, per fare in modo che il programma venga ripetuto all'infinito.Mettendo insieme il tutto, viene fuori questo: 
 
/****************************\ 
* led in sequenza * 
\****************************/ 
#include<pic.h>                                                      // compila per il PIC generico 
#include"delay.c"                                                  // richiama la routine di ritardo per poter usare le pause 
#define asp 120                                                      //definisce che asp è uguale a 120 
main(void)                                                               //l'inizio del programma 
{                                                                               // graffa di apertura del programma 
TRISA = 15                                                            // setta le prime 4 porte A del PIC come entrate 
TRISB = 0;                                                             // setta le porte B del PIC come uscite 
while(1)                                                                   //ripete il ciclo all'infinito 
{                                                                               //graffa di apertura di while 
switch (PORTA)                                                     //lettura PORTA 
          {                                                                    //graffa di apertura di switch 
          case 1:                                                          //se PORTA è 1 (0001) esegue la sequenza sotto, altrimenti salta 
          PORTB = 0b00000001; DelayMs(asp);    //sequenza da 0 a 7 
          PORTB = 0b00000010; DelayMs(asp); 
          PORTB = 0b00000100; DelayMs(asp); 
          PORTB = 0b00001000; DelayMs(asp); 
          PORTB = 0b00010000; DelayMs(asp); 
          PORTB = 0b00100000; DelayMs(asp); 
          PORTB = 0b01000000; DelayMs(asp); 
          PORTB = 0b10000000; DelayMs(asp); 
          break;                                                           //interrompe il programma switch e torna a while 
          case 2:                                                          // se PORTA è 2 (0010) esegue, altrimenti salta 
          PORTB = 0b10000000; DelayMs(asp);     //sequenza da 7 a 0 
          PORTB = 0b01000000; DelayMs(asp); 
          PORTB = 0b00100000; DelayMs(asp); 
          PORTB = 0b00010000; DelayMs(asp); 
          PORTB = 0b00001000; DelayMs(asp); 
          PORTB = 0b00000100; DelayMs(asp); 
          PORTB = 0b00000010; DelayMs(asp); 
          PORTB = 0b00000001; DelayMs(asp); 
          break; 
          case 4:                                                          //se PORTA è 4 (0100) esegue, altrimenti salta 
          PORTB = 0b10000001; DelayMs(asp);     //sequenza incrociata 
          PORTB = 0b01000010; DelayMs(asp); 
          PORTB = 0b00100100; DelayMs(asp); 
          PORTB = 0b00011000; DelayMs(asp); 
          PORTB = 0b00100100; DelayMs(asp); 
          PORTB = 0b01000010; DelayMs(asp); 
          PORTB = 0b10000001; DelayMs(asp); 
          break; 
          case 8:                                                           //se PORTA è 8 (1000) esegue, altrimenti salta 
          PORTB = 0b10000000; DelayMs(asp);      //sequenza a treno 
          PORTB = 0b01000000; DelayMs(asp); 
          PORTB = 0b10100000; DelayMs(asp); 
          PORTB = 0b01010000; DelayMs(asp); 
          PORTB = 0b10101000; DelayMs(asp); 
          PORTB = 0b01010100; DelayMs(asp); 
          PORTB = 0b00101010; DelayMs(asp); 
          PORTB = 0b00010101; DelayMs(asp); 
          PORTB = 0b00001010; DelayMs(asp); 
          PORTB = 0b00000101; DelayMs(asp); 
          PORTB = 0b00000010; DelayMs(asp); 
          PORTB = 0b00000001; DelayMs(asp); 
          break; 
          }                                                                   //graffa di chiusura di switch 
PORTB=0;                                                            //spegne tutti i led 
}                                                                             //graffa di chiusura di while 
}                                                                             //graffa di chiusura main (void) 
 
In questo programma ho preferito introdurre il ciclo switch perché il ciclo for lo abbiamo già trattato nella lezione 1 (quella del semaforo).Se volessimo usare un joystick al posto dei pulsanti, basterà togliere dalla demo il modulo tasti e collegare il modulo joy 
E potremo usare lo stesso programma.Quando programmate il PIC, esso deve avere gli stessi settaggi di configurazione usati nel semaforo. 
Con questa lezione, e con la prima, dovreste aver imparato bene l'uso dei led con il PIC e la loro gestione. 
Avrete notato che l'ultimo programma si è allungato un pochino ma in fondo non è tanto complicato, e già abbiamo fatto una cosa carina.
 
 
barra rossa2 
 
b_home2_baloon 
 
© 2002-2006 by Sergio Fiocco -Tutti i diritti riservati- Vietata la riproduzione, anche parziale del presente sito