Sie sind auf Seite 1von 41

République Algérienne Démocratique et Populaire

Ministère de l’Enseignement Supérieur et de la Recherche Scientifique

Université Abderrahmane Mira – Bejaia

Faculté de la Technologie

Département d’Electronique

Thème

Programmation en C
du Microcontrôleur
PIC 16F877

Présenté par : Encadré par :

 Mr. :BOUKARI Mansour  Mr. :HADJI Slimane

Master S1 2009/2010
Sommaire

Introduction Générale…………………………………………………………………………………………...1

Chapitre 1 : Etude théorique du PIC 16F877


Introduction…………………………………………………………………………………………………….2

1. Présentation du microcontrôleur PIC 16F877…………………………………………………...2


2. Différents types de mémoire…………………………………………………………………………….5
3. Configuration de l’oscillateur (horloge) ……………………………………………………………6
4. Ports d’Entrées/Sorties……………………………………………………………………………………7
5. Timers…………………………………………………………………………………………………………..11
6. Interface MSSP: (Master Synchronous Serial Port)……….………………………………….14
7. InterfaceUSART :
(Universal Synchronous Asynchronous Receiver Transmitter)…………….………….15
8. Convertisseur Analogique-Numérique....………………………………………………………...16
9. Modules CCP (Capture/Compare/PWM) ………………………………………………………..18

Conclusion……………………………………………………………………………………....…………….20

Chapitre 2 : Programmation en C et application


Introduction………………………………………………………………………………………………….21

1. Choix du compilateur…………………………………………………………………………………….21
2. Quelques notions de programmation en C sous SourceBoost…………………………..21
3. Structure d’un programme…………………………………………………………………………….27
4. Exemple d’application……………………………………………………………………………………27

Conclusion…………………………………………………………………………………………………….32

Conclusion Générale……………………………………………………………………………………..……..33

Bibliographie
Introduction Générale
Le développement des applications à base des microcontrôleurs PIC est devenu de plus en
plus courant, ceci est dû à plusieurs causes : beaucoup de ressources internes (périphériques
intégrés), mémoires embarquées de plus en plus grande, vitesse de calcul accrue… En effet, un
microcontrôleur est un composant parfaitement adapté à des applications embarquées, il permet, en
le programmant, d’effectuer et de contrôler une tâche tout en comparant son état à des conditions
préfixées par l’utilisateur.

L’utilisation des microcontrôleurs fait appel tout d’abord à leur programmation. Il existe
plusieurs méthodes de programmation selon le langage utilisé, par exemple en assembleur on peut
écrire un programme où on va tirer le maximum des performances du microcontrôleur mais ce
programme nécessite beaucoup de travail et surtout beaucoup de temps. Heureusement, avec la
montée en puissance des microcontrôleurs, on voit apparaitre des compilateurs en langage C qui
permettent de gagner un temps considérable pour le développement des programmes.

Dans ce travail notre choix est porté vers le PIC 16F877. Dans le premier chapitre nous allons
étudier d’une manière générale ce microcontrôleur et ses différentes ressources internes, ensuite un
deuxième chapitre destiné à la programmation de ce microcontrôleur en langage C en utilisant le
compilateur SourceBoost, dans ce chapitre nous allons exposer quelques notions de programmation
en C et de proposer un exemple d’application.

1
Chapitre 1 Etude théorique du PIC 16F877

Introduction :
Un microcontrôleur est un composant électronique ayant une unité de traitement de
données, des mémoires, des interfaces de communication (entrées/sorties, ports séries . . .) et de
multiple ressources interne. Souvent un microcontrôleur se contente d’un bus de données de 8-bits
ou 16-bits, on peut dire alors qu’il est moins puissant qu’un microprocesseur.

1 Présentation du microcontrôleur PIC 16F877 :


 Définition d’un PIC : [1]

Un PIC (Programmable Interface Controller) est un microcontrôleur de Microchip Technology


Inc.

Un PIC est un composant dit RISC (Reduced Instructions Set Computer), ou encore composant à
jeu d’instruction réduit. Ces microcontrôleurs sont conçus sur une architecture dite HAVARD, elle est
basée sur deux bus, un pour les données (bus de données) et l’autre pour les instructions (bus de
programme).

 Différentes familles des PICs : [2]

La famille des PICs est subdivisée en trois grandes familles :

 Base line : c’est la famille où l’unité centrale travaille sur 12-bits, exemple : 12CXXX…
 Mid-Range : c’est la famille où l’unité centrale travaille sur 14-bits, exemple : 16F877.
 High Performance : c’est la famille où l’unité centrale travaille sur 16-bits, exemple : 18FXXX,
18CXXX …

 Identifier un PIC :[3]

La référence d’un microcontrôleur PIC est de la forme NN LLL XXX où :

 NN désigne la famille à laquelle appartient le circuit.


 LLL est un ensemble d’une, deux ou trois lettres qui indique le type de mémoire de
programme contenue dans le circuit et si la plage de tension d’alimentation est normale ou
étendue.
 XXX est un ensemble de deux ou trois chiffres constituant la référence du circuit.

Exemple du 16F877-20 :

 16 : indique la famille Mid-Range.


 F : indique le type de mémoire programme utilisée : F pour Flash.
 877 : identité.
 20 : indique la fréquence d’horloge.

1.1 Principales caractéristiques du PIC 16F877 : [4]


Un PIC 16F877 possède les caractéristiques suivantes :

2
Chapitre 1 Etude théorique du PIC 16F877

 Une fréquence de fonctionnement allant jusqu’à 20MHz.


 Jeu d’instructions de 35 instructions.
 Une mémoire de programme de type FLASH sur 8K mots (1 mot=14 bits).
 Une mémoire de données de type RAM sur 368 octets.
 Une mémoire de données de type EEPROM sur 256 octets.
 Une pile (Stack) à 8 niveaux.
 14 sources d’interruptions.
 Un chien de garde WDT (Watch Dog Timer).
 Timer0 (compteur 8-bits avec pré-diviseur).
 Timer1 (compteur 16-bits avec pré-diviseur et possibilité d’utiliser une horloge externe).
 Timer2 (compteur 8-bits avec pré-diviseur et post-diviseur).
 Un convertisseur Analogique-Numérique 10-bits à 8 entrées multiplexées.
 Deux modules de capture/comparaison/PWM.
 Ports Entrées/Sorties : A, B, C, D et E.
 Une interface de communication série (MSSP, USART).
 Une interface de communication parallèle (PSP).
 Tension de fonctionnement est entre 2.0V et 5.5V.

1.2 Brochage du PIC 16F877 : [4]

Le boitier ci-contre décrit


l’architecture externe du 16F877
qui comprend 40 pins dont :

 33 pins d’entrées/sorties
multiplexées avec d’autres
fonctions.
 4 pins pour l’alimentation :
VDD et VSS.
 2 pins pour l’oscillateur :
OSC0 et OSC1.
 1 pin pour le RESET : MCLR.

Figure 1.2.2 : Brochage du 16F877

3
Chapitre 1 Etude théorique du PIC 16F877

1.3 Architecture interne : [4]

Figure 1.2.3 : Architecture interne du PIC16F877.

Une fois le programme est stocké dans la mémoire (Program Memory) et le µC est initialisé,
l’instruction à exécuter est désignée par le PC (Program Counter) et sera chargée dans le registre
d’instruction (Instruction reg) au moyen d’un bus de programme sur 14-bits, puis elle sera décodée
dans le décodeur et le contrôleur d’instruction (Instruction Decode & Control) et ensuite dirigée vers
l’UAL (ALU) avec les données chargées à partir des pins configurées comme entrées, l’UAL fera
l’opération nécessaire et sauvegardera le résultat temporairement dans le registre de travail (W reg)
sur 8-bits, ce résultat sera aussi mit dans la RAM à l’aide d’un bus de données sur 8-bits.

4
Chapitre 1 Etude théorique du PIC 16F877

1.4 Registres de Fonction Spéciale (SFR : Special Function Registers) : [4]


Les SFR sont des registres utilisés par l’unité centrale et les modules périphériques, ils sont
implémentés comme une RAM statique. Ils jouent le rôle d’un tableau de bord pour configurer les
différentes ressources internes du PIC, parmi ces registres il y a :

1.4.1 Registre STATUS :( adresses: 03h, 83h, 103h, 183h)


Contient les différents bits flags liés aux opérations arithmétiques, les indicateurs de RESET et le bit
de sélection de la BANK mémoire.

1.4.2 Registre OPTION_REG :(adresses : 81h, 181h)


Ce registre peut être lu et écrit, il contient les bits de contrôle qui permettent de configurer le pré-
diviseur, les interruptions externes, le TMR0 et le pull-up sur le PORTB.

1.4.3 Registre INTCON :(adresses : 0Bh, 8Bh, 10Bh, 18Bh)


C’est le registre de contrôle des interruptions.

2 Différents types de mémoire :


Le 16F877 possède 3 types de mémoire :

 Une mémoire FLASH pour stocker le programme.


 Une RAM pour les données.
 Une EEPROM pour les données.

2.1 La mémoire FLASH :


Est une mémoire qui peut être écrite et effacée
électriquement. Elle est conçue pour stocker le
programme et elle est sur 8k mots (1 mot=14-bits).

Figure 1.3.1 : Organisation de mémoire programme

2.2 La RAM et l’EEPROM :


La RAM est sur 368 octets, elle sert à stocker les données temporaires (résultat de l’UAL…), elle
comprend tous les registres de fonction spéciale. Cette mémoire est partitionnées en 4 parties,
chaque partie est appelée BANK et comporte 7Fh adresses (i.e 128 octets), chaque BANK peut être
sélectionné à partir des bits RP1 et RP0 du registre STATUS comme suit :

5
Chapitre 1 Etude théorique du PIC 16F877

RP1 :RP0 BANK Tableau 1.3 : Sélection des


00 0 BANKs.
01 1
10 2
11 3

L’EEPROM est sur 256 octets prévue pour sauvegarder les données en cas de perte
d’alimentation, le nombre de cycle lecture/écriture est limité à l’ordre de 106 cycles.

3 Configuration de l’oscillateur (horloge) : [4]


Le PIC 16F877 peut fonctionner en 4 modes d’oscillateur :

 LP : Low Power crystal : quartz à faible puissance.


 XT : Crystal/Resonator : quartz/résonateur en céramique.
 HS : High Speed crystal/resonator : quartz à haute fréquence/résonateur en céramique HF.
 RC : circuit RC.

Chacun de ces modes peut être sélectionné à travers les bits de configuration FOSC1 et FOSC0
(registre : CONFIGURATION WORD à 2007h), comme suit :

FOSC1 :FOSC0 Mode Tableau 1.4 : Configuration de


00 LP l’oscillateur.
01 XT
10 HS
11 RC

3.1 Oscillateur en Quartz ou à Résonateur Céramique :


En mode LP, XT ou HS, un quartz ou un résonateur en céramique est connecté aux pins
OSC1/CLKIN et OSC2/CLKOUT pour établir l’oscillation. La figure suivante montre comment ce quartz
ou ce résonateur en céramique est connecté au microcontrôleur :

Figure 1.4.1 a) : Oscillateur en quartz/ résonateur.

Toujours dans l’un de ces modes de fonctionnement, le microcontrôleur peut avoir une horloge
externe connectée à la broche OSC1/CLKIN comme le montre la figure suivante :

6
Chapitre 1 Etude théorique du PIC 16F877

Figure 1.4.1 b) : Connexion d’une horloge externe.

3.2 Oscillateur RC :
La fréquence de l’oscillation dépend du voltage, des valeurs de R et C et de la température de
fonctionnement. La figure (1.4.2) montre comment connecter un circuit RC au microcontrôleur :

Figure 1.4.2 : Oscillateur RC.

4 Ports d’Entrées/Sorties : [4]


Le PIC 16F877 dispose de 5 ports entrées/sorties (au total 33 pins) : port A, B, C, D et E. De plus
il y a le PSP (Parallel Slave Port) : le Port Parallèle Esclave.

4.1 PORT A :
Le PORTA est un port bidirectionnel de 6-bits (6 entrées/sorties) : de RA0 jusqu'à RA5; le
registre correspondant qui définit la direction des données est le TRISA, la mise à ‘1’ d’un bit du
TRISA configura la broche correspondante à ce bit comme entrée, et la mise à ‘0’ de ce bit mettra la
broche correspondante comme sortie.

La broche RA4 est multiplexée avec une autre fonction qui est l’entrée pour l’horloge du
TIMER0, cette broche deviendra donc RA4/T0CKI. Les autres pins sont multiplexées avec les entrées
analogiques du CAN et l’entrée VREF, pour cela, le registre ADCON1 permet de déterminer la fonction
de chaque pin.

7
Chapitre 1 Etude théorique du PIC 16F877

Tableau 1.5.1 : Résumé des registres associés avec le PORTA

Valeur Valeur
Adresse Nom Bit-7 Bit- Bit- Bit- Bit-3 Bit-2 Bit-1 Bit-0 sur sur
6 5 4 POR, autres
BOR RESET
05h PORTA - - RA5 RA4 RA3 RA2 RA1 RA0 --0x 0000 --0u 0000
85h TRISA - - Registre de direction des données PORTA --11 1111 --11 1111
9Fh ADCON1 ADFM - - - PCFG3 PCFG2 PCFG1 PCFG0 --0- 0000 --0- 0000
x : inconnu, u : inchangé, - : emplacements non implémentés (‘0’), les cellules ombragées ne sont pas
utilisées par le PORTA.

Au démarrage (Power-On Reset ‘POR’), les pins de ce port sont configurés comme des entrées
analogiques et lus comme ‘0’.

4.2 PORT B :
Le PORTB est un port bidirectionnel de 8-bits (8 entrées/sorties) : de RB0 jusqu'à RB7; le
registre correspondant qui définit la direction des données est le TRISB, la mise à ‘1’ d’un bit du TRISB
configura la broche correspondante à ce bit comme entrée, et la mise à ‘0’ de ce bit mettra la broche
correspondante comme sortie.

En mode entrée, chaque broche du PORTB doit être maintenue à un niveau haut à l’aide des
résistances de pull-up, ceci en mettant à ‘0’ le bit RBPU (du registre OPTION). En mode sortie ou lors
d’un POR (Power-On Reset), ces pull-ups sont désactivés. Un changement d’état sur l’une des
broches RB4, RB5, RB6 et RB7 déclenche une interruption, ceci n’est possible que pour celles qui sont
configurées comme entrées.

Tableau 1.5.2 : Résumé des registres associés avec le PORTB

Valeur Valeur
Adresse Nom Bit-7 Bit-6 Bit-5 Bit-4 Bit-3 Bit-2 Bit-1 Bit- sur sur
0 POR, autres
BOR RESET
06h, PORTB RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 xxxx xxxx uuuu uuuu
106h
86h, TRISB Registre de direction des données PORTB 1111 1111 1111 1111
186h
81h, OPTION_REG RBPU INTEDC T0CS T0SE PSA PS2 PS1 PS0 1111 1111 1111 1111
181h

x : inconnu, u : inchangé, les cellules ombragées ne sont pas utilisées par le PORTB.

4.3 PORT C :
Le PORTC est un port bidirectionnel de 8-bits (8 entrées/sorties) : de RC0 jusqu'à RC7; le
registre correspondant qui définit la direction des données est le TRISC, la mise à ‘1’ d’un bit du TRISC
configura la broche correspondante à ce bit comme entrée, et la mise à ‘0’ de ce bit mettra la broche
correspondante comme sortie.

8
Chapitre 1 Etude théorique du PIC 16F877

Tableau 1.5.3 : Résumé des registres associés avec le PORTC


Valeur Valeur
Adresse Nom Bit-7 Bit- Bit- Bit- Bit-3 Bit-2 Bit-1 Bit-0 sur sur
6 5 4 POR, autres
BOR RESET
07h PORTC RC7 RC6 RC5 RC4 RC3 RC2 RC1 RC0 xxxx xxxx uuuu uuuu
87h TRISC Registre de direction de données PORTC 1111 1111 1111 1111
x : inconnu, u : inchangé.

4.4 PORT D :
Le PORTD est un port bidirectionnel de 8-bits (8 entrées/sorties) : de RD0 jusqu'à RD7; le
registre correspondant qui définit la direction des données est le TRISD, la mise à ‘1’ d’un bit du
TRISD configura la broche correspondante à ce bit comme entrée, et la mise à ‘0’ de ce bit mettra la
broche correspondante comme sortie.

Le PORTD peut être configuré comme port parallèle esclave : PSP (Parallel Slave Port) en
mettant à ‘1’ le bit PSPMODE du registre TRISE.

Tableau 1.5.4 : Résumé des registres associés avec le PORTD

Valeur Valeur
Adresse Nom Bit-7 Bit- Bit-5 Bit-4 Bit-3 Bit-2 Bit-1 Bit-0 sur POR, sur
6 BOR autres
RESET
08h PORTD RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 xxxx xxxx uuuu uuuu
88h TRISD Registre de direction de données PORTD 1111 1111 1111 1111
89h TRISE IBF OBF IBOV PSPMODE - Registre de direction 0000 -111 0000 -111
de données PORTE
x : inconnu, u : inchangé, - : emplacements non implémentés (‘0’), les cellules ombragées ne sont pas
utilisées par le PORTD.

4.5 PORT E :
Le PORTE a 3 broches : RE0, RE1 et RE2, configurables en entrées ou en sorties à partir des
trois premiers bits du registre TRISE. Ces broches sont multiplexées avec les entrées du CAN
(Convertisseur Analogique Numérique).

