Vous êtes sur la page 1sur 6

UM5. E.N.S.A.M. Rabat.

M-23-1 : Introduction aux Microcontrôleurs

Exercice 4 :
TD 2. Le microcontrôleur PIC 16F87x, en particulier, possède trois temporisateurs : Timer 0 (8
bits), Timer 1 (16 bits) et Timer 2 (8 bits). Le schéma bloc suivant montre la structure
Programmation des microcontrôleurs en langage C : interne du temporisateur Timer0 :
Ports E/S et Temporisateur TMR0 du PIC16F87x.
Timer 0 N
Mux
8
Mux
Exercice 1 :
tcy 0
T0CKI 1
Proposer une procédure, en langage machine et en langage C, de configuration des ports (RA4) 1 Sync TMR0
A et B dans le cas suivant : Prédiviseur 0 2 x tcy
• PortA : lignes RA0 à RA3 en sorties ; (Compteur)
÷D
• PortB : ligne RB0 à RB3 en entrées, et RB4 à RB7 en sorties.

Exercice 2 : Microcontrôleur
Reg. OPTION T0SE T0CS PS2, PS1, PS0 PSA Reg. INTCON T0IF
On se propose d'utiliser un microcontrôleur (PIC16F877A par
RB0
exemple) pour contrôler un témoin L (LED) par l'intermédiaire d'un
commutateur K à deux positions : Le TMR0 est un registre compteur qui peut être chargé par la valeur initiale N (0 à 255).
K
La source de l'horloge peut être interne (tcy = 4/Fq) ou externe sur la broche T0CKI (ligne
2.1. Lire l'état d'un commutateur K à deux positions et
RA4 du port A). Le contrôle du Timer 0 se fait grâce au registre OPTION :
indiquer cet état sur une LED : LED allumée lorsque K est RB1
fermé ; • T0CS : sélection de la source de l'horloge interne ou externe sur TOCKI;
L
• T0SE : choix du front actif si l'horloge est externe ;
2.2. Faire clignoter la LED si le commutateur K est fermé ;
• PSA : utilisation ou non de prédiviseur ;
• PS2..PS0 : sélection du facteur de prédivision D.
Exercice 3 : RB0 AFF Une fois chargé par la valeur initiale N, le Timer 0 s'incrémente au rythme de l'horloge
On se propose d'utiliser un microcontrôleur (PIC16F877A a
RB1 a jusqu'à la valeur finale 255, puis redémarre à 0 ou à partir de la valeur initiale N. Le
Microcontrôleur

par exemple) pour contrôler un afficheur 7 segments placé RB2 b


RB3 c f b passage de 255 à 0 est un débordement qui est signalé par le bit T0IF, indicateur de
sur les lignes RB1 à RB7: g
RB4 d dépassement situé dans le registre INTCON :
3.1. afficher la valeur d'un compteur décimal qui RB5 e e c
s'incrémente automatiquement après une RB6 f Horloge ….. …..
RB7 g d
temporisation;
TMR0 0 1 ….. 254 255 0 1 2 ….. 255 0 1 …..
3.2. afficher la valeur d'un compteur décimal qui
RB0
s'incrémente grâce à un bouton poussoir placé +5v
sur la ligne RB0; T0IF
….. ….. …..
BP
Ràz
Débordement (par logiciel)

E. Benaata. Filière Ingénieurs – EEIN / 1. 1


UM5. E.N.S.A.M. Rabat. M-23-1 : Introduction aux Microcontrôleurs

Solutions proposées :
La configuration du Timer0 se fait grâce au registre OPTION :
Exercice 1 :
Langage machine:

BSF STATUS, RP0 ; Accès TRISA dans Bank 1 RA0


RA1

PORTA
Source de BCF STATUS, RP1
l'horloge : RA2
CLRF TRISA ; RA0 … RA3 en Sorties RA3
Affectation du
prédiviseur : BCF STATUS, RP0 ; Accès POTRA dans Bank 0
CLRF PORTA ; RAZ registre de donnée
Facteur de
Prédivision :

Langage C :

Init_PortA() // configuration et initialisation


{
TRISA = 0x00; // RA0 … RA3 en Sorties
Microcontrôleur
PORTA = 0x00; // RAZ registre de données du portA
4.1. Comme indiqué sur la figure ci contre, on }
voudrait générer un signal carré de période 40 ms
et de rapport cyclique 50%. Ce signal doit être RB7
disponible sur la ligne RB7 du port B. 40 ms
Langage machine:
RB0
4MHz



BSF STATUS, RP0 ; Accès TRISB dans Bank 1
Par l'utilisation du temporisateur TMR0 :

PORTB
BCF STATUS, RP1 RB3
 montrer comment on peut obtenir la période demandée ; RB4
MOVLW 0X0F ; W = 0F = 0000 1111 ,
 donner la configuration du registre OPTION correspondante ;


MOVWF TRISB ; RB0…RB3 en Entrées , RB4…RB7 en Sorties
 écrire en langage C, le programme qui réalise cette tâche. RB7
BCF STATUS, RP0 ; Accès POTRB dans Bank 0
CLRF PORTB ; RAZ registre de données du portB
4.2. Génération de longues durées : pour des valeurs importantes de durées de
temps, on peut utiliser le Timer 1 qui utilise un décompteur 16 bits, ou
simplement utiliser le Timer 0 auquel on associe un compteur de dépassements.
Langage C :
Ce compteur s'incrémente à chaque débordement du Timer 0.
Init_PortB() // configuration et initialisation
Dans ce cas, donner l'expression générale de la durée de temps T et calculer sa
{
valeur maximale Tmax. TRISB = 0x0F; // RB0…RB3 en Entrées , RB4…RB7 en Sorties
 PORTB = 0x00; // RAZ registre de données du portB
}

E. Benaata. Filière Ingénieurs – EEIN / 1. 2


UM5. E.N.S.A.M. Rabat. M-23-1 : Introduction aux Microcontrôleurs

Exercice 2 : Exercice 3 :

2.1. 3.1. Le compteur s'incrémente automatiquement après une temporisation :


#include <pic.h> #include <pic.h>
#define K RB0 // nommer RB0 char T;
#define L RB1 // nommer RB1 char COMPT ;
char CODE7SEG[10] =
void INIT_PortB() // Fonction initialisation du Port B {0x7E,0x0C,0xB6,0x9E,0xCC,0xDA,0xF8,0x0E,0xFE,0xCE};
{ //
TRISB = 0x01; // RB7..RB1 sorties, RB0 entrée void INIT_PortB() // Fonction initialisation du port B
PORTB = 0x00; // RAZ du port B {
} TRISB = 0x01; // RB0: entrée, RB1..7: sorties
void main() // Fonction principale }
{ void main()
INIT_PortB(); {
for(;;) // ou while(1) INIT_PortB();
{ COMPT = 0x00; // RAZ du compteur
if(!K) L = 1; // ou if(K == 0) for(;;)
else L = 0; {
} PORTB = CODE7SEG[COMPT]; // affiche (compteur)
} if(COMPT <= 9) // compteur décimal : 0 à 9
{
2.2. COMPT++;
… // même initialisation for(T = 0; T <= 2; T++) TEMPO();
void TEMPO() }
{ else
int i, j; COMPT = 0;
for(i = 0; i <= 20; i++) // boucle externe }
for(j = 0; j <= 255; j++); // boucle interne }
}
3.2. Le compteur s'incrémente après une action sur le bouton poussoir BP :
void main() //
{ ...
INIT_PortB(); if(!BP) // BP appuyé ?
for(;;) {
{ if(!K) COMPT++; // oui, incrémente compteur
{ L = 1; TEMPO(); }
L = 0; TEMPO(); } if (COMPT > 9) COMPT = 0; // RAZ compteur si > 9
else L = 0; ...
}
}

E. Benaata. Filière Ingénieurs – EEIN / 1. 3


UM5. E.N.S.A.M. Rabat. M-23-1 : Introduction aux Microcontrôleurs

Exercice 4 :
4.2.
4.1. La période du signal est de 40ms et son rapport cyclique est 50% : il suffit de On désigne par COMPT le compteur de dépassements du TMR0. COMPT est une
générer , grâce au TIMER 0, une durée de 20ms qui est équivalente à une demi variable 8 bits (Modulo 256).
période. Expression générale de la temporisation T : T = (256 – N) x COMPT x D x tcy (+ 2xtcy).
• Le TMR0 peut réaliser une temporisation maximale Tmax : Avec cette solution, on peut réaliser donc une temporisation maximale :
Tmax = (256 – 0) x 256 x 1µs = 65,536 ms
Tmax > T = 20 ms: on détermine le facteur de division D et la valeur initiale N. Tmax = (256 – 0) x 256 x 255 x tcy (+ 2xtcy) = 16,712 s; (tcy = 1µs)

 Facteur de prédivision calculé pour N = 0 : Dc = 20ms/(256 x 1µs) = 78,125 , ...


void Init_TMR0()
on sélectionne D = 128 ; {
OPTION = 0x06 ;
 Valeur calculée de N pour D = 128 : Nc = 256 – 20ms/(128 x 1µs) = 99,75 , T0IF = 0 ;
 N = 99 → T = (256 – 99) x 128 x 1µs (+2µs) = 20,098 ms ; }
 N = 100 → T = (256 – 100) x 128 x 1µs (+2µs) = 19,97 ms .
T0CS T0SE PSA PS2 PS1 PS0
void TEMPO()
• Le registre OPTION sera chargé par : {
0 0 0 0 0 1 1 0 = 0x06 char COMPT = 0 ;
... char N = 100 ; // ou 0x64
void Init() // Initialisation TMR0 et PortB if (T0IF) // ou if (T0IF = = 1)
{ {
OPTION = 0b00000110 // ou 0x06; T0IF = 0 ;
T0IF = 0; // RAZ dépassement (Reg. INTCON) COMPT++ ;
TRISB = 0x7F; // RB7 en sortie if (COMPT > 0x0A)
} COMPT = 0;
// TMR0 = N ;
void TEMPO() }
{ void main()
TMR0 = 100; // ou 0x64 {
T0IF = 0; // RAZ dépassement ...
while (T0IF == 0); // ou while (!T0IF) TEMPO() ; // Durée = ??
} ...
// }
void main()
{
Init(); // initialisation
RB7 = 0;
//
for(;;)
{ TEMPO(); // durée 20 ms 
NOP(); //
RB7 = ~RB7; } // inverse l'état
} // Fin du programme

E. Benaata. Filière Ingénieurs – EEIN / 1. 4


UM5. E.N.S.A.M. Rabat. M-23-1 : Introduction aux Microcontrôleurs

Annexes : for(;;)
{
A.1. Version complète de l'exercice 4.1. : TEMPO(); // Temporisation
NOP(); // Ne fait rien
//-------------------------------------- RB7 = ~RB7; // inverse l'état de RB7
// Exercice 4.1: Temporisation avec TMR0 }
//-------------------------------------- } // fin
#include <pic.h>
#define N 100 // Valeur initiale (100 ou 99) dans TMR0
//-------------- A.2. Version de test de l'exercice 4.2. :
void Init_TMR0() // Initialisation du Timer 0 //---------------------------------------------------
{ // Exercice 4.2: Test TMR0 + Compteur de dépassements
// Config Tmr0 par reg. OPTION: //---------------------------------------------------
// -------------------------------------- #include <pic.h>
// |RBPU|INEDG|TOCS|T0SE|PSA|PS2|PS1|PS0| #define N 200
// -------------------------------------- char COMPT;
PS0 = 0; //--------------------------------------
PS1 = 1; // PS2..PS0 = 110: D = 128 void init()
PS2 = 1; {
PSA = 0; // PSA = 0: affecte prédiv. au TMR0 OPTION = 0x08; // D = 1 pour test
T0SE = 0; // Non utilisé (0) T0IF = 0;
T0CS = 0; // T0CS = 0: Source interne de l'horloge }
INTEDG = 0; // Non utilisé (0) //--------------------------------------
RBPU = 0; // Non utilisé (0) void TEMPO()
// {
// ou OPTION = 0b00000110 ou OPTION = 0x06; COMPT = 0;
// TMR0 = N;
T0IF = 0; // RAZ drapeau dépassement (Reg. INTCON) while(COMPT < 0x05) // 0x05 pour test
} {
//---------------- Initialisation du port B if(T0IF)
void Init_PortB() {
{ ++COMPT;
TRISB = 0x7F; // RB7 en sortie (les autres en entrées) T0IF = 0;
} TMR0 = N;
//--------------- Fonction temporisation }
void TEMPO() }
{ }
TMR0 = N; // Recharge valeur initiale dans TMR0 //--------------------------------------
T0IF = 0; // RAZ dépassement void main()
while (T0IF == 0); // ou while (!T0IF) {
} init(); // initialisation
//--------------- Fonction Principale for(;;)
void main() {
{ NOP();
Init_TMR0(); // initialisation TMR0 TEMPO();
Init_PortB(); // initialisation Port B NOP();
RB7 = 0; // RAZ ligne RB7 }
// } // Fin

E. Benaata. Filière Ingénieurs – EEIN / 1. 5


UM5. E.N.S.A.M. Rabat. M-23-1 : Introduction aux Microcontrôleurs

A.3. Différentes façons de produire une temporisation :

• Utilisation d'une ou plusieurs boucles finies à base de l'instruction for ou while :


BP Anti-rebonds Vers µContrôleur
for(i = 0 ; i < N; i++) ; // une seule boucle

ou, pour une durée plus longue: Anti-rebonds matériel: circuit RC , Bascule, …

for(i = 0 ; i < N; i++) Anti-rebonds logiciel: temporisation (qq ms à qq 10ms), ...


for(j = 0 ; j < M; j++) ; // boucles imbriquées

• Utilisation de macros ou fonctions prédéfinies de temporisation : Solution logicielle possible :

...
 delay(n) : n désigne le nombre de cycles machine.
if(!BP)
Exemple : delay(10) produit une temporisation de 20µs si tcy = 2µs, { // BP appuyé ?
for(i = 0 ; i < Tt; i++) ; // Tempo. Anti-rebonds
 delay_us(n) : n désigne le nombre de µs. COMPT++; // incrémente compteur
Exemple : delay_us(20) produit une temporisation de 20µs, }
if (COMPT > 9) COMPT = 0; // RAZ compteur si > 9
 delay_ms(n) : n désigne le nombre de ms. ...
Exemple : delay_ms(20) produit une temporisation de 20ms,

• Utilisation des temporisateurs intégrés dans le microcontrôleur (EX. 4).



A.4. Note sur l'utilisation de boutons poussoirs :

+V

1 Bouton au repos

Bouton appuyé:
2
BP état transitoire

Bouton appuyé:
3
état stable

1 2 3

E. Benaata. Filière Ingénieurs – EEIN / 1. 6

Vous aimerez peut-être aussi