TIMER REGOLABILE 16 MINUTI CON DISPLAY 7-SEGMENTI

Schema per Realizzare un Timer Regolabile da 0 Secondi fino a 16 Minuti che Permette di Visualizzare il Conto alla Rovescia e Controllare un Attuatore…


 
 
 
 



 

INTRO

Il seguente schema è un semplice temporizzatore, ovvero quando si preme un tasto esso accende un attuatore che verrà spento dopo un determinato tempo. La particolarità di questo schema è che essendo realizzato con un microcontrollore permette di regolare il tempo di accensione con un potenziometro e inoltre permette di visualizzare il conteggio alla rovescia su di un display a sette segmenti a tre cifre.

Infatti il tempo di accensione è regolabile da 0 secondi fino a 999 secondi, ovvero 16 minuti. Prima di avviare il conteggio è possibile variare il tempo con il potenziometro, poi con un tasto si avvia il conteggio e il potenziometro non ha nessun effetto. Il conteggio può essere però stoppato prima che il tempo scadi.

Durante il conteggio alla rovescia il microcontrollore ha un pin a tensione di alimentazione per permettere l’accensione di un attuatore. In questo caso si è usato un LED come attuatore ma esso può essere sostituito da un relè, un controllo di un motore o altri.

 





 
CODICE

Il codice è il seguente:

#define attuatore PORTB.F1                       //Uscita attuatore
unsigned int tempo, tempo_display;               //varibile valore tempo
char cifra;                                      //Variabile cifra dei valori
bit start;                                       //Variabile start/stop
unsigned int i, j;                               //Varibili for
char segm[10] = {0xC0, 0xF9, 0xA4, 0xB0,         //vettore sette segmenti anado comune
                0x99, 0x92, 0x82, 0xF8,
                0x80, 0x90};
                
void EXT_INT() iv 0x0008 ics ICS_AUTO {         //Subroutine interrupt tasto
  start = ~ start;                              //start o stop se è in corso il conteggio
  attuatore = start;                            //Accendi o spegni attuatore
  Delay_ms(1);                                  //ritardo antirimbalzo
  if(start==0){                                 //Se si stoppa
    i=tempo;                                    //Variabili for al valore max
    j=660;                                      //Per stoppare i for
  }
  INTCON.INT0IF = 0;                            //reset flag interrupt
}

void sette_seg_3_cifre(int tempo){              //subroutine scrittura 7-seg 3 cifre

  cifra = tempo / 100;                         //estrai Cifra centinaia
  PORTB.F7 = 1;                                //Accendi cifra centinaia
  PORTB.F6 = 0;                                //spegni cifra decine
  PORTB.F5 = 0;                                //spegni cifra unità
  PORTC = segm[cifra];                         //inizializza la cifra centinaia sulle uscite
  Delay_us(51);                                //Delay

  cifra = (tempo / 10) % 10;                   //estrai cifra decine
  PORTB.F7 = 0;                                //spegni cifra centinaia
  PORTB.F6 = 1;                                //Accendi cifra decine
  PORTB.F5 = 0;                               //spegni cifra unità
  PORTC = segm[cifra];                        //inizializza la cifra decine
  Delay_us(50);                                //delay

  cifra = (tempo) % 10;                      //estrai cifra unità
  PORTB.F7 = 0;                              //spegni cifra centinaia
  PORTB.F6 = 0;                             //spegni cifra decine
  PORTB.F5 = 1;                              //Accendi cifra unità
  PORTC = segm[cifra];                      //inizializza la cifra unità
  Delay_us(50);

}