Au démarrage (Power-On Reset ‘POR’), les pins de ce port sont configurés comme des entrées
analogiques et lus comme ‘0’.

9
Chapitre 1 Etude théorique du PIC 16F877

Tableau 1.5.5 : Résumé des registres associés avec le PORTE

Valeur Valeur
Adresse Nom Bit-7 Bit- Bit-5 Bit-4 Bit-3 Bit-2 Bit-1 Bit-0 sur sur
6 POR, autres
BOR RESET
09h PORTE - - - - - RE2 RE1 RE0 ---- -xxx ---- -uuu
89h TRISE IBF OBF IBOV PSPMODE - Registre de direction de 0000 -111 0000 -111
données PORTE
9Fh ADCON1 ADFM - - - PCFG3 PCFG2 PCFG1 PCFG0 --0- 0000 --0- 0000
x : inconnu, u : inchangé, - : emplacements non implémentés (‘0’), les cellules ombragées ne sont pas
utilisées par le PORTE.

4.6 Port Parallèle Esclave (PSP: Parallel Slave Port) : [4]


C’est le PORTD qui fonctionne en PSP (sur 8-bits) quand le bit de contrôle PSPMODE (du
registre TRISE) est à ‘1’. La mise à 1 du bit PSPMODE activera aussi les pins RD (Read), WR (Write) et
CS (Chip Select) (physiquement sont celles du PORTE). Pour cette fonctionnalité, les broches du
PORTE doivent être configurées en entrées (mise à ‘1’ des bits 0, 1 et 2 dans TRISE) et aussi il faut
mettre les 4 premiers bits du registre ADCON1 à ‘1’ pour que le PORTE soit en E/S numériques (pas
de conversion A/N sur ce port).

Le PSP peut interfacer directement avec un microprocesseur 8-bits (bus de données sur 8-bits)
à l’aide des broches :

 CS : pour valider le PIC.


 RD : pour indiquer au PIC qu’il doit lire.
 WR : pour indiquer au PIC qu’il doit écrire.

L’écriture dans le PSP ce fait lorsque CS et WR sont à ‘0’, et quand l’une de ces broches se met à ‘1’ le
bit flag IBF (Input Buffer Full) (du registre TRISE) se met à ‘1’ pour signaler la fin de l’écriture.

La lecture du PSP ce fait lorsque CS et RD sont à ‘0’. Dès la mise à ‘0’ de ces derniers, le bit flag OBF
(Output Buffer Full) (du registre TRISE) se met immédiatement à ‘0’ pour indiquer que le PORTD est
en attente pour être lue par le bus externe. Quand CS ou RD se met à ‘1’, c’est la fin de la lecture et
qui sera signalée par le bit PSPIF (PSP Interrupt Flag) (du registre PIR1) en se mettant à ‘1’.

Quand le mode PSP est désactivé, les bits IBF et OBF doivent être à ‘0’. Cependant, même si le bit
IBOV était à ‘1’, il doit être effacé par logiciel.

10
Chapitre 1 Etude théorique du PIC 16F877

5 Timers :[4]

5.1 Timer0 :
Le Timer0 est un 8-bits temporisateur /compteur.

En mode temporisateur, sélectionné en mettant à ‘0’ le bit T0SC (OPTION_REG),


l’incrémentation du Timer0 se produit chaque cycle d’instruction sans le pré-diviseur, l’écriture dans
le registre TMR0 fait que l’incrémentation sera arrêtée durant les deux cycles d’instruction suivants.

Le mode compteur est sélectionné en mettant à ‘1’ le bit T0SC (OPTION_REG), dans ce cas le
Timer0 sera incrémenté soit sur front montant soit sur front descendant de l’horloge externe sur la
patte RA4/T0CKI. Le front d’incrémentation est sélectionné à partir du bit T0SE (OPTION_REG).

Le Timer0 peut engendrer une interruption lors d’un débordement de FFh à 00h, ce
débordement mit à ‘1’ le bit T0IF (INTCON) pour signaler l’interruption, après la fin de l’interruption
ce bit doit être effacé par logiciel. Il suffit de mettre à ‘0’ le bit T0IE (INTCON) pour désactiver
l’interruption du Timer0.

Pour ce module Timer0 un pré-diviseur (Prescaler) est disponible et il est partagé avec le
Timer Chien de garde WDT (Watchdog Timer), l’assignation du pré-diviseur au Timer0 fait que le
WDT n’a pas de pré-diviseur associé, et vice-versa. L’assignation et la sélection de taux de division de
fréquence se fait à l’aide des bits PSA (pour l’assignation) et PS2 :PS0 (pour le taux) (registre
OPTION_REG). Quand le pré-diviseur est assigné au Timer0, l’écriture dans le registre TMR0 efface le
pré-diviseur mais ne change pas son assignation, et aussi, cette écriture fait que l’incrémentation ne
reprenne qu’après un délai de trois cycles d’instructions.

Figure1.6.1 : Schéma interne du Timer0

5.2 Timer1 :
Le Timer1 est un temporisateur/compteur 16-bits, il possède 2 registres : TMR1H et TMR1L
chacun est sur 8-bits qui s’incrémentent de 0000h à FFFFh. Le Timer1 déclenche une interruption sur
un passage de FFFFh à 0000h (débordement du Timer1), cette interruption est signalée par la mise à
‘1’ du bit TMR1IF (registre PIR1). Cette interruption peut être activée/désactivée en mettant à’1’/’0’
le bit TMR1IE (registre PIE1).

Ce module peut être activé/désactivé à l’aide du bit TMR1ON (registre T1CON) ,1/0.

Le Timer1 fonctionne en deux modes :

11
Chapitre 1 Etude théorique du PIC 16F877

a. Mode temporisateur :

Dans ce cas le Timer1 est incrémenté chaque cycle d’instruction. Ce mode est sélectionné en
mettant à ‘0’ le bit TMR1CS (registre T1CON), cependant l’horloge du timer est FOSC/4 et le bit de
contrôle de synchronisation avec l’horloge interne T1SYNC (registre T1CON) n’a pas d’effet puisque
l’horloge utilisée est l’interne.

b. Mode compteur :

Ce mode est sélectionné en mettant à ‘1’ le bit TMR1CS. Et dès que le Timer1 est activé en
mode compteur, le module doit avoir un front descendant avant que l’incrémentation ne commence.
Cependant le Timer1 fonctionne soit en mode synchrone, soit en mode asynchrone.

En mode synchrone, sélectionné en mettant à ‘0’ le bit T1SYNC, le timer est incrémenté
chaque front montant de l’horloge externe sur la patte RC1/T1OSI/CCP2 si le bit T1OSCEN est mis à
‘1’, ou sur la patte RC0/T1OSO/T1CKI si le bit T1OSCEN est mis à ‘0’. Dans ce cas l’horloge externe est
synchronisée avec la phase de l’horloge interne. Dans cette configuration et durant le mode SLEEP
(mode sommeil), l’incrémentation du timer est arrêtée puisque le circuit de synchronisation est
arrêté.
En mode asynchrone, sélectionné en mettant à ‘1’ le bit T1SYNC, le timer est incrémenté à
chaque front montant de l’horloge externe sans que cette dernière ne soit synchronisée avec
l’horloge interne. Dans cette configuration et durant le mode SLEEP (mode sommeil), le timer
continu l’incrémentation et peut générer une interruption sur un débordement qui réveille le µC de
son sommeil.
Remarque : [3]

Il existe deux sources d’horloge externe : un signal externe appliqué à la patte RC0/T1OSO/T1CKI, ou
il peut utiliser le signal d’un oscillateur qui lui est propre en mettant à ‘1’ le bit T1OSCEN, réalisé en
connectant un quartz entre les pattes RC0/T1OSO/T1CKI et RC1/T1OSI/CCP2.

 Registre T1CON :(adresse : 10h)

U-0 U-0 L/E-0 L/E-0 L/E-0 L/E-0 L/E-0 L/E-0


- - T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON
Bit7 Bit0

Bit 7 Non-implémenté : Lire comme ‘0’.


Bit 6 Non-implémenté : Lire comme ‘0’.
Bit 5:4 T1CKPS1:T1CKPS0 : Bits de sélection du taux de pré-division de l’horloge du Timer1.
11 = 1:8
10 = 1:4
01 = 1:2
00 = 1:1
Bit 3 T1OSCEN : Bit de contrôle de validation de l’oscillateur du Timer1.
1 = Oscillateur activé.
0 = Oscillateur désactivé.
Bit 2 T1SYNC : Bit de contrôle de synchronisation de l’horloge externe du Timer1.
Quand TMR1CS = 1 :
1 = Ne pas synchroniser l’horloge externe entrante.
0 = Synchroniser l’horloge externe entrante.

12
Chapitre 1 Etude théorique du PIC 16F877

Quand TMR1CS = 0 :
Ce bit est ignoré. Le Timer1 utilise l’horloge interne quand TMR1CS = 0.
Bit 1 TMR1CS : Bit de sélection de source d’horloge du Timer1.
1 = Horloge externe sur la pin RC0/T1OSO/T1CKl (sur le front montant).
0 = Horloge interne (FOSC / 4).
Bit 0 TMR1ON : Bit de mise en marche du Timer1.
1 = Active le Timer1.
0 = Stoppe le Timer1.

Figure1.6.2 : Schéma interne du Timer1

5.3 Timer2 :
Le Timer2 est un temporisateur 8-bits avec un pré-diviseur, un post-diviseur et un registre sur
8-bits PR2 dit registre de période. Le registre TMR2 est incrémenté, à l’aide de l’horloge interne
(FOSC/4), de 00h jusqu’à une valeur spécifiée dans le registre PR2, puis il recommence de 00h.
Lorsqu’il y a une égalité entre le contenu du registre TMR2 et celui du PR2, un signal sera appliqué au
post-diviseur (4-bits) pour générer une interruption.

Le Timer2 est arrêté sur la mise à ‘0’ du bit TMR2ON (du registre T2CON).

 Registre T2CON :(adresse : 12h)

U-0 L/E-0 L/E-0 L/E-0 L/E-0 L/E-0 L/E-0 L/E-0


- TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
Bit7 Bit0

Bit 7 Non-implémenté : Lire comme ‘0’.


Bit 6:3 TOUTPS3:TOUTPS0 : Bits de sélection du taux de post-division de la sortie du Timer2.
0000 = 1:1 valeur de post-division.
0001 = 1:2 valeur de post-division.
.
.
.
1111 = 1:16 valeur de post-division.
Bit 2 TMR2ON : Bit de mise en marche du Timer2.
1 = Active le Timer2.
0 = Stoppe le Timer2.
Bit 1:0 T2CKPS1:T2CKPS0 : Bits de sélection du taux de pré-division de l’horloge du Timer2.

13
Chapitre 1 Etude théorique du PIC 16F877

00 = Pré-division par 1.
01 = Pré-division par 4.
1x = Pré-division par 16.

Figure1.6.3 : Schéma interne du Timer2

6 Interface MSSP: (Master Synchronous Serial Port): [4]


Le MSSP est une interface de communication série, qui permet une communication série avec
des microcontrôleurs et d’autres composants périphériques (EEPROMs séries, afficheurs LCD, CAN…).
Le MSSP fonctionne en deux modes :

 Mode SPI (Serial Peripheral Interface).


 Mode I2C (Inter-Inegrated Circuit).

6.1 Mode SPI:


Ce mode permet, de façon synchrone, de transmettre et de recevoir simultanément des
données sur 8-bits, ceci en utilisant 3 pattes et peut être 4 :

 La patte SDO (Serial Data Out): est la sortie des données.


 La patte SDI (Serial Data In): est l’entrée des données.
 La patte SCK (Serial Clock) : est utilisée pour synchroniser l’échange des données, elle est en
sortie sur le maitre et une entrée sur l’esclave. La mise à ‘1’ du bit CPK (registre SSPCON
adresse : 14h) permettra de valider les données sur front descendant, et sur front montant si
‘0’.
 La patte SS (Slave Select) : permet de sélectionner soit le mode maître, soit le mode esclave.

Le port MSSP est activé en mettant à ‘1’ le bit SSPEN (registre SSPCON). Pour redémarrer et
reconfigurer le mode SPI, on mit à ‘0’ le bit SSPEN, réinitialise le registre SSPCON, ensuite on mit à ‘1’
le bit SSPEN. Ceci configure les pattes SDO, SDI, SCK et SS pour le MSSP.

14
Chapitre 1 Etude théorique du PIC 16F877

Une donnée est reçue/transmise s’il y aura une écriture dans le registre SSPBUF, et quand cette
opération est établie, le bit SSPIF se mit à ‘1’ pour le signaler (déclanchement d’une interruption).

En mode maître, le µC peut transférer les données à m’importe quel moment parce que c’est lui qui
contrôle l’horloge (SCK). Tandis qu’en mode esclave, les données sont reçues ou transmises à
chaque coup de l’horloge (SCK).Cependant, il peut recevoir/transmettre des données en mode SLEEP,
le µC s’éveillera lors de la réception de données.

6.2 Mode I2C :


Dans ce cas deux pattes sont utilisées pour le transfert des données, SCL qui est la patte de
l’horloge, et SDA qui est la patte des données. Ce mode est activé an mettant à ‘1’ le bit SSPEN
(registre SSPCON).

Le transfert de données se fait à travers le registre SSPSR qui n’est accessible qu’à partir le
registre SSPBUF, donc les données qui seront transmises/reçues, seront écrites dans le registre
SSPBUF. Vu qu’on peut connecter plusieurs maîtres/esclaves dans ce cas, le µC utilise des adresses
pour l’information envoyée ne sera prise en compte que par le composant de destination.

7 Interface USART :( Universal Synchronous Asynchronous Receiver


Transmitter): [4]
Le module USART est un module de communication série, il est connu aussi sous SCI (Serial
Communications Interface). L’USART peut être configuré en 3 modes de fonctionnement :

 Asynchrone (Full Duplex).


 Synchrone Maître (Half Duplex).
 Synchrone Esclave (Half Duplex).

Le bit SPEN (registre RCSTA) et les bits 6 et 7 du registre TRISC doivent être à ‘1’ pour que les deux
pattes RC6/TX/CK et RC7/RX/DT soient configurées en USART.

7.1 Mode Asynchrone :


En mode asynchrone (Full Duplex) l’USART peut communiquer avec les micro-ordinateurs, on
peut sélectionner ce mode en mettant à ‘0’ le bit SYNC (du registre TXSTA à l’adresse 98h).
 Émission asynchrone :

Elle suit la procédure suivante :

 Initialisation du registre SPBRG par une valeur pour déterminer la vitesse de transmission.
 Validation du port asynchrone série.
 Si on désire des interruptions, on doit mettre à ‘1’ le bit TXIE (bit de validation de
l’interruption de transmission de l’USART) (registre PIE1 à l’adresse 8Ch).
 Si on désire transmettre 9-bits, on doit mettre à ‘1’ le bit TX9 (registre TXSTA).
 Validation de la transmission en mettant à ‘1’ le bit TXEN (registre TXSTA), ce qui mettra le bit
TXIF (registre PIR1, adresse 0Ch) à ‘1’.
 Ecriture du 9ème bit dans TX9D (registre TXSTA), si la transmission 9-bits est sélectionnée.

15
Chapitre 1 Etude théorique du PIC 16F877

 Ecriture de l’octet à transmettre dans le registre TXREG (début de la transmission).


 Si on utilise les interruptions, il faut s’assurer que les bits GIE et PEIE (registre INTCON) sont à
‘1’.

 Réception asynchrone :

Elle suit la procédure suivante :

 Initialisation du registre SPBRG par une valeur pour déterminer la vitesse d’émission.
 Validation du port asynchrone série.
 Si on désire des interruptions, on doit mettre à ‘1’ le bit RCIE (bit de validation de
l’interruption de réception de l’USART) (registre PIE1 à l’adresse 8Ch).
 Si on désire recevoir 9-bits, on doit mettre à ‘1’ le bit TX9 (registre RCSTA, adresse 18h).
 Validation de la réception en mettant à ‘1’ le bit CREN (registre RCSTA).
 Génération d’une interruption lors de la fin de réception, qui sera signalée par la mise à ‘1’
du bit RCIF (registre PIR1). Cette interruption ne sera générer que lorsque le bit de validation
de l’interruption RCIE (registre PIE1) est ‘1’.
 Lecture du registre RCSTE pour avoir le 9ème bit (si la réception 9-bits est validée).
 Lecture du registre RCREG pour avoir l’octet reçu.
 Si on utilise les interruptions, il faut s’assurer que les bits GIE et PEIE (registre INTCON) sont à
‘1’.

7.2 Mode synchrone :


En mode synchrone (Half Duplex) l’USART peut communiquer avec des composants
périphériques tels que les circuits intégrés CAN et CNA, les EEPROMs séries ect.

Le principe est le même que celui du mode asynchrone avec deux différences majeures :

 Émission et réception simultanées ne sont pas possibles, le fait d’activer l’une désactive
automatiquement l’autre.
 Lorsque l’USART est en mode maître, c’est lui qui fournit l’horloge sur la patte RC6/TX/CK à
une fréquence fixée par le contenu du registre SPBRG ; lorsqu’il est en mode esclave, il reçoit
l’horloge sur cette même patte RC6/TX/CK.

8 Convertisseur Analogique-Numérique : [4]


