Catégories
Interruption Arduino Projets électroniques

Projet électronique : Horloge matériel & logiciel avec le microcontrôleur PIC16F877A

Projet électronique Horloge matériel et logiciel avec le microcontrôleur PIC16F877A

Description rapide du projet :

Min projet d’une horloge à afficheurs BCD 7 Segments. Le microcontrôleur 16F877A contrôle 6 afficheurs BCD (décodeur BCD 7 segments intégré) qui sont organisés comme suit :

  • 2 Afficheurs BCD à droite pour les secondes (0-59)
  • 2 Afficheurs BCD au milieu pour les minutes (0-59)
  • 2 Afficheurs BCD à gauche pour les heures (0-23)

Le microcontrôleur permet de générer un signal interne de référence de 1Hz (une seconde) qui sert à incrémenter le compteur des secondes en utilisant deux façons différentes :

  • Par interruption en utilisant le TIMER0 (8 bits)
  • Par programme en utilisant un retard d’une seconde (moins précise)

Configuration du TIMER0 pour avoir une seconde :

Le microcontrôleur 16F877A contient 3 TIMERs

  • Timer0 : 8 bits en mode compteur/timer programmable
  • Timer0 : 16 bits en mode compteur/timer programmable
  • Timer2 : 8 bits en mode compteur/timer avec un registre de 8 bits programmable

Dans ce projet on s’intéressera au Timer0.

En premier lieu, vous pouvez compter les impulsions reçues sur le pin RA4/TOKI (mode compteur) ou compter le nombre des cycles du microcontrôleur (mode timer). Dans ce projet on utilise l’horloge interne du micro pour effecteur le comptage, donc on est en mode timer.

La sélection d’un ou l’autre de ces deux modes de fonctionnement (timer/compteur) s’effectue par le bit 5 du registre OPTION : T0CS (Tmr0 Clock Source Select bit).

  • T0CS = 1 : Fonctionnement en mode compteur
  • T0CS = 0 : Fonctionnement en mode timer

Les registres en relation avec le Timer0 :

  • TIMER0
  • OPTION_REG
  • INTCON

TIMER0 :

8 bits en lecture et écriture, c’est le registre qui contient la valeur du timer

OPTION_REG : 

C’est le registre qui va nous permettre de choisir le mode fonctionnement du Timer0 et définir le facteur d’échelle, dans ce projet j’ai choisi un facteur de 256 (PS (0-2) = 111).

Signification des bits du registre OPTION_REG :

OPTION_REG microcontrôleur PIC16F877A

 

Bits OPTION_REG microcontrôleur PIC16F877A

INTCON : 

Registre de configuration des interruptions : plus de détails sur l’article.

Architecture du TIMER0/WDT :

Archetecture TIMER0 microcontrôleur PIC16F877A

Comment calculer la valeur du compteur pour un temps donné ?

 

On va calcul la valeur de Count pour TMR0=0, Prescaler =256, Fclk=4MHz et Fout =1Hz (Tout =1s) :

Valeur Timer0 PIC16F877Code MikroC (Horloge logiciel) : 

// Compteurs des secondes (premier et deuxième digits)
short int i_sec1=0,i_sec2=0;

// Compteurs des minutes (premier et deuxième digits)
short int i_min1=0, i_min2=0;

// Compteurs des heures (premier et deuxième digits)
short int i_hour1=0,i_hour2=0;

// Les valeurs maximales (60,24)
const int Max_10 =10;
const int Max_6 =6;
const int Max_2 =2;
const int Max_4 =4;

// Fonction initialisation de l'horloge
void clearAll(void)
{
  i_sec1=0;
  i_sec2=0;
  i_min1=0;
  i_min2=0;
  i_hour1=0;
  i_hour2=0;
}

