Download 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
Programmation en C du Microcontrôleur PIC 16F877
Présenté par :
Encadré par :
Mr. :BOUKARI Mansour
Master S1 2009/2010
Mr. :HADJI Slimane
Sommaire Introduction Générale…………………………………………………………………………………………...1 Chapitre 1 : Etude théorique du PIC 16F877 Introduction…………………………………………………………………………………………………….2 1. 2. 3. 4. 5. 6. 7.
Présentation du microcontrôleur PIC 16F877…………………………………………………...2 Différents types de mémoire…………………………………………………………………………….5 Configuration de l’oscillateur (horloge) ……………………………………………………………6 Ports d’Entrées/Sorties……………………………………………………………………………………7 Timers…………………………………………………………………………………………………………..11 Interface MSSP: (Master Synchronous Serial Port)……….………………………………….14 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. 2. 3. 4.
Choix du compilateur…………………………………………………………………………………….21 Quelques notions de programmation en C sous SourceBoost…………………………..21 Structure d’un programme…………………………………………………………………………….27 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 00 01 10 11
Tableau 1.3 : Sélection des BANKs.
BANK 0 1 2 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 00 01 10 11
Mode LP XT HS RC
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 :
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 Adresse Nom Bit-7 Bit- Bit- Bit- Bit-3 Bit-2 Bit-1 Bit-0 sur 6 5 4 POR, BOR --0x 0000 05h PORTA RA5 RA4 RA3 RA2 RA1 RA0 --11 1111 85h TRISA Registre de direction des données PORTA 9Fh ADCON1 ADFM PCFG3 PCFG2 PCFG1 PCFG0 --0- 0000
Valeur sur autres RESET --0u 0000 --11 1111 --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
Adresse Nom
06h, 106h 86h, 186h 81h, 181h
PORTB
Bit-7
RB7
TRISB OPTION_REG RBPU
Bit-6
RB6
Bit-5 Bit-4
Bit-3
Bit-2
Bit-1
RB5
RB3
RB2
RB1
RB4
Valeur Bit- sur 0 POR, BOR RB0 xxxx xxxx
Registre de direction des données PORTB INTEDC T0CS
T0SE
PSA
PS2
PS1
PS0
Valeur sur autres RESET uuuu uuuu
1111 1111
1111 1111
1111 1111
1111 1111
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
Adresse Nom
Bit-7
07h PORTC RC7 87h TRISC x : inconnu, u : inchangé.
Bit6
Bit5
Bit4
Bit-3
Bit-2
Bit-1
RC6 RC5 RC4 RC3 RC2 RC1 Registre de direction de données PORTC
Bit-0
RC0
Valeur sur POR, BOR xxxx xxxx 1111 1111
Valeur sur autres RESET uuuu uuuu 1111 1111
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
Bit6
Bit-5
Bit-4
Bit-3
Bit-2
Bit-1
Bit-0
Valeur sur POR, BOR
Valeur sur autres RESET uuuu uuuu 1111 1111 0000 -111
RD6 RD5 RD4 RD3 RD2 RD1 RD0 xxxx xxxx 1111 1111 Registre de direction de données PORTD IBF OBF IBOV PSPMODE Registre de direction 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. 08h 88h 89h
PORTD TRISD TRISE
RD7
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
Adresse Nom
09h 89h
PORTE TRISE
Bit-7
IBF
Bit6
Bit-5
Bit-4
Bit-3
Bit-2
Bit-1
OBF IBOV PSPMODE -
Bit-0
Valeur sur POR, BOR ---- -xxx 0000 -111
Valeur sur autres RESET ---- -uuu 0000 -111
RE2 RE1 RE0 Registre de direction de 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 Bit7
U-0 -
L/E-0 L/E-0 L/E-0 L/E-0 T1CKPS1 T1CKPS0 T1OSCEN T1SYNC
L/E-0 TMR1CS
L/E-0 TMR1ON 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
Bit 1
Bit 0
Etude théorique du PIC 16F877
Quand TMR1CS = 0 : Ce bit est ignoré. Le Timer1 utilise l’horloge interne quand TMR1CS = 0. 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). 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 Bit7
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 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 Bit7
U-0 -
L/E-0 CCPxX
L/E-0 CCPxY
L/E-0 CCPxM3
L/E-0 CCPxM2
L/E-0 CCPxM1
L/E-0 CCPxM0 Bit0
Bit 7 Bit 6 Bit 5:4
Non-implémenté : Lire comme ‘0’. Non-implémenté : Lire comme ‘0’. 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) 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
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 bit, bool char Int, unsigned int, signed int short, unsigned short, signed short long, unsigned long, signed long
Taille 1-bit 8-bits 16-bits 16-bits 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@;
Où 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
[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. c=a+b c=b-a c=a*b c=b/a c=b%a
Exemples : ;//c=2+15 ;//c=15-2 ;//c=2*15 ;//c=15/2 ;//c=15%2
donne donne donne donne donne
c=17 c=13 c=30 c=7 c=1
X=10 ; c=x++ ; //après X=10 ; c=++x ; //après c=x-- ; c=--x ;
//post-incrémentation l’opération :x=11, c=10 //pré-incrémentation l’opération :x=11, c=11 //post-décrémentation //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
‘= 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 14 1
OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV
2 3 4 5 6 7
15pF
RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RE0/AN5/RD RC2/CCP1 RE1/AN6/WR RC3/SCK/SCL RE2/AN7/CS RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
8 9 10
D1
D2
comptage
Mise à zéro
RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD
RD0/PSP0 RD1/PSP1 RD2/PSP2 RD3/PSP3 RD4/PSP4 RD5/PSP5 RD6/PSP6 RD7/PSP7
33 34 35 36 37 38 39 40
R1 6M8
15 16 17 18 23 24 25 26 19 20 21 22 27 28 29 30
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 #include #pragma DATA _CONFIG, #pragma CLOCK_FREQ
_XT_OSC & _WDT_OFF 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
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
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 ii.
Programmation en C et application
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.