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 :
INTCON :
Registre de configuration des interruptions : plus de détails sur l’article.
Architecture du TIMER0/WDT :
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) :
Code 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) :
- Codes MikroC du projet horloge matériel et logiciel
- Montage ISIS du projet horloge matériel et logiciel
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!
Bonjour, Merci pour ton commentaire. Tu récupère la valeur de la variable du « count » tu divise par 15 pour obtenir le nombre des secondes, ensuite tu calcules les minutes, les heures, jours, etc. Ensuite, tu transfères les données à l’afficheur. Regarde ce projet avec Arduino, il peut t’aider: https://www.electronique-mixte.fr/projet-horloge-simple-avec-arduino-sans-rtc-gps-v1/
Bon courage.