Ce module de conversion convertit un signal analogique présent sur l’une de ces 8 entrées à
son équivalent numérique sur 10-bits. Le CAN a deux tensions de référence : haute et basse, qui sont
choisis par programmation parmi VDD, VSS, RA2 ou RA3.De plus, il y a 4 registres qui lui sont associés:

 ADCON0 : qui est un registre de contrôle des opérations du CAN, il est disponible à l’adresse
1Fh.
 ADCON1 : qui est un registre de configuration du CAN, il est disponible à l’adresse 9Fh.
 ADRESL : registre de résultat de la conversion, il contient les bits du poids faible, disponible à
l’adresse 9Eh.

16
Chapitre 1 Etude théorique du PIC 16F877

 ADRESH : registre de résultat de la conversion, il contient les bits du poids fort, disponible à
l’adresse 1Eh.

Pour effectuer une conversion A/N, voici les étapes à suivre :

1. Configuration du module CAN :


 Configuration du port entrée pour le CAN et les tensions de référence (par le registre
ADCON1 bits 3 :0).
 Sélection du canal d’entrée analogique (par le registre ADCON0 bits 5 :3).
 Sélection de l’horloge de conversion (par le registre ADCON0 bits 7 :6).
 Mise en route du module CAN (par le registre ADCON0 bit 0).
2. Configuration de l’interruption (cette étape n’est pas obligatoire) :
 Mise à ‘0’ du bit ADIF (registre PIR1).
 Mise à ‘1’ du bit ADIE (registre PIE1).
 Mise à ‘1’ du bit PEIE (registre INTCON).
 Mise à ‘1’ du bit GIE (registre INTCON).
3. Attendre à ce que l’acquisition soit faite (temps d’acquisition).
4. Démarrer la conversion :
 Mettre à ‘1’ le bit GO/DONE (registre ADCON0).
5. Attendre à ce que la conversion soit terminée :
 Signalée par la mise à ‘0’ du bit GO/DONE, ou par une interruption.
6. Lire le résultat de la conversion. Le résultat est stocké dans les registres ADRESH : ADRESL, et
mettre à ‘0’ le bit ADIF si c’est nécessaire.
7. Pour effectuer une deuxième conversion, il faut attendre au moins 2 fois le temps de
conversion par bit.

 Remarque :

Du fait que le registre pair du résultat (ADRESH : ADRESL) est sur 16-bits, on a donc la possibilité de
justifier le résultat (qui est sur 10-bits) soit à gauche en mettant à ‘0’ le bit ADFM (registre ADCON1),
soit à droite en mettant le bit ADFM à ‘1’.

8.1 Choix de l’horloge de conversion :


C’est le temps de conversion par bit (TAD), il existe 4 possibilités pour effectuer ce choix, le
tableau suivant montre comment ce temps est choisi :

Tableau 1.9.1 : valeurs de TAD.

TAD ADCS1 :ADCS0 Fréquence max. du composant


(registre ADCON0)
2TOSC 00 1.25 MHz
8TOSC 01 5 MHz
32TOSC 10 20 MHz
RC interne du CAN 11 Inferieure à 1 MHz
Le fonctionnement du CAN continu durant un SLEEP à condition d’utiliser l’horloge RC interne.

17
Chapitre 1 Etude théorique du PIC 16F877

Figure 1.9 : Schéma du module de conversion analogique-numérique.

9 Modules CCP (Capture/Compare/PWM) : [4]


Le PIC 16F877 possède deux modules CCP qui fonctionnent de la même façon. Chaque module
contient un registre sur 16-bits qui peut fonctionner en un des modes suivants :

 Registre de capture.
 Registre de comparaison.
 Registre de la PWM.

Ce registre de 16-bits CCPR1 pour le module CCP1 (ou CCPR2 pour le module CCP2) est constitué de
deux registres de 8-bits chacun : CCPR1L (CCPR2L) qui contient l’octet bas et CCPR1H (CCPR2H) qui
contient l’octet haut.

 Registre CCP1CON/CCP2CON :( adresse : 17h/1Dh)

U-0 U-0 L/E-0 L/E-0 L/E-0 L/E-0 L/E-0 L/E-0


- - CCPxX CCPxY CCPxM3 CCPxM2 CCPxM1 CCPxM0
Bit7 Bit0

Bit 7 Non-implémenté : Lire comme ‘0’.


Bit 6 Non-implémenté : Lire comme ‘0’.
Bit 5:4 CCPxX:CCPxY : Bits de poids faible du PWM.
Mode capture et comparaison:
Inutilisés.
Mode PWM :
Ces bits sont les deux bits de poids faible du temps de cycle PWM. Les huit bits de poids
fort se trouvent dans CCPRxL.
Bit 3:0 CCPxM3:CCPxM0 : Bit de sélection du mode CCP.
0000 = module Capture/Compare/PWM désactivé (Reset le module CCPx).
0100 = Mode capture, à chaque front descendant.

18
Chapitre 1 Etude théorique du PIC 16F877

0101 = Mode capture, à chaque front montant.


0110 = Mode capture, à chaque 4ème front montant.
0111 = Mode capture, à chaque 16ème front montant.
1000 = Mode comparaison, mise à ‘1’ de la sortie lors d’une égalité (le bit CCPxIF (registre
PIRx) est mit à ‘1’).
1001 = Mode comparaison, mise à ‘0’ de la sortie lors d’une égalité (le bit CCPxIF est mis à
‘1’).
1010 = Mode comparaison, génère une interruption lors d’une égalité (le bit CCPxIF est mis
à ‘1’, la pin CCPx est non-affecté).
1011 = Mode comparaison, événement spécial trigger (le bit CCP1IF est positionné, la pin
CCPx est non-affecté) ; Le CCPx reset le TMR1, le CCP2 démarre le CAN (s’il est activé).
11xx = Mode PWM.

Vu que les deux modules sont identiques, on ne décrira qu’un seul : CCP1.

9.1 Mode capture :


Dans ce cas, le registre CCPR1 (CCPR1H :CCPR1L) capture le contenu du registre TMR1 (du
Timer1) quand l’un des événements suivants se produit sur la patte RC2/CCP1 :

 Tous les fronts descendants.


 Tous les fronts montants
 Tous les 4 fronts montants.
 Tous les 16 fronts montants.

Quand une capture est faite, il y aura génération d’une interruption signalée par le bit CCP1IF.

Le Timer1 étant associé au mode capture, il doit fonctionner en mode temporisateur ou compteur
synchronisé. La patte RC2/CCP1 doit être configurée en entrée.

9.2 Mode comparaison :


Dans ce mode, la valeur du registre CCPR1 est comparée à celle du registre TMR1. Quand une
égalité aura lieu, l’un des cas suivants se produira :

 Passage à ‘0’ de la patte RC2/CCP2.


 Passage à ‘1’ de la patte RC2/CCP2.
 Aucun changement sur cette patte.

En ce même temps, le bit CCP1IF se mit à ‘1’ pour signaler une interruption.

Même chose pour le Timer1, il doit être configuré en temporisateur ou en compteur synchronisé,
tandis que la patte RC2/CCP1 doit être configurée en sortie.

9.3 Mode PWM :


Dans ce mode le module CCP permet de générer une PWM (Pulse Width Modulation) avec une
résolution de 10-bits. La patte RC2/CCP1 doit être configurée en sortie.

19
Chapitre 1 Etude théorique du PIC 16F877

9.3.1 Période de la PWM :


La période de la PWM est spécifiée en écrivant une valeur dans le registre PR2 (registre
période du Timer2) et qui sera calculée en utilisant la formule suivante :

Période de la PWM = [(PR2) + 1] x 4 x TOSC x (la valeur du pré-diviseur du Timer2)

9.3.2 Rapport cyclique :


Le rapport cyclique est spécifié en écrivant une valeur dans le registre CCPR1L (sur 8-bits) qui
détermine les bits du poids fort et dans CCP1CON (bit 4 et 5) qui détermine les bits du poids faible
donc on a 10-bits. La formule suivante permet de déterminer ce rapport cyclique :

Rapport cyclique = (CCPR1L:CCP1CON<5:4>) x TOSC x (la valeur du pré-diviseur du Timer2)

Le registre CCPR1H est utilisé comme esclave du CCPR1L et ne peut être écrit par le
programmateur, il sert, avec les deux autres bits, à sauvegarder la valeur du rapport cyclique pour
ensuite générer une même période que la précédente, cette sauvegarde ne se produit que lorsque la
valeur du PR2 soit égale à celle du TMR2 (cette égalité signifie qu’une période est terminée).

Conclusion :
Cette étude théorique nous a permis de traiter et de comprendre le fonctionnement des
différentes ressources interne du PIC 16F877, d’envisager des applications pour ce µC et on va
présenter une de ces applications dans le chapitre qui suit.

20
Chapitre 2 Programmation en C et application

Introduction :
La programmation des microcontrôleurs PIC est supportée par plusieurs langages de
programmation tel que : MPLAB, l’Assembleur, le C ou C++. Dans ce chapitre on va présenter de
manière générale la procédure de programmation en C des microcontrôleurs PIC et donner quelques
exemples d’application.

1. Choix du compilateur : [5]


Il existe plusieurs compilateurs C pour PIC, et notre choix s’est porté sur l’outil développement
SourceBoost IDE qui permet de développer des programmes en C et de les compiler pour générer le
code Hexadécimal pour PIC en utilisant le compilateur BoostC, puisque le langage est le C et surtout
qu’on peut facilement accéder à n’importe quel bit de n’importe quel registre. Avec SourceBoost on
peut faire l’essentiel de ce qu’on peut faire avec l’assembleur ou d’autres langages moins évolués
mais avec moins d’instructions, mais aussi qu’il prend en charge la gestion d’un certain nombre de
mécanismes, par exemple : pas besoin de spécifier la page mémoire dans laquelle on veut écrire, le
compilateur s’en charge.

2. Quelques notions de programmation en C sous SourceBoost : [6]


La saisie d’un programme en ‘C’ répond pratiquement toujours à la même structure. On peut
noter que :
 Le symbole “#” est suivi d’une directive.
 Le symbole “//” est suivi d’un commentaire, ou bien “/*” indiquant le début d’un
commentaire et “*/” indiquant sa fin.
 Chaque ligne d’instruction se termine par un “;”.
 Le début d’une séquence est précédé du symbole “{”.
 La fin d’une séquence est suivie du symbole “}”.
 La notation des nombres peut se faire en décimal de façon normale ou en hexadécimal avec
le préfixe “0x” ou encore en binaire avec le préfixe“0b”.

2.1.Les directives :
 Directives de compilation :
#include <nomdufichier.h>

Cette directive indique au pré-compilateur d’inclure le fichier.h indiqué par son nom entre ‘< >’, ce
fichier est une bibliothèque contenant toutes les définitions qui seront utilisées par la suite dans le
programme. Si ce fichier est non disponible, une erreur sera générée et la compilation est stoppée.

#define iden (a,b,…) statement

Cette directive indique des équivalences. iden est le nom de l’équivalence déclarée dans
statement, avec (a,b,…) des variables utilisées dans cette équivalence.

#undef iden

21
Chapitre 2 Programmation en C et application

Cette directive permet de mettre fin à l’équivalence iden définie précédemment.

 Directives pragma :
#pragma CLOCK_FREQ fréquence en Hz

Cette directive indique au pré-compilateur la valeur de la fréquence (en Hz) utilisée par notre PIC.

#pragma DATA addr, d1, d2, …

Cette directive permet à l’utilisateur de se placer dans la mémoire à l’adresse désignée par addr et
de mettre les constantes d1, d2, … qui sont sur 8-bits.

#pragma DATA _bit du registre configuration word

Dans ce cas cette directive permet de configurer le µC à travers le registre configuration word, tel
que l’oscillateur, le WDT, LVP…

2.2.Les données :
En général, les données sous SourceBoost sont de type tel qu’il est indiqué dans le tableau suivant :

Types Taille
bit, bool 1-bit
char 8-bits
Int, unsigned int, signed int 16-bits
short, unsigned short, signed short 16-bits
long, unsigned long, signed long 32-bits
Tableau 2.3.2 : Type de données
Et en plus de ces données il y ales constantes et les variables :

 Constantes :

Les constats peuvent être exprimés en :

 Binaire : 0bXXXX, où X est : soit 1, soit 0.


 Octal : 0XXXX, où X est un nombre entre 0 et 7.
 Décimal : XXXX, où X est un nombre entre 0 et 9.
 Hexadécimal : 0xXXXX, où X est un nombre entre 0 et 9 ou A et F.

 Variables :

Les variables peuvent être déclarées et utilisées comme dans tout compilateur de langage C.

Les variables peuvent être forcées de se placer dans une certaine adresse. La syntaxe est la suivante :

char var@<addr>;

Où <addr> est une adresse en hexadécimal ou en décimal. Cette technique est utilisée pour
accéder à un registre spécifié depuis le programme.

22
Chapitre 2 Programmation en C et application

Les variables bit peuvent aussi avoir une adresse fixe. Cette adresse peut inclure la position du bit et
peut se faire suivant deux formes :

bit b; //la variable sera placée arbitrairement


bit b1@0x40.1; // bit 1 du registre dont l’adresse est 0x40
bit b2@0x202; // bit 2 du registre dont l’adresse est 0x40 (0x40*8 + 2)
En plus des variables bit, on peut accéder à un bit d’un registre spécifié en utilisant l’operateur ‘.’
Comme suit :

char var;
var.2 = 1; //mettre à ‘1’ le bit 2 de la variable ‘var’

Il existe un type de variable appelé volatile qui est utilisé pour déclarer des variables bit qui :

a) peuvent changer en dehors du programme, par exemple : l’assigner à une patte d’un port.
b) reçoivent des valeurs immédiates.

Exemple :

Volatile bit pinB1@0x6.1; //déclare le bit de patte 1 du portB à


//l’addresse 0x06 comme volatile, pinB1 est le nom donné à cette variable.

2.3 .Les opérateurs :


Plusieurs opérateurs sont disponibles sous SourceBoost pour effectuer différentes opérations :

 Opérateurs arithmétiques :

Ces opérateurs permettent d’effectuer les opérations arithmétiques et sont :

‘+’ : addition, ‘-‘ : soustraction, ‘*’: multiplication, ‘/’ : division, ‘%’ : donne le reste de la division de
deux opérandes, ‘++’ : incrémentation, ‘--’ : décrémentation.

 Exemples :

c=a+b ;//c=2+15 donne c=17 X=10 ;


c=b-a ;//c=15-2 donne c=13 c=x++ ; //post-incrémentation
c=a*b ;//c=2*15 donne c=30 //après l’opération :x=11, c=10
c=b/a ;//c=15/2 donne c=7 X=10 ;
c=b%a ;//c=15%2 donne c=1 c=++x ; //pré-incrémentation
//après l’opération :x=11, c=11
c=x-- ; //post-décrémentation
c=--x ; //pré-décrémentation

 Opérateurs d’affectation :

Ces opérateurs permettent d’affecter une valeur à une variable avec possibilité d’effectuer une
opération sur cette variable, ces opérateurs sont :

 ‘=’ : opérateur d’affectation, la valeur ou l’expression à droite de cet opérateur est affectée à
la variable qui est à gauche de cet opérateur.

23
Chapitre 2 Programmation en C et application

x=5 ;//quelque soit la valeur de x elle sera remplacée par 5

 ‘+=’ : opérateur addition et affectation, la variable à gauche de cet opérateur sera


additionnée avec celle d’à droite, puis le résultat sera affecté à la variable d’à gauche.

x+=2 ;//si x avait la valeur 14,après cette opération x vaudra 16

 ‘-=’ : opérateur soustraction et affectation, la variable à droite de cet opérateur sera


soustraie de celle d’à droite, puis le résultat sera affecté à la variable d’à gauche.

x-=2 ;//si x avait la valeur 14,après cette opération x vaudra 12

 ‘*=’ : opérateur multiplication et affectation, la variable à gauche de cet opérateur sera


multipliée par celle d’à droite, puis le résultat sera affecté à la variable d’à gauche.

x*=2 ;//si x avait la valeur 14,après cette opération x vaudra 28

 ‘/=’ : opérateur division et affectation, la variable à gauche de cet opérateur sera divisée par
celle d’à droite, puis le résultat sera affecté à la variable d’à gauche.

x/=2 ;//si x avait la valeur 14,après cette opération x vaudra 7

 ‘%=’ : opérateur reste de la division et affectation, le reste de la division de la variable qui est
à gauche de cet opérateur par celle qui est à droite sera affecté à la variable qui est à gauche.

x%=2 ;//si x avait la valeur 15,après cette opération x vaudra 1

 ‘&=’ : opérateur ET bit à bit et affectation. Cet opérateur effectue le ET logique (bit à bit)
entre la variable à sa gauche et celle à sa droite, ensuite il affecte le résultat à la variable à
gauche.

x &= 0b11110001 ;//si x avait la valeur 0b10001111,après cette opération x


//vaudra 0b10000001

 ‘|=’ : opérateur OU bit à bit et affectation. Cet opérateur effectue le OU logique (bit à bit)
entre la variable à sa gauche et celle à sa droite, ensuite il affecte le résultat à la variable à
gauche.

x |= 0b11110000 ;//si x avait la valeur 0b10001110,après cette opération x


//vaudra 0b11111110

 ‘^=’ : opérateur XOR et affectation. Cet opérateur effectue le XOR logique (bit à bit) entre la
variable à sa gauche et celle à sa droite, ensuite il affecte le résultat à la variable à gauche.

x ^= 0b11111000 ;//si x avait la valeur 0b00011110,après cette opération x


//vaudra 0b11100110

 ‘<<=’ : opérateur de décalage à gauche et affectation. Les bits de la variable à gauche vont
être décalés à gauche, le nombre de cases de décalage est indiqué par la variable à droite.

x <<= 0b00000010; // si x avait 0b00011110,après cette opération x vaudra


//0b01111000.

24
Chapitre 2 Programmation en C et application

 ‘>>=’: opérateur de décalage à droite et affectation. Les bits de la variable à gauche vont être
décalés à droite, le nombre de cases de décalage est indiqué par la variable à droite.

x >>= 0b00000010; // si x avait 0b00011110,après cette opération x vaudra


// 0b00000111.

 Opérateurs de comparaison :

Ces opérateurs sont utilisés pour la comparaison de deux opérandes.

== Egalité
!= Non égalité
<= Inférieur ou égale
< Inférieur
>= Supérieur ou égale
> Supérieur
 Opérateurs de condition :

Ces opérateurs permettent d’exécuter une partie du programme sous certaines conditions.

 ‘if / else’ : la syntaxe de cet opérateur est la suivante :

if (condition)

séquences d’instructions à exécuter si la condition est vérifiée

else

séquences d’instructions à exécuter si la condition n’est pas vérifiée

 ‘switch / case’ : la syntaxe est la suivante :

switch (expression)//selon l’état de cette expression

case a :

séquences d’instructions à exécuter dans ce cas

case b :

séquences d’instructions à exécuter dans ce cas

2.4 Les boucles :


 La boucle ‘for’ :

25
Chapitre 2 Programmation en C et application

Cette permet de contrôler le nombre de fois à exécuter un bloc d’instructions. Dans la syntaxe de
cette boucle on trouve : la valeur initiale du compteur, ça valeur finale et la valeur avec laquelle il
doit être incrémenté (ou décrémenté) chaque fois que le bloc d’instructions est exécuté.

Exemple :

for (i=0 ;i=10 ;i++)//i est le compteur

portd = portd++;

Supposons que le port d a 0 comme valeur initiale, donc en sortant de cette boucle le port d aura la
valeur 10 puisque il sera incrémenté en fonction de i, de 0 à 10.

 La boucle ‘while’ :

La boucle ‘while’ ou bien ‘tant que’ en français, permet l’exécution d’une suite d’instructions
plusieurs fois tant que une condition soit vraie. Si cette condition à un moment donné ne soit pas
vérifiée (fausse), l’exécution de cette boucle va être stoppée.

Exemple:

While (x>5)

portb = portb++;

--x ;

Supposons que x a une valeur initiale de 8 et le port b une valeur 0. Tant que la valeur de x est
supérieure à 5, le port b est incrémenté. Quand la valeur de x soit égale à 5 cette boucle ne sera plus
exécutée.

 La boucle ‘do / while’ :

Cette boucle permet l’exécution d’une suite d’instructions avant de vérifiée la condition, donc cette
boucle est exécutée au moins une fois même si la condition n’est pas vérifiée. Si la condition n’est
pas vérifiée l’exécution est stoppée, sinon elle continue.

Exemple:

do

portb = portb++;

--x ;

26
Chapitre 2 Programmation en C et application

} while (x>5) ;

Si la valeur initiale de x est inférieure à 5, le port b sera incrémenté une seule fois puis l’exécution de
la boucle est stoppée. Sinon il sera incrémenté jusqu'à ce que la valeur de x soit inférieure à 5.

2.5.Fonctions à usage général :

 clear_bit (var,num) : Cette fonction permet de mettre à zéro le bit ‘num’ de la variable ‘var’.
 set_bit (var,num) : Cette fonction permet de mettre à un le bit ‘num’ de la variable ‘var’.
 test_bit (var,num) : test si le bit ‘num’ de la variable ‘var’ est à un.
 MAKESHORT (dst,lobyte,hibyte) : cette fonction permet créer une valeur sur 16 bit qui sera
stockée dans ‘dst’ à partir de deux valeurs de 8 bit, ‘lobyte’ pour l’octet du poids faible et
‘hibyte’ pour l’octet du poids fort. Notons que ‘dst’ doit être une variable sur 16 bit.
 LOBYTE (dst,src) : permet d’avoir l’octet du poids faible à partir de ‘src’ et de le stocker dans
‘dst’.
 HIBYTE (dst,src) : permet d’avoir l’octet du poids fort à partir de ‘src’ et de le stocker dans
‘dst’.
 void nop (void) : c’est une fonction inline c-à-d que ça syntaxe dans le programme est la
suivante : nop(). Cette fonction permet de générer l’instruction ‘nop’ (no operation).
 void sleep (void) : c’est une fonction inline c-à-d que ça syntaxe dans le programme est la
suivante : sleep(). Cette fonction permet de générer l’instruction ‘sleep’ qui mettra en
veille le µC.
 void reset (void) : c’est une fonction inline c-à-d que ça syntaxe dans le programme est la
suivante : reset(). Cette fonction permet de générer un reset.

3. Structure d’un programme :


Un programme sous SourceBoost a la structure suivante :

 Le programme doit commencer par une directive de compilation qui indique au compilateur
quel sont les fichiers à inclure, ensuite il faut configurer le µC à travers le registre
configuration word, et après ça il faut indiquer au compilateur la fréquence du µC.
 La deuxième partie du programme consiste à définir les interruptions et le programme de
chacune.
 La dernière partie est la partie du programme principale, elle est subdivisée en deux parties :
dans la première partie le programmateur doit configurer et initialiser chaque port,
configurer les timers et d’autres ressources internes et aussi configurer les interruptions. La
deuxième partie est dédiée au programme qui va définir la tâche à effectuer par le µC.

4. Exemple d’application :
Après avoir vu comment programmer un µC PIC, nous allons présenter, dans cette partie, un
exemple d’application où le PIC est programmé en C sous SourceBoost.

27
Chapitre 2 Programmation en C et application

L’exemple que nous allons présenter est une application très simple à réaliser, c’est un compteur
qui peut aller de 0 à 99 (8 bits) avec un bouton de remise à zéro. Le circuit de cet exemple a été
réalisé et simulé sous le logiciel ISIS, la figure suivante illustre ce montage :

15pF

(1)

U1
13 33
OSC1/CLKIN RB0/INT
14 34
OSC2/CLKOUT RB1
1 35
MCLR/Vpp/THV RB2
36
RB3/PGM
15pF 2 37
RA0/AN0 RB4
3 38
4
RA1/AN1 RB5
39
R1
RA2/AN2/VREF- RB6/PGC
5 40
RA3/AN3/VREF+ RB7/PGD 6M8
6
RA4/T0CKI
7 15
RA5/AN4/SS RC0/T1OSO/T1CKI
16
RC1/T1OSI/CCP2
8 17
RE0/AN5/RD RC2/CCP1
9 18
RE1/AN6/WR RC3/SCK/SCL
10 23
RE2/AN7/CS RC4/SDI/SDA
24
RC5/SDO
25
RC6/TX/CK
D1 D2 RC7/RX/DT
26
comptage Mise à zéro
19
RD0/PSP0
20
RD1/PSP1
21
RD2/PSP2
22
RD3/PSP3
27
RD4/PSP4
28
RD5/PSP5
29
RD6/PSP6
30
RD7/PSP7
PIC16F877

Figure 2.5 : compteur 0 à 99 (8 bits)

Comme nous pouvons le voir, ce circuit est constitué d’un µC PIC 16F877, deux afficheurs 7 segments
avec circuits de décodage BCD intégrés l’un est connecté au port d et l’autre au port c, deux LED :
une rouge pour indiquer le comptage et une jaune pour indiquer la remise à zéro et un bouton
poussoir pour la remise à zéro. Un autre circuit connecté entre OSC1 et OSC2 qui est composé d’un
quartz de 4MHz en parallèle avec deux condensateurs de 15pF qui permet de fixer l’horloge à 4MHz.

Pour que ce circuit fonctionne il faut que le µC soit programmé correctement. Le programme qui
permet d’effectuer cette tâche est le suivant :

#include <system.h>

#include <pic16F877.h>

#pragma DATA _CONFIG, _XT_OSC & _WDT_OFF

#pragma CLOCK_FREQ 4000000

int i;//Déclaration d’un entier.

void main( void )

trisb = 0xFF;

trisc = 0x00;

trisd = 0x00; trise = 0x00;

28
Chapitre 2 Programmation en C et application
portc = 0x00;

portd = 0x00;

intcon = 0x90;

sleep();

for (i=0;i=99;i++)

clear_bit(porte,1);

set_bit(porte,0);

portd=portd++;

delay_ms(20);

if ((portd==9) && (portc!=9))

portd=0;

portc=portc++;

if ((portd==9) && (portc==9))

break;

portd=0;

portc=0;

void interrupt( void )

if(INTF==1)

portd=0;

portc=0;

29
Chapitre 2 Programmation en C et application
set_bit (porte,1);

clear_bit( intcon, INTF );

4.1.Analyse de la structure :
#include <system.h>

Cette directive indique au pré-compilateur d’inclure le fichier system.h. Celui-ci contient à son
tour un fichier contenant toutes les informations sur les différents PIC et de plus il permet d’inclure
des fonctions qui seront utilisées dans le programme.

#include <pic16F877.h>

Cette directive indique au pré-compilateur d’inclure le fichier pic16F877.h. Celui-ci contient des
informations sur le PIC 16F877 telles que les associations nom de registre/adresse mémoire.

#pragma DATA _CONFIG, _WDT_OFF & _XT_OSC

Une autre directive de pré-compilation, qui permet de définir les bits de configuration du PIC. Ces
bits de configuration permettent de configurer un certain nombre de paramètres de fonctionnement
du PIC:
• WDT_OFF: désactive le Watch Dog Timer.
• XT_OSC : Configure l’oscillateur en mode XT.
Pour l’instant on désactive tout (OFF), à part bien sûr l’oscillateur qu’on configure en mode « XT »
puisque l’oscillateur utilisé est en quartz à 4MHz.

#pragma CLOCK_FREQ 4000000

A nouveau une directive de pré-compilation. On indique ici quelle est la fréquence du quartz utilisé.
C’est à partir de cette valeur que les temporisations sont générées par la fonction « delay ».

void main( void )

La fonction main est obligatoire en langage C, elle indique le début du programme principal. C’est
dans cette zone entre accolades ‘{ }’ qu’on a:
 Configurer les différents ports utilisés dans cette application :
trisb = 0xFF; configurer toutes les pins du port b en entrées.

trisc = 0x00; configurer toutes les pins du port c en sorties.

trisd = 0x00; configurer toutes les pins du port d en sorties.

trise = 0x00; configurer toutes les pins du port e en sorties.

30
Chapitre 2 Programmation en C et application

 Initialiser les ports par des valeurs :

portc = 0x00;initialisation du port c par 0.

portd = 0x00; initialisation du port d par 0.

porte = 0x00; initialisation du port e par 0.

 Valider les interruptions :

intcon = 0x90; INTCON est un registre qui permet de contrôler les interruptions. L’équivalent de
90h en binaire est 10010000b, affecter cette valeur au registre INTCON permet de mettre à ‘1’ le 8 ème
bit qui correspond au bit de validation globale des interruptions et le 5ème bit qui correspond au bit
de validation de l’interruption sur changement de RB0, et de mettre à ‘0’ tous les autres bits pour
désactiver toute autre interruption.

 Ecrit la partie programme qui définit la tâche principale à effectuer par la µC :

Après que le µC exécute les étapes précédentes, il va exécuter la fonction ‘sleep’ qui va le mettre en
veille. L’intérêt de cette mise en veille dans notre exemple est de ne pas commencer le comptage
qu’après avoir reçu un changement d’état sur RB0 (en appuyant sur le bouton poussoir), donc il va
exécuter la routine d’interruption pour ensuite continuer l’exécution du programme.

Dès que le µC sort de la routine d’interruption, il retourne au programme principal pour exécuter la
boucle ‘for’.

Initialement, au début du programme, on déclarer un entier ‘i’ qui va servir de compteur pour la
boucle et qui va être incrémenté chaque fois que la boucle est exécutée de ‘0’ à ‘99’:

for (i=0;i=99;i++)

Entre les accolades de cette boucle, on trouve :

clear_bit(porte,1);qui va mettre à ‘0’ la pin RE1 pour éteindre la LED jaune qui est connectée à
cette pin, ce qui va signaler la fin de la mise à ‘0’ du compteur et début du comptage.

set_bit(porte,0);qui mettra à ‘1’ la pin RE0 où une LED rouge est connectée. Cette mise à ‘1’
allume la LED pour signaler le comptage et elle reste allumée tant qu’une remise à zéro ne s’est
produite.

Incrémentation de la valeur du port d par : portd=portd++; et génération d’un délai de 20ms


avant que la prochaine instruction ne soit exécutée : delay_ms(20);

Ensuite on rencontre un bloc d’instructions précédé par un operateur de condition (un test) :
if ((portd==9) && (portc!=9))

 Si la valeur du port d est égale à 9 et celle du port c est différente de 9, le bloc d’instructions
va être exécuté, dans ce bloc on va:
i. Mettre à ‘0’ le port d : portd=0;, cette remise à zéro est nécessaire puisque le port d ne
doit pas dépasser 9.

31
Chapitre 2 Programmation en C et application

ii. Incrémenter la valeur du port c : portc=portc++; ,puisque il n’a pas encore atteint la
valeur ‘9’. Cette incrémentation nous permet de passer, par exemple, des dizaines aux
vingtaines.

Après l’exécution de ce bloc, le µC passe directement à l’instruction qui suit.

 Sinon, c-à-d que les conditions ne sont pas vérifiées, le bloc ne va pas être exécuté et le µC
passe directement à l’instruction qui suit le bloc.

L’instruction suivante est un operateur de condition (de test) :


if ((portd==9) && (portc==9)) :

 Si ces conditions ne sont pas vérifiées, donc le compteur n’a pas encore atteint la valeur ‘99’
et il faut l’incrémenté, pour cela le µC va ignorer l’instruction qui suit ce test pour ensuite se
retrouver à la fin de la boucle ‘for’ ce qui lui permettra de reboucler tout en incrémentant le
‘i’ et de ré-exécuter cette boucle.
 Sinon, le µC trouve que les conditions son vérifiées (le compteur à atteint ‘99’), donc il va
exécuter l’instruction qui suit et c’est un ‘break’, cette instruction est utilisée généralement à
la fin d’une boucle ‘for’ et exécutée après vérification d’une certaine condition, l’exécution
de cette instruction permet au µC de sortir de la boucle. Dans ce cas notre condition est
vérifiée donc le µC sort de la boucle pour continuer l’exécution du reste du programme.

Le reste du programme consiste à remettre le compteur à ‘0’ puisque il a atteint ‘99’ :

portd=0; mise à ‘0’ du port d (bits de poids faible).

portc=0; mise à ‘0’ du port c (bits de poids fort).

Si, durant l’exécution du programme ou à la fin de l’exécution, le µC a reçu un changement d’état sur
RB0 (en appuyant sur le bouton poussoir), ceci va engendrer une interruption. Le sous programme
qui traite cette interruption ce mis entre les accolades de la fonction ‘interrupt’ comme suit :

void interrupt( void )

interrupt est la fonction qui traite les interruptions, Le void signifie que cette fonction ne
retourne rien. Dans ce sous programme on a :

 Affecter un ‘0’ au port d et au port c pour permettre au µC de mettre à zéro chaque pins de
ces ports, ce qui fait que le compteur sera mit à zéro.
 Mis à ‘1’ la patte RE1, où une LED jaune est connectée, par set_bit(porte,1);. Dès que
cette patte est mise à ‘1’, la LED s’allume indiquant la remise à zéro.
 clear_bit(intcon,INTF);permet de mettre à zéro le bit INTF du registre INTCON, ce bit
qui signale un changement sur RB0 et de déclenche une interruption en se mettant à ‘1’,
d’où la nécessité de le remettre à ‘0’ pour signaler la fin de cette interruption.

32
Chapitre 2 Programmation en C et application

Après que le µC sort de cette routine, il va continuer l’exécution du programme principal de la


fonction ‘main’.

Conclusion :
A travers les notions et l’application présentée dans ce chapitre, nous avons fait un pas dans la
programmation des PIC en C.

33
Conclusion Générale
L’élaboration de ce modeste travail nous a permis de comprendre un peu le fonctionnement
du microcontrôleur PIC 16F877 à travers une étude théorique de ces différentes ressources internes,
ensuite de s’initier à leur programmation en langage C, pour cela nous avons utilisé le compilateur
SourceBoost et comme nous l’avons vu il est d’une grande simplicité. Cela nous a permis aussi
d’élaborer une application pour mettre en œuvre toutes les notions théoriques.

A la fin nous espérons avoir apporté une contribution au domaine des microcontrôleurs PIC
et à leur programmation en langage C.

33
Bibliographie

 [1] : Les Microcontrôleurs PIC 16F87X, Philippe LETENNEUR - GRANVILLE –


2003.

 [2] : Programmation En C Sur Carte "EASYPIC 2" du Microcontrôleur PIC16F877,


Karim SAAD, Mémoire de fin d’étude -Licence LMD-, Université d’ORAN.
Promotion 2007/2008.

 [3] : Les Microcontrôleurs PIC : Description et mise en œuvre, Christian


TAVERNIER, Nouvelle présentation de la 2ème édition, DUNOD, 2002.

 [4]: PIC16F87X DATA SHEET, Microchip Technology Inc, 2001.

 [5]: Programmation des PIC en C-PARTIE 1, Noxyben, 2007.

 [6]: BoostC C Compiler for PICmicro Reference Manual, SourceBoost


Technologies.