void main ()
{
  TRISB=0x00;
  TRISC=0x00;
  TRISD=0x00;

  PORTB=0x00;
  PORTC=0x00;
  PORTD=0x00;
  
  while(1)
  {
     // Transfert des secondes aux afficheurs BCD (à gauche)
     PORTB=(i_sec1 & 0x0F) + (i_sec2<<4 & 0xF0) ;
     
     // Transfert des minutes aux afficheurs BCD (au milieu)
     PORTC=(i_min1 & 0x0F) + (i_min2<<4 & 0xF0) ;
     
     // Transfert des heures aux afficheurs BCD (à droite)
     PORTD=(i_hour1 & 0x0F) + (i_hour2<<4 & 0xF0) ;

     // Temporisation d'une seconde
     delay_ms(1000);
     
      // Incrémentations et tests des différents compteurs
      i_sec1++;
      i_sec1=i_sec1 % Max_10;
      if( i_sec1==0)
      {
         i_sec2++;
         i_sec2=i_sec2 % Max_6;

         if( i_sec2==0)
         {
             i_min1++;
             i_min1=i_min1 % Max_10;
             if( i_min1==0)
             {
                 i_min2++;
                 i_min2=i_min2 % Max_6;
                 if( i_min2==0)
                 {
                     i_hour1++;
                     i_hour1=i_hour1 % Max_10;
                     if( i_hour1==0)
                     {
                         i_hour2++;
                         i_hour2=i_hour2 % Max_10;
                     }
                     else if( i_hour1==Max_4 && i_hour2==Max_2)
                     {
                         clearAll();
                     }

                 }

             }
         }
     }
  }
}

Code MikroC (Horloge matériel avec interruption) : 

// Compteurs des secondes (premier et deuxième digits)
short int i_sec1=0,i_sec2=0;

// Compteurs des minutes (premier et deuxième digits)
short int i_min1=0, i_min2=0;

// Compteurs des heures (premier et deuxième digits)
short int i_hour1=0,i_hour2=0;

// Variable count qui sert à avoir une seconde (count = 15)
short int count=0;

// Les valeurs maximales (60,24)
const int Max_10 =10;
const int Max_6 =6;
const int Max_2 =2;
const int Max_4 =4;

// Les valeur maximale du count qui donne 1s
const int Count_Value_1HZ=15;

// Routine d'interruption du TIMER0
void interrupt(void)
{
   // Désactiver l'interruption globale
   INTCON.GIE=0;

   if(INTCON.TMR0IF)
   {
        INTCON.TMR0IF=0;
        count++;
   }

   INTCON.GIE=1;
}

void clearAll(void)
{
  i_sec1=0;
  i_sec2=0;
  i_min1=0;
  i_min2=0;
  i_hour1=0;
  i_hour2=0;
}

void main ()
{
  TRISB=0x00;
  TRISC=0x00;
  TRISD=0x00;

  PORTB=0x00;
  PORTC=0x00;
  PORTD=0x00;

  // Initialisation du TIMER0 à 0
  TMR0=0;

  // Activer l'interruption globale et celle du TIMER0
  INTCON.GIE=1;
  INTCON.TMR0IE=1;

  // TIMER0 en mode timer avec l'hologe du uC
  OPTION_REG.T0CS=0;
  OPTION_REG.T0SE=0;
  OPTION_REG.PSA=0;
  // Définir une valeur de prescaler de 256
  OPTION_REG.PS0=1;
  OPTION_REG.PS1=1;
  OPTION_REG.PS2=1;


  while(1)
  {
    while(count == Count_Value_1HZ)
    {
       count=0;

       PORTB=(i_sec1 & 0x0F) + (i_sec2<<4 & 0xF0) ;
       PORTC=(i_min1 & 0x0F) + (i_min2<<4 & 0xF0) ;
       PORTD=(i_hour1 & 0x0F) + (i_hour2<<4 & 0xF0) ;

        i_sec1++;
        i_sec1=i_sec1 % Max_10;
        if( i_sec1==0)
        {
           i_sec2++;
           i_sec2=i_sec2 % Max_6;

           if( i_sec2==0)
           {
               i_min1++;
               i_min1=i_min1 % Max_10;
               if( i_min1==0)
               {
                   i_min2++;
                   i_min2=i_min2 % Max_6;
                   if( i_min2==0)
                   {
                       i_hour1++;
                       i_hour1=i_hour1 % Max_10;
                       if( i_hour1==0)
                       {
                           i_hour2++;
                           i_hour2=i_hour2 % Max_10;
                       }
                       else if( i_hour1==Max_4 && i_hour2==Max_2)
                       {
                           clearAll();
                       }

                   }

               }
           }
       }

    }
  }
}

Télécharger gratuitement le fichier du projet : Horloge matériel & logiciel avec le  microcontrôleur PIC16F877A (Schéma ISIS + Code MikroC) :

  1. Codes MikroC du projet horloge matériel et logiciel
  2. Montage ISIS du projet horloge matériel et logiciel

Revenir au sommaire des projets électronique

2 réponses sur « Projet électronique : Horloge matériel & logiciel avec le microcontrôleur PIC16F877A »

Bonjour,

Merci de votre article, il m’a beaucoup aidé!
Petite question: quelles seraient les modifications du code pour réaliser la même projet mais sur un LCD 16×2?

Merci!

Laisser un commentaire