Un esempio di semaforo a LED con PIC16F84A. 

Schema elettrico:

Il circuito è molto semplice, abbiamo tre led di colore verde, giallo e rosso sulle uscite RB0, RB1 e RB2 rispettivamente.

Il codice è scritto in C ed il compilatore usato è XC8 della Microchip. Viene usato il Timer0 per ottenere un interrupt ogni secondo. Con le costanti TEMPO_DI_ON_VERDE,TEMPO_DI_ON_GIALLO,TEMPO_DI_ON_ROSSO  è possibile fissare il tempo di accensione dei led verde, giallo e rosso modificando i valori. Nel codice sono impostate a 15 sec per i led verde e rosso e 3 sec per quello giallo.

Il codice è ampiamente commentato ma in caso di necessità potete contattarmi.

/*
 * File:   main.c
 * Author: primok
 *
 * Created on 7 novembre 2021, 18.42
 */

#include <xc.h>

/*************************************************************************
                      CONFIGURAZIONE REGISTRI 
 *************************************************************************/
// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power-up Timer is disabled)
#pragma config CP = OFF         // Code Protection bit (Code protection disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

/*************************************************************************
                      DEFINIZIONE COSTANTI 
 *************************************************************************/
#define VERDE PORTBbits.RB0
#define GIALLO PORTBbits.RB1
#define ROSSO PORTBbits.RB2
#define TEMPO_DI_ON_VERDE 15 //Durata semaforo Verde in secondi
#define TEMPO_DI_ON_GIALLO 3 //Durata semaforo Giallo in secondi quando il semaforo verde è già acceso
#define TEMPO_DI_ON_ROSSO 15 //Durata semaforo Rosso in secondi
#define TIME_1SEC      125  //Costante per avere un secondo

/*************************************************************************
                      DEFINIZIONE VARIABILI 
 *************************************************************************/
volatile unsigned char Time_One_Sec=0;//Variabile per conteggio 1 sec
volatile unsigned char semaf_cont=0;//Variabile per stati semaforo
volatile unsigned char Timer_ON=0;//Variabile per durata accensione semaforo

/*************************************************************************
                    ROUTINE INTERRUPT
 *************************************************************************/
 void   __interrupt () ISR(void){
     
     if (INTCONbits.T0IF){//Interrupt ogni 8 msec
         
         if (--Time_One_Sec==0){//Dopo 1 secondo
             
             Time_One_Sec=TIME_1SEC;//Ricarica variabile per ottenere 1 secondo
             
           if(--Timer_ON==0) { //Dopo TEMPO_DI_ON_VERDE
               
                if( ++semaf_cont>2){//Aggiorna Stato semaforo
                    semaf_cont=0;
                   }
                
                if(semaf_cont==0){
                    Timer_ON=TEMPO_DI_ON_VERDE;//Durata accensione led verde 
                 }
                
                if(semaf_cont==1){
                    Timer_ON=TEMPO_DI_ON_GIALLO;//Durata accensione led giallo (quando il verde è acceso)
                
                  }
                 
                if(semaf_cont==2){
                    
                    Timer_ON=TEMPO_DI_ON_ROSSO;//Durata accensione led rosso 
                }
           }//Fine di  if(--Timer_ON==0) {
             
         }//Fine di  if (--Time_One_Sec==0){

       TMR0=6;
       INTCONbits.T0IF=0; 
    }//Fine di  if (INTCONbits.T0IF){
     
 }//Fine di void   __interrupt () ISR(void){
/*************************************************************************
                               MAIN
 *************************************************************************/ 
void main(void) {
    //Impostazione porte e registri 
    TRISA=0b00000000;
    PORTA=0b00000000;
    TRISB=0b00000000;
    PORTB=0b00000000;
    OPTION_REG=0b00000100;
    INTCON=0b10100000;
    TMR0=6;
    Time_One_Sec=TIME_1SEC;
    VERDE=1;
    Timer_ON=TEMPO_DI_ON_VERDE;
    
//Ciclo while   
    while(1){
     
        switch (semaf_cont){
            
           case 0:
               VERDE=1; 
               GIALLO=0;
               ROSSO=0;
           break;
             
           case 1:
               VERDE=1;  
               GIALLO=1;
               ROSSO=0;
            break;
             
            case 2:
               VERDE=0;
               GIALLO=0;
               ROSSO=1;
             break;
        }
          
    }
    
    return;
}

Al prossimo tutorial.

Primok_V

No comments

Leave your comment

In reply to Some User