void main (){                               //Programma principale

  TRISA = 0b00000001;                       //AN0 ingresso
  TRISB = 0b00000001;                       //PORTB uscite, tranne INT0
  TRISC = 0b00000000;                       //PORTC uscite
  
  INTCON.GIE = 1;                           //attivo gli interrupt

  INTCON2.INTEDG0 = 1;                      //interrupt sul fronte di salita
  INTCON.INT0IE = 1;                        //attiva INT0

  ADC_Init();                               //inizializza ADC

  start = 0;                                //Conteggio parte da fermo
  attuatore = 0;                            //attuatore spento

  while (1) {                               //Ciclo infinito

    tempo = ADC_Get_Sample(0);              //Leggi valore ADC0
    tempo = tempo*0.9765;                   //Converti per avere 0-999
    tempo_display = tempo;                  //copia il valore del tempo
    sette_seg_3_cifre(tempo_display);       //visualizzalo sul display
    
    
    if (start == 1){                        //Se start=1
      for(i=0; i<tempo; i++){               //Esegui per i secondi desiderati
        for(j=0; j<660; j++) sette_seg_3_cifre(tempo_display); //Ciclo di 1 secondo
        tempo_display --;                   //scala di un secondo il tempo
      }
      start=0;                              //Finito il conteggio stoppa
      attuatore = 0;                        //Spegni attuatore
    }
  }
}

Prima di tutto si seleziona il pin dell’attuatore e si inizializzano le variabili di programma e la variabile per il controllo del display sette segmenti.

Il tasto di start e stop viene controllato da una subroutine di interrupt. In questa subroutine, se attivata, si va ad invertire la variabile di controllo di start/stop, ovvero se è uguale a 1 (start) viene posta a 0 logico (stop) o viceversa. Viene inoltre acceso o spento l’attuatore e si pongono le variabili usate nei due for successivi ad un valore tale da stoppare i for.

Nella subroutine per la scrittura su display sette segmenti viene preso il numero da visualizzare, scomposto in centinaia, decine e unità e queste tre componenti vengono mostrate una per volta sul display. Ogni cifra rimane accesa per un certo tempo e mai contemporaneamente. Il delay interno a questa soubroutine è ben studiata in modo tale da avere un certo ritardo di esecuzione.

Nel programma principale si inizializzano gli ingressi, le uscite, l’interrupt sul pin INT0, si inizializza l’ADC e le variabili di controllo del funzionamento.

Nel ciclo infinito si legge il valore della tensione di uscita del trimmer e in base ad essa si va ad inizializzare la variabile del tempo che viene successivamente visualizzata. Se il conteggio non è avviato il programma legge l’ADC, inizializza il valore del tempo e lo visualizza.

Se il conteggio è avviato viene eseguito per un numero uguale al tempo un for che semplicemente chiama la subroutine di visualizzazione per 660 volte. Il numero 660 nasce dal fatto che grazie al debug di mikroc è stato misurato il tempo per eseguire una volta questa linea di codice. Il numero 660 vale solo se si usa un quarzo con frequenza di 4MHz. Dopo il ritardo di 1 secondo il tempo viene decrementato.

Quando il conteggio arriva a 0 esso viene stoppato e l’attuatore spento.

SCHEMA

Lo schema è il seguente:

La tensione di alimentazione è 5V continui con il positivo connesso a VDD e il negativo connesso alla massa del circuito. Il microcontrollore usato è il PIC18F252 ma può essere sostituito con uno equivalente con stesso numero di porte, ADC e interrupt INT0. Il circuito di oscillazione è formato dal cristallo a 4MHz e da C1, C2. R9 mantiene un livello logico alto sul pin 1 evitando che il PIC18 si resetti.

Per la regolazione del tempo vi è il potenziometro RV1 connesso al pin 2 contraddistinto dalla notazione SET mentre il pulsante di start/stop è connesso al pin 21 con la resistenza di pull down R8. L’attuatore è formato da un led blu con la resistenza di protezione R10.

Per il display sette segmenti è stato usato un display a bassissima corrente con anodo comune che non richiede quindi un buffer tra il microcontrollore e i contatti degli anodi comune. Le resistenze connesse al PORTC sono resistenze di protezione usate per far scorrere circa 3mA in ogni segmento.

I fuses per la programmazione sono così configurati:

 
DOWNLOAD

Potete scaricare la simulazione con PROTEUS al seguente LINK!!!





 

[Voti Totali: 0 Media Voti: 0]
Segui la Nostra Pagina Facebook: Facebook

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *