41
République Algérienne Démocratique et Populaire Ministère de lEnseignement Supérieur et de la Recherche Scientifique Université Abderrahmane Mira Bejaia Faculté de la Technologie Département d’Electronique Thème Présenté par : Encadré par : M r. :BOUKARI Mansour M r. :HADJI Slimane Programmation en C du Microcontrôleur PIC 16F877 Master S1 2009/2010

Programmation en C du Microcontrôlleur PIC16F877

Embed Size (px)

Citation preview

Page 1: Programmation en C du Microcontrôlleur PIC16F877

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

Présenté par : Encadré par :

Mr. :BOUKARI Mansour M

r. :HADJI Slimane

Programmation en C

du Microcontrôleur

PIC 16F877

Master S1 2009/2010

Page 2: Programmation en C du Microcontrôlleur PIC16F877

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

Page 3: Programmation en C du Microcontrôlleur PIC16F877
Page 4: Programmation en C du Microcontrôlleur PIC16F877

Introduction Générale

1

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.

Page 5: Programmation en C du Microcontrôlleur PIC16F877
Page 6: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

2

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 :

Page 7: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

3

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

Page 8: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

4

1.3 Architecture interne : [4]

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.

Figure 1.2.3 : Architecture interne du PIC16F877.

Page 9: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

5

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).

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 :

Figure 1.3.1 : Organisation de mémoire programme

Page 10: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

6

Tableau 1.3 : Sélection des

BANKs.

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 :

Tableau 1.4 : Configuration de

l’oscillateur.

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 :

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 :

RP1 :RP0 BANK

00 0

01 1

10 2

11 3

FOSC1 :FOSC0 Mode

00 LP

01 XT

10 HS

11 RC

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

Page 11: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

7

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 :

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.

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

Figure 1.4.2 : Oscillateur RC.

Page 12: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

8

x : inconnu, u : inchangé, - : emplacements non implémentés (‘0’), les cellules ombragées ne sont pas

utilisées par le PORTA.

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

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

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

Adresse

Nom

Bit-7

Bit-6

Bit-5

Bit-4

Bit-3

Bit-2

Bit-1

Bit-0

Valeur sur POR, BOR

Valeur sur autres 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

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.

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.

Adresse

Nom

Bit-7

Bit-6

Bit-5

Bit-4

Bit-3

Bit-2

Bit-1

Bit-0

Valeur sur POR, BOR

Valeur sur autres RESET

06h, 106h

PORTB RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 xxxx xxxx uuuu uuuu

86h, 186h

TRISB Registre de direction des données PORTB 1111 1111 1111 1111

81h, 181h

OPTION_REG RBPU INTEDC T0CS T0SE PSA PS2 PS1 PS0 1111 1111 1111 1111

Page 13: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

9

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

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

Adresse

Nom

Bit-7

Bit-6

Bit-5

Bit-4

Bit-3

Bit-2

Bit-1

Bit-0

Valeur sur POR, BOR

Valeur sur 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

de données PORTE

0000 -111 0000 -111

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’.

Adresse

Nom

Bit-7

Bit-6

Bit-5

Bit-4

Bit-3

Bit-2

Bit-1

Bit-0

Valeur sur POR, BOR

Valeur sur autres 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

Page 14: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

10

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

Adresse

Nom

Bit-7

Bit-6

Bit-5

Bit-4

Bit-3

Bit-2

Bit-1

Bit-0

Valeur sur POR, BOR

Valeur sur autres RESET

09h PORTE - - - - - RE2 RE1 RE0 ---- -xxx ---- -uuu

89h TRISE IBF OBF IBOV PSPMODE - Registre de direction de données PORTE

0000 -111 0000 -111

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.

Page 15: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

11

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.

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 :

Figure1.6.1 : Schéma interne du Timer0

Page 16: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

12

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.

Page 17: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

13

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.

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.

Figure1.6.2 : Schéma interne du Timer1

Page 18: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

14

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

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.

Figure1.6.3 : Schéma interne du Timer2

Page 19: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

15

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.

Page 20: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

16

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.

Page 21: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

17

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 (registre ADCON0)

Fréquence max. du composant

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.

Page 22: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

18

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.

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

Page 23: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

19

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.

Page 24: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 1 Etude théorique du PIC 16F877

20

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.

Page 25: Programmation en C du Microcontrôlleur PIC16F877
Page 26: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

21

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

Page 27: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

22

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

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.

Tableau 2.3.2 : Type de données

Page 28: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

23

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 [email protected]; // 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 [email protected]; //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

c=b-a ;//c=15-2 donne c=13

c=a*b ;//c=2*15 donne c=30

c=b/a ;//c=15/2 donne c=7

c=b%a ;//c=15%2 donne c=1

X=10 ;

c=x++ ; //post-incrémentation

//après l’opération :x=11, c=10

X=10 ;

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.

Page 29: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

24

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.

Page 30: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

25

‘>>=’: 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’ :

Page 31: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

26

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 ;

Page 32: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

27

} 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.

Page 33: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

28

#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;

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 :

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 :

RA0/AN02

RA1/AN13

RA2/AN2/VREF-4

RA4/T0CKI6

RA5/AN4/SS7

RE0/AN5/RD8

RE1/AN6/WR9

RE2/AN7/CS10

OSC1/CLKIN13

OSC2/CLKOUT14

RC1/T1OSI/CCP216

RC2/CCP117

RC3/SCK/SCL18

RD0/PSP019

RD1/PSP120

RB7/PGD40

RB6/PGC39

RB538

RB437

RB3/PGM36

RB235

RB134

RB0/INT33

RD7/PSP730

RD6/PSP629

RD5/PSP528

RD4/PSP427

RD3/PSP322

RD2/PSP221

RC7/RX/DT26

RC6/TX/CK25

RC5/SDO24

RC4/SDI/SDA23

RA3/AN3/VREF+5

RC0/T1OSO/T1CKI15

MCLR/Vpp/THV1

U1

PIC16F877

(1)

D1comptage

D2Mise à zéro

R1

6M8

15pF

15pF

Figure 2.5 : compteur 0 à 99 (8 bits)

Page 34: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

29

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;

Page 35: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

30

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.

set_bit (porte,1);

clear_bit( intcon, INTF );

}

}

Page 36: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

31

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.

Page 37: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

32

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.

Page 38: Programmation en C du Microcontrôlleur PIC16F877

Chapitre 2 Programmation en C et application

33

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.

Page 39: Programmation en C du Microcontrôlleur PIC16F877
Page 40: Programmation en C du Microcontrôlleur PIC16F877

Conclusion Générale

33

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.

Page 41: Programmation en C du Microcontrôlleur PIC16F877

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.