Vous êtes sur la page 1sur 80

Microcontrôleur PIC16F887

A.OUMNAD

1

LES MICROCONTROLEURS Par la pratique

Etude détaillée du

PIC® 16F887

Abdelmajid OUMNAD

Microcontrôleur PIC16F887

A.OUMNAD

2

INTRODUCTION

Un microcontrôleur est un composant électronique Autonome doté :  d’une unité de traitement capable de décoder et d'exécuter des instructions,  de la mémoire RAM,  de la mémoire permanente,  des interfaces d’E/S parallèle et série (RS232, I2C, SPI …)  des interfaces d’E/S analogique  Des Timer pour gérer le temps  D’autres modules plus au moins sophistiqués selon la taille du microcontrôleur Un microcontrôleur est généralement moins puissant qu’un microprocesseur en terme de rapidité ou de taille mémoire, il se contente le plus souvent d’un bus 8 ou 16 bits. Ceci en fait un composant très bon marché parfaitement Adapté pour piloter les applications embarquées dans de nombreux domaines d’application. Je pense qu’on ne se tromperait pas beaucoup si on affirme qu’aujourd’hui il y’a un microcontrôleur ( grand) dans chaque équipement électronique :  Informatique (souris, modem …)  Vidéo (Appareil photos numérique, caméra numérique …)  Contrôle des processus industriels (régulation, pilotage)  Appareil de mesure (affichage, calcul statistique, mémorisation)  Automobile (ABS, injection, GPS, airbag)  Multimédia (téléviseur, carte audio, carte vidéo, MP 3, magnétoscope)  Téléphones (fax, portable, modem)
 Electroménager (lave-vaisselle, lave-linge, four micro-onde)

Un microcontrôleur peut être programmé une fois pour toutes pour effectuer une ou des tâches précises au sein d'un appareil électronique. Les microcontrôleurs récents peuvent être reprogrammés et ceci grâce à leur mémoire permanente de type FLASH (d’où le terme flasher un équipement) Plusieurs Constructeurs se partagent le marché des microcontrôleurs, citons INTEL, MOTOROLA, ATMEL, ZILOG, PHILIPS et MICROCHIP® avec ses PIC® très populaires auxquels nous allons nous intéresser dans cet ouvrage.

Microcontrôleur PIC16F887

A.OUMNAD

3

Les microcontrôleurs, quelque soit leurs constructeurs, ont des architecture très similaires et sont constitués de modules fondamentaux assurant les mêmes fonctions : UAL, Ports d’E/S, interfaces de communications série, Interfaces d’E/S analogiques, Timers et horloge temps réels …On peut dire que seul le langage de programmation (Assembleurs) constitue la différence majeure en deux microcontrôleur (similaires) venant de deux constructeurs différents. Nous avons choisit dans ce document d'étudier les microcontrôleurs PIC® mid-range fabriqués par Microchip®. Ce sont des microcontrôleurs à architecture RISC (Reduce Instructions Set Computer), ou encore composant { jeu d’instructions réduit. L'avantage est que plus on réduit le nombre d’instructions, plus leur décodage sera rapide ce qui augmente la vitesse de fonctionnement du microcontrôleur. La famille des PIC® est subdivisée en 3 grandes familles :  La famille Base-Line, qui utilise des mots d’instructions de 12 bits, elle constitue l'entrée de gamme des microcontrôleurs fabriqués par Microchip®  la famille Mid-Range, qui utilise des mots de 14 bits. C'est la famille des microcontrôleurs moyenne puissance  la famille High-End, qui utilise des mots de 16 bits. C'est la famille haut de gamme. Au lieu de nous lancer dans l'étude générale sur les microcontrôleurs, qui de notre avis, apporte peu d'aide aux lecteurs ciblés par cet ouvrage, nous avons opté pour une étude détaillée du microcontrôleur 16F887 qui est le remplaçant désigné du très populaire 16F877. C'est un élément très représentatif de la famille mid-range puisqu'il est doté de la plupart des modules qui équipent les circuits de cette famille. Cet ouvrage est organisé d'une façon telle que le lecteur peur passer rapidement à la pratique. Tous les aspects nécessaires à l'écriture, la compilation et l'implantation d'un programme sur le PIC® sont regroupé dans les cinq premiers chapitres, volontairement courts pour éviter au lecteur de s'égarer. Ensuite l'ouvrage peut servir comme document de référence, le lecteur n'est pas obligé d'étudier le reste des chapitres dans l'ordre présenté.

Microcontrôleur PIC16F887

A.OUMNAD

4

Table des matières
INTRODUCTION ................................................................................................................................................... 2 Chapitre I ............................................................................................................................................................... 7 LES ELEMENTS DE BASE DU PIC16F887 ........................................................................................................ 7 I.1 I.2 Eléments essentiels du PIC 16F887 ................................................................................................................... 7 Brochage du 16F887............................................................................................................................................... 8

I.3 L'Horloge.................................................................................................................................................................... 8 I.3.1 Oscillateur à quartz ...................................................................................................................................... 9 I.3.2 Oscillateur RC. ..............................................................................................................................................10 I.3.3 Horloge externe. ..........................................................................................................................................10 I.3.4 Oscillateur interne. .....................................................................................................................................10 I.4 Les Registres de configuration CONFIG1 et CONFIG2 ...............................................................................11 I.4.1 Exemple de Configuration générique ...................................................................................................14 I.5 L'unité de traitement centrale (CPU) .............................................................................................................14 I.6 Organisation de la mémoire RAM ....................................................................................................................15 I.6.1 Accès à la RAM par adressage DIRECT .................................................................................................15 I.7 I.8 Accès à la RAM par l’adressage INDIRECT ....................................................................................................17 Quelques registres de configuration et leurs bits ......................................................................................19

Chapitre II............................................................................................................................................................ 20 LE JEUX D'INSTRUCTIONS DU PIC16F887 ................................................................................................... 20 II.1 Les instructions orientées Registre ...............................................................................................................20 II.2 Les instructions orientées bits .........................................................................................................................20 II.3 Les instructions opérant sur une valeur .......................................................................................................21 II.4 Les instructions de saut et appel de procédures ........................................................................................21 II.5 Le jeu d'instructions.............................................................................................................................................21 II.5.1 Les instructions movwf et movf ..............................................................................................................22 II.5.2 Les instructions btfss et btfsc .................................................................................................................22 II.5.3 Les instructions incfsz et decfsz .............................................................................................................22 II.5.4 L’instruction goto ........................................................................................................................................23 II.5.5 L’instruction call..........................................................................................................................................23 II.6 Les indicateur d’état (drapeaux) .....................................................................................................................24 II.6.1 Les indicateurs, la soustraction et la comparaison..........................................................................24 II.7 Les directives de l'assembleur MPASM ..........................................................................................................24 II.7.1 La directive LIST ..........................................................................................................................................25 II.7.2 La directive INCLUDE.................................................................................................................................25 II.7.3 La directive EQU ..........................................................................................................................................25 II.7.4 Les directives CBLOCK/ENDC .................................................................................................................25 II.7.5 La directive ORG ..........................................................................................................................................25 II.7.6 La directive #DEFINE ................................................................................................................................26 II.7.7 Les directives LOW et HIGH .....................................................................................................................26 II.7.8 La directive DE .............................................................................................................................................26 II.7.9 La directive DT .............................................................................................................................................27 II.7.10 La directive END :........................................................................................................................................27 II.7.11 La directive __CONFIG ................................................................................................................................27 II.8 Les opérateurs arithmétique et logique de l'assembleur ........................................................................27 II.9 Les macros...............................................................................................................................................................28

Microcontrôleur PIC16F887

A.OUMNAD

5

Chapitre III .......................................................................................................................................................... 29 LES OUTILS DE DEVELOPPEMENT ................................................................................................................ 29 III.1 Procédure de travail.............................................................................................................................................29 III.1.1 Programmeur simple .................................................................................................................................29 III.1.2 PIC® en mode exécution .........................................................................................................................30 III.2 L’environnement de développement MPLAB® ..........................................................................................30 III.3 Programme type : adressage direct ................................................................................................................32 III.3.1 Des macros pour sélectionner les banks .............................................................................................34 III.4 Boucles de temporisation...................................................................................................................................35 III.4.1 Temporisation avec une boucle .............................................................................................................35 III.4.2 Temporisation avec 2 boucles imbriquées.........................................................................................36 III.4.1 Temporisation avec 3 boucles imbriquées.........................................................................................36 Chapitre IV .......................................................................................................................................................... 38 LES PORTS d’ENTRÉE SORTIES ...................................................................................................................... 38 IV.1 Le port d' E/S PORTA ...........................................................................................................................................38 IV.2 Le port d'E/S PORTB ............................................................................................................................................39 IV.3 Le port d' E/S PORTC............................................................................................................................................39 IV.4 Le port d' E/S PORTD ...........................................................................................................................................39 IV.5 Le port d'E/S PORTE ............................................................................................................................................40 IV.6 Situation au démarrage.......................................................................................................................................40 IV.7 Programmes types ................................................................................................................................................40 IV.7.1 Faire clignoter une LED.............................................................................................................................40 IV.7.2 Commande d'un relai .................................................................................................................................42 IV.8 Commande d'un afficheur sept segments .....................................................................................................44 IV.9 Commande d'un afficheur LCD .........................................................................................................................46 IV.9.1 Initialisation de l'afficheur en mode 8 bits .........................................................................................47 IV.9.2 Initialisation de l'afficheur en mode 4 bits .........................................................................................47 IV.9.3 Exemple de branchement.........................................................................................................................49 Chapitre V ............................................................................................................................................................ 50 LES MÉMOIRES PERMANENTES ..................................................................................................................... 50 V.1 La mémoire EEPROM de données ....................................................................................................................50 V.2 Procédure de lecture dans la EEPROM...........................................................................................................51 V.3 Procédure d'écriture dans la EEPROM ...........................................................................................................51 V.4 La mémoire EEPROM Programme ou mémoire flash ...............................................................................52 V.5 Procédure de lecture dans la mémoire programme .................................................................................52 V.6 Procédure d'écriture dan la mémoire programme....................................................................................53 V.7 Mécanisme d'écriture dan la mémoire programme ..................................................................................53 Chapitre VI .......................................................................................................................................................... 55 LES INTERRUPTIONS ........................................................................................................................................ 55 VI.1 Déroulement d'une interruption .....................................................................................................................55 VI.2 Les sources d'interruption .................................................................................................................................56 VI.3 L'interruption INT (Entrée RB0 de PORTB) .................................................................................................56

Microcontrôleur PIC16F887

A.OUMNAD

6

VI.4 L'interruption IOCB ..............................................................................................................................................56 VI.5 Les autres interruptions .....................................................................................................................................57 Chapitre VII ......................................................................................................................................................... 58 LES TIMERS ......................................................................................................................................................... 58 VII.1 Le Timer TMR0.......................................................................................................................................................58 VII.1.1 Programmes types: Clignoter LED, scrutation du drapeau T0IF ................................................59 VII.1.2 Programme type: Clignoter LED, interruption de TMR0 ...............................................................60 VII.2 Le Timer TMR2.......................................................................................................................................................61 VII.2.1 Cycle de comptage ......................................................................................................................................61 VII.2.2 Le registre T2CON: ......................................................................................................................................62 VII.2.3 Programme type : Clignoter une LED, Interruption de TMR2......................................................62 VII.2.4 Programme type : Signal asymétrique.................................................................................................64 Chapitre VIII ....................................................................................................................................................... 65 LE MODULE DE CONVERSION ANALOGIQUE NUMÉRIQUE...................................................................... 65 VIII.1 VIII.2 VIII.3 VIII.4 VIII.5 VIII.6 VIII.7 Les registres ADCON0 et ADCON1..........................................................................................................66 Déroulement d’une Conversion .............................................................................................................67 Temps de conversion .................................................................................................................................67 Temps d'acquisition ...................................................................................................................................68 Fréquence d'échantillonnage ..................................................................................................................68 Valeur numérique obtenue ......................................................................................................................69 Programmation en bref.............................................................................................................................69

VIII.8 Programmes types ......................................................................................................................................69 VIII.8.1 Prendre une seule mesure .......................................................................................................................69 VIII.8.2 Relever 40 échantillons ............................................................................................................................70 VIII.8.3 Relever 40 échantillons, fe=8000 Hz ....................................................................................................71 Chapitre IX .......................................................................................................................................................... 73 L'USART................................................................................................................................................................ 73 IX.1 Mode Asynchrone .................................................................................................................................................73 IX.1.1 Mode 8 bits ....................................................................................................................................................73 IX.1.2 Mode 9 bits ....................................................................................................................................................74 IX.2 Le port en transmission ......................................................................................................................................74 IX.2.1 Le registre de contrôle TXSTA ................................................................................................................74 IX.3 Le port en réception .............................................................................................................................................75 IX.3.1 Lecture du 9ème bit ......................................................................................................................................76 IX.3.2 Le registre de contrôle RCSTA ................................................................................................................76 IX.3.3 Mode détection d'adresse ........................................................................................................................77 IX.4 La vitesse de communication ............................................................................................................................78 IX.4.1 Le registre BAUDCTL..................................................................................................................................79 IX.5 La transmission en bref (sans interruption)................................................................................................79 IX.6 La réception en bref (sans interruption) ......................................................................................................80 IX.7 Registres utilisés par l'USART ...........................................................................................................................80

Microcontrôleur PIC16F887

A.OUMNAD

7

Chapitre I LES ELEMENTS DE BASE DU PIC16F887
I.1 Eléments essentiels du PIC 16F887
Parmi les éléments essentiels du PIC16F887, on peut citer:  Mémoire programme de type EEPROM flash de 8K mots de 14 bits,  Mémoire EEPROM de 256 octets,  RAM donnée de 368 octets,  5 ports d'entrée sortie (8bits), PORTA, PORTB, PORTC, PORTD, PORTE(4 bits),  Convertisseur Analogiques numériques 10 bits à 14 canaux,  USART, Port série universel, mode asynchrone (RS232) et mode synchrone,  MSSP, Port série synchrone supportant I2C,  Trois TIMERS TMR0, TMR1 et TMR2,  Deux modules de comparaison et Capture CCP1 et CCP2,  Un chien de garde,  13 sources d'interruption,  Générateur d'horloge, { quartz (jusqu’ { 20 MHz) ou à Oscillateur RC,  Protection de code,  Fonctionnement en mode sleep pour réduction de la consommation,  Programmation in-situ ICSP (In Circuit Serial Programming) 12V ou 5V,  Possibilité aux applications utilisateur d’accéder { la mémoire programme,  Tension de fonctionnement de 2 à 5V,  Jeux de 35 instructions

Microcontrôleur PIC16F887

A.OUMNAD

8

PORTE

PORTD

PORTC

PORTB 96 registres système SFR 368 registres utilisateur GPR W ALU

PORTA

14 bits : config

DAC 10 bits
Chien de garde

timer 0 TMR0 timer 2 TMR2 timer 1 TMR1
Capture/Comparaison

Mémoire programme de type Flash Unité De contrôle 8 x 1024 mots de 14 bits

WDT

MSSP (I2C/SPI) USART (RS232)

CCP1 CCP2

Capture/Comparaison

Horloge système

256 octets

EEPROM

Fig. I.1 : Les éléments constitutifs du PIC 16F887

I.2

Brochage du 16F887

I-1 : brochage du 16F887 (source : document Microchip DS41291F)

I.3

L'Horloge

Microcontrôleur PIC16F887

A.OUMNAD

9

Figure I-2 : possibilités d’horloge sur un PIC 16F887 (source : document Microchip® DS41291F)

Le PIC16F887 dispose d’un générateur interne qui délivre une horloge de fréquence Fosc. Cette horloge est utilisée par pratiquement tous les modules. L'horloge utilisée par l'unité de traitement pour cadencer l'exécution du programme est obtenu par division par quatre. On l'appelle horloge instruction car le PIC® exécute une instruction par période de cette horloge. Sa période sera appelée Tcy en référence au cycle machine. Le générateur d'horloge est constitué de deux oscillateurs. Un oscillateur externe et un double oscillateur interne. Le premier oscillateur est dit externe car le quartz ou le réseau RC permettant de fixer la fréquence sont externes. Le choix de l'oscillateur est de la fréquence Fosc se fait à l'aide de deux registres: o Le registre de configuration permanent CONFIG1 de type EEPROM qui est flaché au moment de l'implantation du programme sur le PIC®, o Le registre OSCCON qui est situé dans la RAM et qui peut être changé à tout moment lors de l'exécution du programme.

I.3.1

Oscillateur à quartz

Figure I-3 : Oscillateur à quartz

La fréquence Fosc peut aller jusqu’{ 20 MHz. Le quartz (externe) doit être relié aux entrées OSC1 et OSC2. Le réseau de filtrage Rs, C1 et C2 n'est pas obligatoire pour les basses fréquences. Le registre CONFIG1 doit être configuré par la directive __CONFIG dans l’un des modes suivants :

Microcontrôleur PIC16F887

A.OUMNAD

10

o LP : FOSC<2:1:0>= 000. Pour les quartz de fréquence inférieure à 200 kHz. Ce mode est bien adapté pour le quartz d'horlogerie 32.768 kHz qui permet d'obtenir une horloge d'une seconde par division de fréquence. o XT : FOSC<2:1:0>= 001. Pour les quartz de fréquence inférieure à 8 MHz o HS : FOSC<2:1:0>= 010 : Pour les quartz de 8 MHz à 20 MHz. Dans ce cas, il est conseillé d’utiliser C1 et C2 avec des valeurs de 10pF à 30pF . o

I.3.2

Oscillateur RC.

Figure I-4 : oscillateur RC

La fréquence de l'oscillation est fixée par Vdd, Rext et Cext. Elle peut varier légèrement d'un circuit à l'autre. Le registre CONFIG1 doit être configuré dans l’un des modes suivants : o RC : FOSC<2:1:0>= 111. Le réseau RC est connecté sur la broche OSC1. L'horloge instruction Fosc/4 est accessible sur la broche OSC2. L’horloge système de fréquence Fosc/ 4 est disponible sur la sortie OSC2. On peut ainsi mesurer sa fréquence et ajuster les valeurs de Rext et Cext. o RCIO : FOSC<2:1:0>= 110. Dans ce cas, l'horloge fosc/4 n'est pas accessible. La broche OSC2 fonctionne comme E/S normale RA6 accessible par le bit 6 du port PORTA o

I.3.3

Horloge externe.

Figure I-5: Horloge externe

L’horloge externe est appliquée sur l’entrée OSC1. La broche OSC2 fonctionne en E/S normale RA6. Le registre CONFIG1 doit être configuré dans le mode EC : FOSC<2:1:0>= 011

I.3.4

Oscillateur interne.

Dans ce mode, on n’a pas besoin de composant externes. L’horloge est issue de l’un des deux oscillateurs internes HFINTOSC et LFINTOSC.  Le registre CONFIG1 doit être configuré dans l’un des deux modes :

Microcontrôleur PIC16F887

A.OUMNAD

11

 INTOSC : FOSC :<2:1:0>= 101: l'horloge Fosc/4 est disponible sur la broche OSC2 qui fonctionne en CLKOUT alors que la broche OSC1 fonctionne en E/S normale RA7  INTOSCIO : FOSC<2:1:0>= 100: Les deux broches OSC1 et OSC2 fonctionnent en E/S normales  Il faut configurer le registre OSCCON (bank1) pour choisir la fréquence désirée entre 31kHz et 8MHz 

I.3.4.1
OSCCON

Le registre OSCCON
U(0) R/W(1) R/W(1) R/W(0) R(1) R(0) R(0) R/W(1)

-

IRCF2 IRCF1 IRCF0 OSTS HTS LTS

SCS

IRCF<2:0>: sélection de fréquence 111  8 MHz 110  4 MHz (default) 101  2 MHz 100  1 MHz 011  500 kHz 010  250 kHz 001  125 kHz 000  31 kHz (LFINTOSC) OSTS: indicateur sur l'état de l'horloge en mode Internal External Switchover (voir registre CONFIG1) 1  le système fonctionne avec l'horloge définie par les bits FOSC<2:0> du registre CONFIG1 0  le système fonctionne avec l'horloge interne (HFINTOSC ou LFINTOSC) HTS: Indicateur sur l'état de l'oscillateur interne HFINTOSC (après le démarrage) 1  HFINTOSC s'est stabilisé 0  HFINTOSC ne s'est pas encore stabilisé LTS: Indicateur sur l'état de l'oscillateur interne LFINTOSC (après le démarrage) 1  LFINTOSC s'est stabilisé 0  LFINTOSC ne s'est pas encore stabilisé SCS: Choix de l'horloge système (ce bit est important) 1  Le système utilise l'horloge issue des oscillateurs interne 0  Le système utilise l'horloge issue de l'oscillateurs externe ( RC, XT , HS …)

I.4

Les Registres de configuration CONFIG1 et CONFIG2

Pour le PIC16F887, les switchs de configuration sont regroupés dans deux registres CONFIG1 et CONFIG2 situés dans la EEPROM de configuration aux positions 2007h et2008h. Attention, ces registres ne sont pas des SFR que l’on peut modifier durant l’exécution du programme. Ce sont des registres permanents flashés au même moment que le programme. Les bits de ces registres sont aussi appelés fusibles ou switchs de configuration. Ces deux registres doivent être configurés à l'aide de la directive __CONFIG. Les logiciels de flachage du PIC® permettent aussi de les positionner.

Microcontrôleur PIC16F887

A.OUMNAD

12

CONFIG1 : 2007
DEBUG LVP FCMEN IESO BOREN1 BOREN0 CPD CP MCLRE PWRTE WDTE FOSC2 FOSC1 FOSC0

DEBUG: In-Circuit Debugger Mode bit Si on active ce mode, on peut brancher un équipement (débuggeur) sur les broches RB6 et RB7 et interagir avec le PIC alors qu’il est déj{ placé dans son environnement réel. On peut ainsi, par exemple suivre un programme à la trace, consulter les valeurs des registres pour trouver les erreurs. 1  In-Circuit Debugger désactivé 0  In-Circuit Debugger active LVP: Low Voltage Programming Enable bit Lors du flashage du PIC, il faut le placer en mode programmation en forçant la broche MCLR soit à 12V (mode HVP) soit à 5V (mode LVP) 0  Low Voltage programming désactivé (mode HVP) 1  Low Voltage programming activé FCMEN: Fail-Safe Clock Monitor Enable bit Le fail safe clock monitor permet au PIC de continuer à fonctionner en cas défaillance des éléments externes de l’horloge en basculant automatiquement sur l’horloge interne 0  Fail-Safe Clock Monitor désactivé 1  Fail-Safe Clock Monitor est activé IESO: Internal External Switchover bit Les oscillateurs à quartz sont connus pour mettre du temps à démarrer. Si on active le mode Internal External Switchover, Le PIC commence { exécuter le programme { l’aide de l’horloge interne en attendant que l’horloge externe se stabilise pour basculer dessus automatiquement 0  Internal/External Switchover désactivé 1  Internal/External Switchover activé BOREN<1:0>: Brown-out Reset Selection bits Si ce mode est activé, le PIC se réinitialise automatiquement chaque fois que Vdd chute en dessous de La valeur VBOR fixée par le bit BOR4V du registre CONFIG2 11  BOR activé 10  BOR activé en fonctionnement normal, désactivé en mode sleep 01  BOR contrôlé durant l’exécution du programme { l’aide du bit SBOREN du registre PCON 00  BOR désactivé CPD: Data Code Protection bit Protection en lecture de la EEPROM de données 1  désactivé 0  activé CP: Code Protection bit Protection en lecture de la mémoire programme 1  désactivé 0  activé

Microcontrôleur PIC16F887

A.OUMNAD

13

MCLRE: RE3/MCLR pin select bit Choix de la fonction de la broche RE3/MCLR 1  RE3/MCLR fonctionne en MCLR = entrée RESET (⍽  Initialisation) 0  RE3/MCLR fonctionne comme entrée numérique. Elle ne peut pas fonctionner en sortie PWRTE: Power-up Timer Enable bit Si on active cette option, au démarrage, le PIC attend 64 ms avant de démarrer le programme. 1  PWRT désactivé 0  PWRT activé WDTE: Watchdog Timer Enable bit 1  Chien de garde WDT activé 0  le chien de garde WDT est désactivé mail il peut être activé durant l’exécution du programme { l’aide du bit SWDTEN du registre WDTCON FOSC<2:0>: Oscillator Selection bits (voir paragraphe sur l’horloge) 111  RC oscillator: RA6=CLKOUT, RA7=pour connecter R et C 110  RCIO oscillator: RA6=E/S normale, RA7=pour connecter R et C 101  INTOSC oscillator: RA6=CLKOUT, RA7=E/S normale 100  INTOSCIO oscillator: RA6=E/S normale, RA7=E/S normale 011  EC (External Clock): RA6=E/S normale, RA7= entrée horloge 010  HS oscillator: High-speed crystal/resonator, Quartz relié sur RA6 et RA7 001  XT oscillator: Crystal/resonator, Quartz relié sur RA6 et RA7 000  LP oscillator: Low-power crystal, Quartz relié sur RA6 et RA7 CONFIG2 : 2008 -

WRT1

WRT0

BOR4V

-

-

-

-

-

-

-

-

WRT<1:0>: Flash Program Memory Self Write Enable bits, Pour protéger la mémoire programme contre des écritures intempestives (par le programme) 00  zone 0000h à 0FFFh protégée, le reste contrôlé par le bit WREN du registre EECON1 00  zone 0000h à 07FFh protégée, le reste contrôlé par le bit WREN du registre EECON1 00  zone 0000h à 00FFh protégée, le reste contrôlé par le bit WREN du registre EECON1 11  protection désactivée. La totalité de la mémoire dépend du bit WREN du registre EECON1 BOR4V: Brown-out Reset Selection bit, Permet de définir la valeur de VBOR, valeur de Vdd en dessous de laquelle le PIC se réinitialise automatiquement (dans le cas ou le BOREN est activé) 0  VBOR = 2.1V 1  VBOR = 4V Les bits non utilisés n’ont pas d’importance. On peut les placer { 0 ou à 1.

Microcontrôleur PIC16F887

A.OUMNAD

14

I.4.1

Exemple de Configuration générique
FCMEN :OFF(0) IESO : OFF(0) CP : OFF(1), MCLRE : ON(1) FOSC : INTOSCIO(100)

CONFIG1 : DEBUG : OFF(1) LVP : OFF(0) BOREN : ON(11) DCP : OFF(1) PWRTE : ON(0) WDTE : OFF(0),  10 0011 1110 0100 = 0x23E4 CONFIG2 : WRT:OFF(11), BOR4V :2.1V(0) __CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF

 11 1110 1111 1111 = 0x3FFF

I.5

L'unité de traitement centrale (CPU)

Le PIC16F887 dispose d'une unité de traitement 8 bits d'architecture RISC (Reduced Instruction Set Computer). Elle reconnait un jeu de 35 instructions simples. Les instructions complexes comme la multiplication et la division ne sont pas implantées. La différence avec les processeurs d'architecture CISC (Complex Instruction Set Computer), qui peuvent décoder jusqu'à 200 instructions dont certaines peuvent être très sophistiquées, est que toutes les instructions sont codées sur un nombre fixe et réduit de bits. Ceci en facilite le décodage et l'exécution. En effet, toutes les instruction sont codées sur 14 bits et sont exécutées en un cycle Tcy de l'horloge instruction Fosc/4. La mémoire programme et la mémoire de données sont distinctes ce qui facilite la gestion des bus. La mémoire programme est une mémoire de type EEPROM flash de capacité 8 × 1024 mots de 14 bits. Chaque position contient le code d'une instruction. Cette mémoire garde son contenu quand le PIC® est éteint et peut être reprogrammée à souhait. Elle joue un peu le rôle d'un disque dur. La mémoire de données est une RAM appelée fichier des registres. Elle est constituée de 96 registres de configuration appelés SFR (Special Function Registers) et de 368 registre à usage général GPR (General Propose Registers) qui jouent le rôle de RAM proprement dit. Tous les registres SFR ou GPR sont des registres 8 bits. Toutes les opérations exécutées dessus sont des opérations 8 bits. Le processeur dispose d'un seul accumulateur nommé W (Working register). C'est un registre de travail 8 bits intégré avec l’Unité Arithmétique et Logique. Il ne peut donc pas être adressé de la même façon que les registres SFR ou GPR puisqu'il n'est pas situé dans la RAM. Toutes les opérations à deux opérandes passent par lui. On peut avoir : - Une opération entre W et une valeur (précisée dans l'instruction) avec résultat dans W - Une opération entre W et un registre ( RAM). Le résultat peut être récupéré soit dans W soit dans le registre. Le processeur dispose d'une pile de 8 positions non accessible par programme. Elle est utilisée pour sauvegarder le compteur programme lors de l'appel de sous-programmes et au branchement aux interruptions. Le programmeur fera donc attention à ne pas avoir plus de 8 appels de fonctions imbriquée.

Microcontrôleur PIC16F887 RAM 96 SFR
W

A.OUMNAD

15

CPU Unité de control et de décodage

Mémoire programme Flash 8 x 1024 x 14 bits

368 GPR

UAL

Horloge système
Figure I-6 : structure très simplifiée de l'unité de traitement

I.6

Organisation de la mémoire RAM

L’espace mémoire RAM adressable est de 512 positions de 1 octet chacune :  96 positions sont réservées au SFR (Special Function Registers) qui sont les registres de configuration du PIC.  Les 416 positions restantes constituent les registres GPR (General Propose Registers) ou RAM utilisateur. Sur le 16F887, 3 blocs de 16 octets chacun ne sont pas implantés physiquement d’où une capacité de RAM utilisateur de 368 GPR. Pour accéder à la RAM, on dispose de deux modes d’adressage :

I.6.1

Accès à la RAM par adressage DIRECT

Avec ce mode d’adressage, on précise dans l’instruction la valeur de l’adresse { laquelle on veut accéder. Par exemple, pour additionner le contenu de l'accumulateur W avec le contenu de la case mémoire d'adresse 50h avec résultat dans Won utilise l'instruction ADDWF 50h,0 ADDWF est l'instruction qui ajoute W au contenu d'une case mémoire. 50h est l'adresse de notre case mémoire. 0 est un bit qui précise que le résultat doit être rangé dans W, si on avait pris 1, le résultat aurait été rangé dans la case mémoire 50h. Cette instruction sera codée sur 14 bits, comme le montre la figure ci-dessous :
6 1 7

CO

d

adresse

Figure I-7: code machine d'une instruction avec adressage direct

 CO est le code opération de l'instruction ADDWF. Il est codé sur 6 bits car on a 35 instructions différentes,  d précise la destination du résultat. Comme il n'y a que deux possibilités W ou F, un seul bit suffit,  adresse est l'adresse la case mémoire. On est obligé de la coder sur 7 bits pour compléter les 14 bits de l'instruction Problème, 7 bits permettent d’adresser seulement 128 positions. Pour pouvoir adresser les 512 positions accessibles, il faut 9 bits d’adresse. Pour avoir ces 9 bits, le PIC® complète les 7 bits venant de l’instruction par deux bits situés dans le registre de configuration STATUS. Ces bits sont appelés RP0

Microcontrôleur PIC16F887

A.OUMNAD

16

et RP1 et doivent être positionnés correctement avant toute instruction qui accède à la RAM par l’adressage direct. RP1 RP0 7 bits venant de l'instruction 9 bits
Figure I-8 : constitution de l'adresse pour l'adressage physique

Même si on précise une adresse supérieure à 127 (+ de 7 bits) dans une instruction, elle est tronquée à 7 bits puis complétée par les bits RP0 et RP1 pour former une adresse 9 bis. Par exemple, pour copier l’accumulateur W dans la case mémoire d’adresse 1EFh, il faut d’abord placer les bits RP0 et RP1 à 1 , ensuite on utilise soit l’instruction MOVWF 6Fh soit l’instruction MOVWF 1EFh, qui donne le même résultat. En effet, que l’on écrive 6Fh = 0110 1111 ou 1EFh = 0001 1110 1111, le PIC ne prend que 7 bits soit : 1101111 = 6Fh et complète avec les bits RP1 RP0 pour obtenir 11 1101111 = 1EFh. Pour positionner les bits RP0 et RP1 on utilise les instructions bcf et bsf. La RAM apparaît alors organisée en 4 pages appelées banks de 128 octets chacun. L'adresse instruction permet d'adresser à l'intérieur d'un bank alors que les bits RP0 et RP1 du registre STATUS permettent de sélectionner un bank. La Figure I-9 montre l’organisation de la RAM avec les zones allouée au SFR et aux GPR. Les zones hachurées ne sont pas implantées physiquement. Si on essaye d’y accéder, on est aiguillé automatiquement vers la zone [70h,7Fh] appelée zone commune. Oublier de sélectionner le bank est une cause fréquente de disfonctionnement de programmes. Si par exemple RP1 RP0 = 01 (bank1 est le bank courant). Si on veut faire une opération sur la case 20h et on oublie de changer de bank. Le processeur prend 7 bits de l'adresse 20h=0010 0000 et complète avec 01 ce qui donne 01 0100000= A0h. Nous croyons travailler sur la case 20h alors que le processeur travaille sur la case A0h. De la même façon, si le bank courant est 11=bank3 et on fait une opération sur le registre PORTA, le processeur travaille sur le registre SRCON. Les 16 cases de la zone commune sont intéressantes car pour y accéder, on n'est pas obligé de préciser le bank.

Microcontrôleur PIC16F887

A.OUMNAD

17

00h 01h 02h 03h 04h 05h 06h 07h 08h 09h 0Ah 0Bh 0Ch 0Dh 0Eh 0Fh 10h 11h 12h 13h 14h 15h 16h 17h 18h 19h 1Ah 1Bh 1Ch 1Dh 1Eh 1Fh 20h

Bank 0 (00) INDF TMR0 PCL STATUS FSR PORTA PORTB PORTC PORTD PORTE PCLATH INTCON PIR1 PIR2 TMR1L TMR1H T1CON TMR2 T2CON SSPBUF SSPCON CCPR1L CCPR1H CCP1CON RCSTA TXREG RCREG CCPR2L CCPR2H CCP2CON ADRESH ADCON0

80h 81h 82h 83h 84h 85h 86h 87h 88h 89h 8Ah 8Bh 8Ch 8Dh 8Eh 8Fh 90h 91h 92h 93h 94h 95h 96h 97h 98h 99h 9Ah 9Bh 9Ch 9Dh 9Eh 9Fh A0h

Bank 1 (01) INDF OPTION_REG PCL STATUS FSR TRISA TRISB TRISC TRISD TRISE PCLATH INTCON PIE1 PIE2 PCON OSCCON OSCTUNE SSPCON2 PR2 SSPADD SSPSTAT WPUB IOCB VRCON TXSTA SPBRG SPBTGH PWM1CON ECCPAS PSTRCON ADRESL ADCON1

100h 101h 102h 103h 104h 105h 106h 107h 108h 109h 10Ah 10Bh 10Ch 10Dh 10Eh 10Fh 110h

Bank 2 (10) INDF TMR0 PCL STATUS FSR WDTCON PORTB CM1CON0 CM2CON0 CM2CON1 PCLATH INTCON EEDATA EEADR EEDATH EEADRH

180h 181h 182h 183h 184h 185h 186h 187h 188h 189h 18Ah 18Bh 18Ch 18Dh 18Eh 18Fh 190h

Bank 3 (11) INDF OPTION_REG PCL STATUS FSR SRCON TRISB BAUDCTL ANSEL ANSELH PCLATH INTCON EECON1 EECON2

120h

1A0h

6Fh 70h Zone commune 7Fh

EFh F0h

16Fh 170h

1EFh 1F0h

FFh

17Fh Figure I-9 : organisation de la RAM du 16F876/877

1FFh

I.7

Accès à la RAM par l’adressage INDIRECT

Pour accéder à une position de la RAM en utilisant l’adressage indirect, on passe toujours par une position fictive appelée INDF (Indirect File). Exemple : l’instruction CLRF INDF signifie : mettre { zéro la case mémoire d’adresse INDF. Mais quelle est l’adresse de cette position appelée INDF ? La réponse est : INDF est la case mémoire pointée par le pointeur IRP/FSR. IRP est un bit qui se trouve dans le registre STATUS et FSR est un registre accessible dans tous les bancs. On peut se demander pourquoi on ajoute le bit IRP. En effet, le registre de pointage FSR est un

Microcontrôleur PIC16F887

A.OUMNAD

18

registre 8 bits, il peut donc adresser au maximum 256 positions mémoire (de 00h à FFh), c’est seulement la moitié de la RAM. Il nous manque un bit pour avoir les 9 bits nécessaires. On utilise le bit IRP qui se trouve dans le registre STATUS. Exemple : Si on place 74h dans le registre FSR et on positionne le bit IRP à 1, alors, l’instruction CLRF INDF signifie : remettre { zéro la case mémoire d’adresse 174h.

IRP

FSR

0 00 0 1F 0 20

SFR (32) GPR (96) SFR (32) GPR (80)

1 00 1 0F 1 10

SFR (16)

GPR (96)
SFR (16)

1 6F 1 80 1 8F 1 90

0 7F 0 80 0 9F 0 A0 0 EF 0 FF

GPR (96)

1 EF 1 FF

page 0

page 1

Figure I-10 : organisation de la RAM pour l'adressage indirect

En résumé, chaque fois que le PIC rencontre le mot INDF dans un programme, il sait qu’il s’agit de la case mémoire dont l’adresse (9 bits) se trouve dans le pointeur FSR complété par le bit IRP du registre STATUS INDF est la case mémoire pointée par le pointeur:

IRP

FSR pointeur 9 bits

IRP = 0  000h à 0FFh IRP = 1  100h à 1FFh

 

page 0 page 1

Microcontrôleur PIC16F887

A.OUMNAD

19

I.8

Quelques registres de configuration et leurs bits
STATUS OPTION_REG INTCON PIE1 PIR1 PIE2 PIR2 PCON OSCCON OSCTUNE EECON1 TXSTA RCSTA CCP1CON CCP2CON T1CON T2CON SSPCON SSPCON2 SSPSTAT CM1CON0 CM2CON0 CM2CON1 SRCON PWM1CON ECCPAS PSTRCON VRCON TXSTA RCSTA BAUDCTL ADCON0 ADCON1 WDTCON TRISx Bank all 1/3 all 1 0 1 0 1 1 1 3 1 0 0 0 0 0 0 1 1 2 2 2 3 1 1 1 1 1 0 3 0 1 2 1 IRP RBPU GIE OSIE OSIF — EEPGD CSRC SPEN P1M1 — T1GINV — WCOL GCEN SMP C1ON C2ON MC1OUT SR1 PRSEN ECCPASE VREN CSRC SPEN ABDOVF ADCS1 ADFM RP1 INTEDG PEIE ADIE ADIF C2IE C2IF IRCF2 — TX9 RX9 P1M0 — TMR1GE TOUTPS3 SSPOV ACKSTAT CKE C1OUT C2OUT MC2OUT SR0 PDC6 ECCPAS2 VROE TX9 RX9 RCIDL ADCS0 — RP0 T0CS T0IE RCIE RCIF C1IE C1IF ULPWUE IRCF1 — TXEN SREN DC1B1 DC2B1 T1CKPS1 TOUTPS2 SSPEN ACKDT D/A C1OE C2OE C1RSEL C1SEN PDC5 ECCPAS1 VRR TXEN SREN CHS3 VCFG1 TO PD T0SE PSA INTE RBIE TXIE SSPIE TXIF SSPIF EEIE BCLIE EEIF BCLIF SBOREN — IRCF0 OSTS TUN4 TUN3 — WRERR SYNC — CREN ADDEN DC1B0 CCP1M3 DC2B0 CCP2M3 T1CKPS0 T1OSCEN TOUTPS1 TOUTPS0 CKP SSPM3 ACKEN RCEN P S C1POL C2POL C2RSEL C2REN PULSS PDC4 PDC3 ECCPAS0 PSSAC1 STRSYNC STRD VRSS VR3 SYNC — CREN ADDEN SCKP BRG16 CHS2 CHS1 VCFG0 WDTPS3 WDTPS2 Z PS2 T0IF CCP1IE CCP1IF ULPWUIE ULPWUIF — HTS TUN2 WREN BRGH FERR CCP1M2 CCP2M2 T1SYNC TMR2ON SSPM2 PEN R/W C1R C2R PULSR PDC2 PSSAC0 STRC VR2 BRGH FERR CHS0 WDTPS1 DC PS1 INTF TMR2IE TMR2IF POR LTS TUN1 WR TRMT OERR CCP1M1 CCP2M1 TMR1CS T2CKPS1 SSPM1 RSEN UA C1CH1 C2CH1 T1GSS PDC1 PSSBD1 STRB VR1 TRMT OERR WUE GO/DONE WDTPS0 C PS0 RBIF TMR1IE TMR1IF CCP2IE CCP2IF BOR SCS TUN0 RD TX9D RX9D CCP1M0 CCP2M0 TMR1ON T2CKPS0 SSPM0 SEN BF C1CH0 C2CH0 C2SYNC FVREN PDC0 PSSBD0 STRA VR0 TX9D RX9D ABDEN ADON SWDTEN RESET 0001 1xxx 1111 1111 0000 000x 0000 0000 0000 0000 -r-0 0--0 -r-0 0--0 --01 --qq -110 q000 -110 q000 x--- x000 0000 -010 0000 000x 0000 0000 --00 0000 --00 0000 -000 0000 0000 0000 0000 0000 0000 0000 0000 -000 0000 -000 0000 --10 0000 00-0 0000 0000 0000 0000 ---0 0001 0000 0000 0000 -010 0000 000x 01-0 0-00 0000 00-0 0-00 ------0 1000 1111 1111

Tableau I-1 : détail des registres SFR et leurs états au démarrage

Exercice 1) Dans quel bank se trouvent les cases mémoire d'adresse : 1A4h, B5h, 130h, 58h, 100, 200, 250, 300, 400 Exercice 2) Combien de cases mémoires libres (GPR) y a-t-il dans la zone mémoire qui commence à la position A0h et se termine à EAh. Exercice 3) Quelle est l'adresse de la dernière position d'une zone mémoire de 40 cases qui commence à la position 190h. Exercice 4) Combien de cases mémoires libres (GPR) y a-t-il dans les bancs bank0, bank1, bank2 et bank3

Microcontrôleur PIC16F887

A.OUMNAD

20

Chapitre II LE JEUX D'INSTRUCTIONS DU PIC16F887
 Tous les PIC® Mid-Range ont un jeu de 35 instructions,  Chaque instruction est codée sur un mot de 14 bits qui contient le code opération ( OC) ainsi que l'opérande,  Toutes les instructions sont exécutées en un cycle d'horloge, à part les instructions de saut qui sont exécutées en 2 cycles d’horloge. Sachant que l’horloge système est égale { Fosc/4, si on utilise un quartz de 20MHz, on obtient une horloge Fosc/4 = 5000000 cycles/seconde, cela nous donne une puissance de l’ordre de 5MIPS (5 Million d’ Instructions Par Seconde

II.1

Les instructions orientées Registre

Ce sont des instructions qui manipulent un octet se trouvant dans la RAM. Ça peut être un registre de configuration SFR ou une case mémoire quelconque (Registre GPR) Ces instruction se présentent sous la forme : ADDWF F,d  ADDWF est le nom de l'instruction. Le F dans le nom de l'instruction signifie que celle-ci agit sur une case mémoire (registre). Chez Microchip®, la RAM est appelée register File (Fichier des registres), d'où l'utilisation de la lettre F pour tout ce qui est registre. o F est l'adresse du registre (SFR ou GPR). Ça peut être une adresse directe ou le mot INDF pour indiquer l'adressage indirect. o d est la destination du résultat. Si d=0 ou d=w, le résultat est rangé dans l'accumulateur W. Si d=1 ou d=f, le résultat est rangé dans le registre F. Dans le tableau ci-dessous, on utilise l'abréviation {W,F ? d} pour dire que le résultat va dans W ou dans F selon la valeur de d. ADDWF 70h,1 ou ADDWF 70h,f Additionner le contenu de W avec le contenu du GPR 70h et placer le résultat dans le GPR 70h XORWF 35h,0 ou XORWF 35h,w Faire un ou exclusif entre W et le contenu du GPR 35h et placer le résultat dans W

II.2

Les instructions orientées bits

Ce sont des instructions destinées { manipuler directement un bit d’un registre que se soit un registre de configuration SFR ou une case mémoire quelconque (registre GPR). Tous les bits de la RAM peuvent être manipulés individuellement. Ces instruction se présentent sous la forme : BCF F,b o F est le registre qui contient le bit o b est le numéro du bit dans le registre. On compte à partir de la droite en commençant par 0 BSF STATUS,2 ; signifie : mettre à 1 le bit 2 (3ème bit à partir de la droite) du registre STATUS

Microcontrôleur PIC16F887

A.OUMNAD

21

II.3

Les instructions opérant sur une valeur

Ce sont les instructions entre l’accumulateur W est une valeur K précisée dans l'instruction. Le résultat va dans W. Toutes ces instructions contiennent la lettre L dans leur nom. Ceci vient du fait que chez Microchip®, ce type d'adressage est appelé adressage Literal.

II.4

Les instructions de saut et appel de procédures

Ce sont les instructions qui permettent de sauter à une autre position dans le programme et de continuer l’exécution { partir de cette position. La position est désignée par une étiquette qui peut être n'importe quelle chaîne alphanumérique qui commence par caractère. L'étiquette peut être terminée par le caractère (:) mais ce n'est pas obligatoire. Elle peut être seule sur une ligne ou au début d'une ligne contenant une instruction.

II.5

Le jeu d'instructions
{W,F ? d} signifie que le résultat est rangé soit dans W si d=0 ou w, soit dans F si d= 1 ou f
INSTRUCTIONS OPERANT SUR REGISTRE ADDWF F,d W+F  {W,F ? d} ANDWF F,d W and F  {W,F ? d} CLRF F Clear F COMF F,d Complémente F  {W,F ? d} DECF F,d décrémente F  {W,F ? d} DECFSZ F,d décrémente F  {W,F ? d} skip if 0 INCF F,d incrémente F  {W,F ? d} INCFSZ F,d incrémente F  {W,F ? d} skip if 0 IORWF F,d W or F  {W,F ? d} MOVF F,d F  {W,F ? d} MOVWF F WF RLF F,d rotation à gauche de F a travers C  {W,F ? d} RRF F,d rotation à droite de F a travers C  {W,F ? d} SUBWF F,d F – W  {W,F ? d} SWAPF F,d permute les 2 quartets de F  {W,F ? d} XORWF F,d W xor F  {W,F ? d} INSTRUCTIONS OPERANT SUR BIT BCF F,b RAZ du bit b du registre F BSF F,b RAU du bit b du registre F BTFSC F,b teste le bit b de F, si 0 saute une instruction BTFSS F,b teste le bit b de F, si 1 saute une instruction INSTRUCTIONS OPERANT SUR CONSTANTE ADDLW K W+KW ANDLW K W and K  W IORLW K W or K  W MOVLW K KW SUBLW K K–WW XORLW K W xor K  W AUTRES INSTRUCTIONS CLRW Clear W CLRWDT Clear Watchdoc timer CALL etqt Branchement à un sous programme de label etqt GOTO etqt branchement à la ligne de label etqt NOP No operation RETURN retourne d'un sous programme RETFIE Retour d'interruption RETLW K retourne d'un sous programme avec K dans W SLEEP se met en mode standby C,DC,Z Z Z C,DC,Z Z Z TO', PD' indicateurs C,DC,Z Z Z Z Z Z Z Z C C,DC,Z Z Cycles 1 1 1 1 1 1(2) 1 1(2) 1 1 1 1 1 1 1 1 1 1 1(2) 1(2) 1 1 1 1 1 1 1 1 2 2 1 2 2 2 1

TO', PD'

Microcontrôleur PIC16F887

A.OUMNAD RAM

22

II.5.1 Les instructions movwf et movf
Ce sont les instructions les plus utilisées, movwf: permet de copier l’accumulateur W dans un registre (SFR ou GPR):
movwf movwf STATUS 55h ; Copier le contenu de W dans le registre STATUS ; Copier W dans la case mémoire d’adresse 55h

W

MOVWF

RAM movf: permet de copier le contenu d’un registre (SFR ou GPR) dans l’accumulateur W, le paramètre d doit être = 0(w)
movf movf STATUS,0 ; Copier le registre STATUS dans l’accumulateur W 35h,w ; Copier le contenu du GPR 35h dans l’accumulateur W

W

MOVF

Avec le paramètre d=1, l’instruction movf semble inutile car elle permet de copier un registre sur lui-même ce qui à priori ne sert à rien.
movf STATUS,1 ; Copier le contenu du registre STATUS dans lui même

En réalité cette instruction peut s’avérer utile car elle positionne l’indicateur Z. On peut s en servir pour tester si le contenu d’un registre est égal { zéro

II.5.2 Les instructions btfss et btfsc
Ces instructions permettent de tester un bit et de sauter ou non une ligne de programme en fonction du résultat,
Btfsc F,b ; bit test skip if clear : teste le bit b du registre F et saute l’instruction suivante si le bit testé est nul ; bit test skip if set : teste le bit b du registre F et saute l’instruction suivante si le bi t testé est égal à 1

Btfss

F,b

exemple :
sublw 100 btfss STATUS,Z clrf 70h cmpf 70h,f suite du programme suite du programme … ; 100 – W  W ; tester le bit Z du registre STATUS et sauter une ligne si Z=1 ; le programme continue ici si Z=0 ; le programme continue ici si Z=1

II.5.3 Les instructions incfsz et decfsz
Ces instructions permettent d’incrémenter ou de décrémenter un registre et de sauter si le résultat est nul
incfsz F,1 ; increment skip if Z : incrémente le registre F et sauter une ligne si le résultat = 0. Le paramètre 1 indique que le résultat de l’incrémentation doit aller dans F. ; decrement skip if Z : décrémente le registre F et sauter une ligne si le résultat = 0. Le paramètre f indique que le résultat de la décrémentation doit aller dans F.

deccfsz

F,f

Microcontrôleur PIC16F887

A.OUMNAD

23

II.5.4 L’instruction goto
Permet de transférer l’exécution (label)
Instruction 1 Instruction 2 Goto bonjour instruction 3 instruction 4 instruction 5 instruction 6 instruction 7

à une autre position du programme repérée par une étiquette

bonjour:

Pour faire un branchement relatif à la ligne courante, on peut utiliser le caractère $ qui désigne l'adresse de la ligne courante
Instruction Instruction Goto $-1 Instruction Goto $+3 Instruction Instruction Instruction Goto $ ; aller à la ligne précédente ; sauter 2 lignes

; rester planté ici

II.5.5 L’instruction call
L’instruction call permet d’appeler une fonction. Une fonction est un sous programme qui peut être écrit avant ou après le programme principal. Sa première ligne doit comporter une étiquette et elle doit se terminer par return. La différence en call et goto est que, quant le processeur rencontre l’instruction call, il sauvegarde (dans la pile) l’adresse de la ligne suivante avant de se brancher { la fonction. Comme ça, quand il rencontre l’instruction return, il sait où il doit retourner pour continuer l’exécution du programm e principal
Programme principal Debut: Instruction Instruction Instruction Instruction Call afficher Instruction Instruction Instruction … goto debut Fonction Afficher:

Instruction Instruction Instruction Instruction Instruction Instruction Instruction return

Microcontrôleur PIC16F887

A.OUMNAD

24

II.6

Les indicateur d’état (drapeaux)

Les bits Z, DC et C situés dans le registre STATUS sont des indicateurs qui permettent de savoir comment une instruction s’est terminée. Toutes les instructions n’agissent pas sur les indicateurs, voir liste des instructions ci-dessous. Z : passe à 1 quand le résultat d’une instruction est nul C : passe à 1 quand l’opération a généré une retenue DC : Digital carry, passe à 1 quand l'opération sur le bit 3 (4ème bit) génère une retenue vers le bit 4 Ces bits peuvent être utilisés très astucieusement par les instructions btfsc et btfss qui permettent de tester un bit et de réaliser un saut conditionnel. Nous aurons l’occasion d’en reparler dans la suite. STATUS IRP RP1 RP0 Z DC C

II.6.1 Les indicateurs, la soustraction et la comparaison
Les instructions SUBWF et SUBLW positionne les drapeaux Z et C. C correspond a la retenue de la soustraction que l 'on désignera par B (Borrow) F - W = 0 ==> F - W > 0 ==> F - W < 0 ==> Z=1 , C=1 , B=0 => pas de retenue de soustraction Z=0 , C=1 , B=0 => pas de retenue de soustraction Z=0 , C=0 , B=1 => il ya retenue de soustraction

Pour réaliser une comparaison entre F et W, on fait F – W et on observe Z et C Z=1 ==> égalité C=1 ==> F sup ou égal à W C=0 ==> F inférieur à W
F-W

Z=1?

oui

F=W

non
C=1?

oui

F>W

non
F<W Figure II-1 : organigramme de la comparaison

II.7

Les directives de l'assembleur MPASM

Les directives de l'assembleur sont des instructions qu'on ajoute dans le programme et qui seront interprétées par l'assembleur MPASM. Ce ne sont pas des instructions destinées au PIC. On ne présente ici que quelques directives. Pour le reste, on peut consulter la documentation de MPASM "MPASM User's Guide". L'aide du logiciel MPLAB contient aussi une rubrique sur l'assembleur MPASM. Remarque : dans la suite, les directives seront représentées en Majuscule. Ce n'est pas une obligation, le compilateur MPASM accepte les instructions et les directives en minuscule et en majuscule. Attention ce n’est pas le cas pour les étiquettes et les noms de déclaration des constantes.

Microcontrôleur PIC16F887

A.OUMNAD

25

II.7.1 La directive LIST
Cette directive permet de définir un certain nombre de paramètres comme le processeur utilisé (p), la base par défaut pour les nombres (r) ainsi que d'autres paramètres. Exemple : LIST p=16F887, r=dec Avec r=dec, les nombres sans préfix ni suffixe seront considérés par l'assembleur comme des nombre décimaux, sinon voir tableau ci-contre
Base Décimal Hexadécimal Binaire Octal Préfixe D'nnn' .nnn H'nn' 0xnn nnh B'….' O'nnn' Exemple (36) D'36' .36 H'24' 0x24 24h B'00100100' O'44'

II.7.2 La directive INCLUDE
Cette directive permet d'insérer un fichier source. Par exemple le fichier p16f887.inc contient la définition d'un certain nombre de constante comme les noms des registres ainsi que les noms de certains bits;
INCLUDE p16f887.inc ; insère le fichier p16f887.inc à cet endroit avant de compiler

Le nom du fichier peut être place entre "" ou entre <> mais ce n'est pas obligatoire

II.7.3 La directive EQU
Cette directive permet de définir une constante ou une variable :
XX EQU 0x20

Chaque fois que le compilateur rencontrera XX, il la remplacera par 0x20. Ça peut être une constante s'il s'agit d'une instruction avec adressage Literal, ou d'une adresse s'il s'agit d'une instruction avec adressage direct.
MOVLW MOVF XX XX,w ; placer dans W la constante 0x20 ; placer dans W le contenu de la case d’adresse 0x20

II.7.4 Les directives CBLOCK/ENDC
Ces directives permettent de définir un bloc C dont le rôle est de simplifier la déclaration des constantes Exemple : L'ensemble des déclarations suivantes :
XX1 XX2 XX3 XX4 EQU EQU EQU EQU 0x20 0x21 0x22 0x23

Peut être remplacé par
CBLOCK 0x20 XX1, XX2, XX3, XX4 ENDC

II.7.5 La directive ORG
Cette directive permet de définir la position dans la mémoire programme à partir de laquelle seront inscrites les instructions qui la suivent. On peut ainsi faire en sorte que le programme ou un bloc de programme soit situé à un endroit particulier de la mémoire programme.

Microcontrôleur PIC16F887

A.OUMNAD

26

Fig. II.1 : Illustration de la directive ORG

II.7.6 La directive #DEFINE
Fonctionne un peu comme la directive EQU tout en étant un peu plus générale. Elle permet d’affecter toute une chaîne à une abréviation
#DEFINE #DEFINE BCF XX LED LED 0x20 ; dans ce cas c’est équivalent à XX EQU 0x20 PORTB,3 ; chaque fois que le compilateur rencontrera le mot LED, il le remplacera par PORTB,3 ; sera remplacé par BCF PORTB,3 => éteindre la LED branchée sur la broche 3 de PORTB

II.7.7

Les directives LOW et HIGH

LOW : retourne l'octet de poids faible d'un nombre (bit 0 à 7) HIGH : retourne l'octet de poids fort d'un nombre (bit 8 à 15) Le nombre décimal 37500 est un nombre 16 bits (10010010 01111100). Il n'est pas aisé de déterminer les valeurs de l'octet de poids faible et de poids fort sans passer par le binaire. C'est là qu'apparait l'intérêt des directives LOW et HIGH.
Movlw Movlw LOW HIGH 37500 37500 ; place dans W la valeur 124 = 01111100 ; place dans W la valeur 146 = 10010010

On remarquera au passage que le poids décimal de l'octet de poids faible est 1 et celui de l'octet de poids fort est 256. Ainsi, 37500 = 146 × 256 + 124

II.7.8 La directive DE
Sert à déclarer des donnés qui seront stockée dans l'EEPROM de donnée au moment de l'implantation du programme sur le PIC®. L'adresse de la première position de la EEPROM de données est 0x2100
ORG 0x2104 DE "PIC", .70, 'Z',.23, 58h, .260, 3f6h ORG 0 Programme

Microcontrôleur PIC16F887

A.OUMNAD

27

Lors du flashage du PIC®, le programme sera flashé à partir de la première position de la mémoire programme. Les données "PIC", .70, 'Z',.23, 58h, .260, 3F6h seront flashé à partir de la position 04 de la mémoire EEPROM de données. Chaque octet occupe une position. Pour les caractères, c'est le code ASCII qui est stocké, cela va de soi. Si une donnée dépasse 8 bits (255) elle est tronquée. La figure ci-dessous montre comment les données seront placées dans la mémoire EEPROM
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

P

I

C

.70

Z

.23

58h

4

F6h

II.7.9 La directive DT
L'instruction RETLW k est une instruction qui permet de quitter un sous programme et retourner au programme appelant en ramenant la valeur k dans W. Cette instruction est souvent utilisée pour réaliser des transcodages de tableaux. Normalement cette opération nécessite l'écriture d'un nombre éventuellement important de lignes RETLW k. Pour faciliter l'écriture des programmes, la directive DT permet de générer une suite d'instruction RETLW.
DT .10,35h,’Hello’ RETLW RETLW RETLW RETLW RETLW RETLW RETLW .10 35h 'H' 'e' 'l' 'l' 'o' ; le compilateur remplace cette ligne par lignes ci-dessous

II.7.10 La directive END :
Cette directive doit être placée tout à la fin du programme, après le programme principal et les fonctions.

II.7.11 La directive __CONFIG
Cette directive (qui commence par 2 underscore) permet de définir les registres de configuration CONFIG1 et CONFIG2. Exemple :
__CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF

II.8

Les opérateurs arithmétique et logique de l'assembleur

L'assembleur MPASM dispose d'un préprocesseur qui peut interpréter un ensemble important d'opérateurs. Ces opérateurs peuvent agir sur des valeurs de constante ou de variable de l'assembleur et en aucun cas sur le contenu des registres du PIC®. Si on écrit l'instruction movlw 25 + 7. L'assembleur reconnait l'opérateur + et fait l'addition à notre place. Lors de la compilation, l'instruction sera remplacée par movlw 32. En aucun cas, on n'a le droit d'écrire une instruction du genre: movlw FSR + 5 où FSR est un registre du PIC®. opérateur + * / ~ % déscription addition Soustraction ou négation multiplication division complément modulo
exemple ALPHA EQU 12 BETA EQU 50 movlw -5 addlw ((ALPHA + 25)*3 –BETA) / 2 movlw ~0x0F équivaut à movlw 0xF0 movlw BETA % 16

Microcontrôleur PIC16F887 ≪ ≫ & | ^ LOW HIGH UPPER

A.OUMNAD

28

Movlw 3 ≪ 2 (3 décalée à gauche de 2 position =12) Décalage à gauche Movlw BETA ≫ 3 Décalage à droite ET bit par bit Movlw ((BETA & ALPHA) | 0x0F) ^ 25 OU bit par bit XOR bit par bit Movlw LOW 2011 Extrait l'octet bas movlw HIGH 2011 Extrait l'octet haut ème ; W=33h Extrait le 3 octet à Movlw UPPER 44332211h Movlw UPPER (44332211h ≫ 8) ; W=44h partir de la droite
Tableau II-1: quelques opérateurs de l'assembleur (liste très incomplète)

II.9

Les macros

Les macros de l'assembleur MPASM constituent un moyen de programmation très avancé. On va se contenter d'une définition simple. Une macro fonctionne un peut comme la directive #DEFINE ou EQU, elle permet d'affecter une abréviation à un bloc d'instruction. La syntaxe de déclaration est la suivante
Nom_Macro macro Instruction 1 Instruction 2 Instruction 3 … endm

Exemple:
BANK0 macro Bcf Bcf endm STATUS,RP0 STATUS,RP0

Chaque fois que l'on désire se place dans le bank0, il suffira d'écrire BANK0, le compilateur la remplacera par les deux instructions correspondantes. Attention, une macro n'est pas une fonction. Chaque fois que le compilateur rencontre une macro, il la remplace par les instructions correspondantes. Si on déclare une macro de 100 instructions, chaque fois qu'on l'invoque, le compilateur écrit 100 lignes de programme. Si on l'invoque 100 fois dans un programme, la taille de celui-ci dépassera les 10000 lignes et ne pourra pas être implanté dans le 16f887. Avec une fonction, c'est différent. Chaque fois qu'on l'invoque à l'aide de l'instruction call, le processeur va exécuter la fonction à son emplacement et revient continuer son travail. De ce fait, la fonction est écrite une seule fois dans le programme. Une macro peut avoir des paramètres, exemple:
TEMPO1 macro movlw call endm Fosc,Tus ((Tus*Fosc)-.14)/.12 tempo1

Cette macro peut être invoquée en lui passant des paramètres, exemple :
TEMPO1 8, 50

Le langage des macros de l'assembleur MPASM est très évolué. Nous n'en parlerons pas ici car il ne fait pas partie des objectifs de cet ouvrage.

Microcontrôleur PIC16F887

A.OUMNAD

29

Chapitre III LES OUTILS DE DEVELOPPEMENT
L’outil de développement principal est l’environnement de développement intégré MPLAB® IDE fournit gratuitement par Microchip. Cet outil intègre l'éditeur, l'assembleur Microchip MPASM, le simulateur MPLAB SIM, le programme de flashage à condition d'utiliser un flasheur Microchip® qui lui, n'est pas gratuit.

III.1

Procédure de travail

Les étapes nécessaires permettant de voir un programme s'exécuter sur un PIC sont :  Ecrire un programme en langage assembleur dans un fichier texte et le sauvegarder avec l'extension .asm (les adeptes du C peuvent travailler en C, mais ça, c’est une autre histoire)  Assembler (compiler) ce programme avec l'assembleur MPASM. Le résultat est un fichier exécutable avec l'extension .hex contenant une suite de codes machines compréhensible par le PIC®.  Implanter le fichier .hex dans la mémoire programme du PIC (mémoire flash) à l'aide d'un programmateur adéquat. On peut utiliser les programmateurs de Microchip ou tout autre programmateur acheté ou réalisé par soit même.  Mettre le PIC dans son montage final, mettre sous tension et admirer le travail.

III.1.1 Programmeur simple
Le programmeur le plus simple que l'on puisse réaliser est celui représenté sur la figure ci-dessous. Nous l'avons essayé avec succès sur un ordinateur de bureau avec le logiciel ICPROG. Le port série des ordinateurs portables ne délivre pas le 12V nécessaire à l'entrée MCLR pour placer le PIC® en mode programmation. Par ailleurs, les ordinateurs portables récents ne sont pas équipés de port série. Des programmeurs qui se branchent sur le port USB sont désormais disponibles à des prix abordables.
5V Port série Vdd TxD(3) RTS(7) DTR(4) CTS(8) GND(5)
Figure III-1 : programmeur à deux résistances

MCLR 22k 2.2k RB6 RB7 Vss

PIC

Microcontrôleur PIC16F887

A.OUMNAD

30

III.1.2 PIC® en mode exécution
Après sa programmation, le PIC® doit être placé en mode exécution (mode RUN) pour qu'il commence à exécuter le programme. Pour cela, il faut placer la broche MCLR au niveau haut. Il est préférable de le faire à travers une résistance 1kΩ ou plus. Si le PIC® est configuré pour fonctionner avec l'horloge à quartz ou l'horloge RC, il ne faut pas oublier de brancher le quartz ou le réseau RC
5V 5V 5V

Vdd 1k MCLR 1k

Vdd OSC1 MCLR OSC2

Vdd 1k MCLR OSC1

PIC
Vss

Vss

Vss

Figure III-2 : PIC® en mode RUN, oscillateur interne, oscillateur à quartz, oscillateur RC

III.2

L’environnement de développement MPLAB®

MPLAB-IDE® peut être téléchargé site web www.microchip.com Après l'installation, lancer MPLAB®, faire la config ci-dessous :  Sélectionner le PIC® sur lequel on travaille  Configure  Select Device  PIC16F887  Pour faire apparaître la barre d’outils du simulateur : Debugger  Select tool  MPLAB SIM  Pour retrouver l'ancien espace de travail après un redémarrage: Configure  settings Workspace automatically save workspace upon closing et reload last workspace at startup On va réaliser un tout petit programme sans grand intérêt pour voir la procédure de fonctionnement,  Ouvrir une nouvelle fenêtre (de l'éditeur) pour commencer à écrire un programme : file  new ou cliquer sur l'icône feuille blanche  Saisir le petit programme ci-dessous. Ce programme incrémente sans fin la position mémoire (RAM) 70H
loop incf goto END 70h,1 looop

 Sauvegarder (file  save ) ce programme dans le dossier de votre chois sous le nom bidon.asm  Lancer la compilation du programme à l'aide de la commande project  Quikbuild Apparemment il y a un problème, le compilateur nous dit qu'il y une erreur à la ligne 2
Error[113] C:\...\BIDON.ASM 2 : Symbol not previously defined (looop)

Microcontrôleur PIC16F887

A.OUMNAD

31

Effectivement, il ya une erreur de frappe. L’étiquette s’appelle loop et non looop. Double cliquez sur la ligne Error[113]... ce qui vous envoie directement { la ligne contenant l’erreur. Corrigez et recommencez. Cette fois ça a l'air d'aller. On peut vérifier que le compilateur a créé le fichier bidon.hex dans le même dossier où se trouve bidon.asm. D'autres fichiers sont créés. Seul le fichier .hex nous intéresse pour le moment. Les autres peuvent être détruits s'il le faut.  On peut maintenant exécuter le programme en simulation pour voir s'il réalise bien la tache demandée. On remarque qu'après la compilation, une flèche verte pointe sur la première ligne du programme. Cette flèche correspond à la position du program Counter. Elle pointe sur la prochaine instruction qui sera exécutée. Si la flèche n'est pas visible, c'est que le simulateur MPLAB SIM n'a pas été sectionné. Il faut le sélectionner comme indiqué plus haut et recompiler le programme. Ouvrir la fenêtre qui visualise la mémoire RAM : view  FileRegisters et repérer la case mémoire 70h  Exécuter le programme PAS à PAS en cliquant à chaque fois sur le bouton Step Into {} en observant la case mémoire 70h . (on dirait que ça marche).  On peut aussi exécuter en continu en cliquant sur le bouton animate  , pour arrêter, il faut cliquer sur le bouton halt   Dans le programme, remplacer 70h par 190h, compilez, simulez et tirer les conclusions. On dirait qu'il y a comme un petit problème de bank.

Figure III-3 : capture d'écran MPLAB®

Microcontrôleur PIC16F887

A.OUMNAD

32

III.3

Programme type : adressage direct

On va écrire un petit programme simple pour illustrer comment on définit les registres de configuration CONFIG1 et CONFIG2 essentiellement pour configurer l'horloge. On va aussi aborder le problème de changement de bank quand on accède à la RAM par l'adressage direct. L'objectif du programme et de placer quatre octets dans la RAM : .35 dans la position 20h, 'A' dans la position A0h -5 dans la position 110h, 35h dans la position 190h  Pour les switchs de configuration, on utilisera la configuration générique du paragraphe I.4.1. Les choix les plus importants sont WDT:OFF, LVP:OFF, horloge interne
__CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF

 Pour la fréquence, on choisira Fosc = 8 Mhz, à l'aide du registre OSCCON (bank1) (§I.3.4.1, page 11) : OSCCON = 0 111 000 1 = 0x71
Movlw movwf 0x71 OSCCON

 Le PIC® ne connait pas les noms des registres SFR comme STATUS dont nous allons avoir besoin pour changer de bank. Normalement, il faut y accéder par leurs adresses. Ceci rend la programmation un peu rébarbative. Pour y remédier il suffit d'inclure dans notre programme le fichier p16f887.inc qui contient la déclaration EQU des tous les registres SFR et de tous les bits genre RP0, RP1 …Attention, Tous les registres et les bits ont été déclarés en MAJUSCULE
INCLUDE p16f887.inc

 Bien que ce ne soit pas obligatoire, on va rajouter la directive LIST pour définir le processeur et définir le décimal comme base par défaut,
LIST p=16f887, r=dec

 Le caractère (;) sert à introduire un commentaire qui n'est pas interprété par le compilateur,  Malgré le fait qu'on ait définit le décimal comme base par défaut. Il est conseiller de prendre l'habitude de précéder les nombres décimaux par le préfix (.)  A la fin, on peut mettre une instruction sleep pour placer le PIC® en mode faible consommation.  Il ne faut pas oublier de terminer le programme par la directive END On obtient le programme ci-dessous
Programme ram_direct.asm ;========================================================== ; Accès à la RAM par l'adressage direct ;========================================================== INCLUDE p16f887.inc LIST p=16f887, r=dec __CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF ; ==== fin déclarations début programme ========== bsf STATUS,RP0 bcf STATUS,RP1 ; 01 : bank1 movlw 0x71 movwf OSCCON ; Oscillateur interne, Fosc=8MHz bcf bcf movlw movwf STATUS,RP0 STATUS,RP1 .35 20h ; 00 : Bank0

Microcontrôleur PIC16F887

A.OUMNAD

33

bsf movlw movwf bcf bsf movlw movwf bsf movlw movwf sleep END

STATUS,RP0 'A' 0xA0 STATUS,RP0 STATUS,RP1 -.5 ;ou -D'5' 110h STATUS,RP0 35h 190h

; 01 : Bank 1

; 10 : bank 2

; 11 : Bank3

o Démarrer MPLAB, commencer un nouveau fichier o Sauvegarder le sous le nom ram_direct.asm, Il est important de donner un nom au programme avant même de le saisir car, en voyant l'extension (.asm), l'éditeur de MPLAB sait que c'est un programme assembleur. Il reconnait les mots clef et les affiche avec des couleurs différentes ce qui permet une saisie plus agréable. o Saisir le programme o Le compiler : Project → Quickbuild Nous disposons maintenant du programme exécutable ram_direc.hex que nous pouvons implanter dans un PIC®. Nous n'allons pas le faire car on ne pourra rien voir vu que ce programme ne fait aucune action externe. Par contre nous pouvons faire quelques investigations en simulation sous MPLAB. On peut visualiser la mémoire programme : View → Program Memory

Figure III-4:

Sur la fenêtre qui s'affiche on peut tirer quelques enseignements :  La colonne Opcode contient les codes machines 14 bits qui seront réellement implantés dans la mémoire programme du PIC®.  La colonne Disassembly est là pour vérification.

Microcontrôleur PIC16F887

A.OUMNAD

34

o On peut y voir que les directives ne font pas partie du programme exécutable. C'est normal, les directives ne sont pas destinées au PIC®, elles sont interprétées par le compilateur, o L'instruction bcf STATUS,RP0 a été remplacée par bcf 0x3, 0x5, c'est normal, l'unité de traitement du PIC® ne reconnait pas les mots clef STATUS, RP0, RP1…le compilateur les a remplacés par leur valeur qu'il a trouvé dans le fichier p16f887.inc. On peut vérifier sur la Figure I-9 (page17) que 0x3 est l'adresse du registre STATUS et sur le Tableau I-1 (page19) que RP0 et le bit 5 de STATUS o Sur la ligne 10, on remarque que le compilateur a remplacé le (-5) par (0xFB) qui est le complément à 2 de 5. Ceci nous évite de le faire nous même. o Les lignes 11 et 14 contiennent la même instruction MOVWF 0x10. Alors que dans notre programme, la première est : movwf 110h, et la deuxième est movwf 190h. C'est normal, avec l'adressage direct, le compilateur ne prend que 7 bits de l'adresse qu'on lui donne. Or 110h = 1 0001 0000 et 190h =1 1001 0000, si on prend 7 bits à partir de la droite, on obtient 001 0000 = 10h dans les deux cas o Après la fin du programme toutes les positions de la mémoire programme contiennent le code machine 3FFFh = 11 1111 1111 1111. (Les positions de la mémoire programme qui n'on pas été flashés ont tous leurs bits égaux à 1). Ce code machine correspond à une instruction qui existe, addlw 0xFF. Quand le PIC® a terminé l'exécution du programme que nous lui avons donné, il continue en exécutant ces instruction. Ceci n'a aucune conséquence grave. On peut l'éviter en terminant le programme par l'instruction sleep qui arrête l'exécution et place le PIC® en mode faible consommation.. On peut maintenant simuler le programme pour voir s'il réalise les taches prévues. o Ouvrir la fenêtre qui visualise la mémoire RAM : view  FileRegisters et repérer les cases mémoire 20h, A0h, 110h, 90h o Exécuter le programme PAS à PAS en cliquant à chaque fois sur le bouton Step Into {}

III.3.1 Des macros pour sélectionner les banks
Vous avez sans doute remarqué que l'utilisation des bits RP0 et RP1 pour changer de bank n'est pas très commode. Nous allons introduire dans le programme quatre macros que nous appellerons BANK0, BANK1, BANK2 et BANK3. Ces macros nous permettrons de sélectionner un bank D'une façon plus souple. Exercice 5) macros Ecrire les 4 macros. Les placer dans un fichier appelé mesmacros.inc et donner la version du programme précédent en utilisant ces macros Exercice 6) adressage indirect Programme qui copie l'alphabet majuscule dans la RAM à partir de la position 190h La position 70h est utilisée comme compteur. Ce programme illustre l'utilisation de l'adressage indirect et la réalisation d'une boucle avec un compteur et l'instruction decfsz.

Exercice 7) Soustraction Donner les instructions qui permettent de :

Microcontrôleur PIC16F887  Changer le signe de l'accumulateur W (W = -W)

A.OUMNAD

35

 Changer le signe du contenu d'un registre F (F = -F)  Soustraire la constante 33 de l'accumulateur W (W-33) (W–  Soustraire le contenu de la case mémoire 70h de l'accumulateur W avec résultat dans W. [70h]  W )

Exercice 8) (comp1.asm) Comparer les contenus des cases mémoire 6Fh et EFh, s’il son égaux mettre { zéro tous les bits de la case 16Fh sinon mettre à 1 tous les bits de la case 1EFh Exercice 9) (comp2.asm) Comparer les contenus des cases mémoire 6Fh et EFh, si [6Fh] = [EFh] copier la lettre E dans la case mémoire 16Fh si [6Fh] > [EFh] copier la lettre S dans la case mémoire 16Fh si [6Fh] < [EFh] copier la lettre I dans la case mémoire 16Fh

III.4

Boucles de temporisation

On a souvent besoin d'introduire des temporisations pendant l'exécution d'un programme. Le PIC dispose de 3 timers permettant de gérer le temps avec précision. On étudiera ces modules plus tard, pour l'instant, on va réaliser des temporisations à l'aide de simples boucles. L'idée est d'initialiser une variable à une valeur donnée et ensuite la décrémenter en boucle jusqu'à ce qu'elle atteigne 0. Connaissant le temps d'exécution de chaque instruction, on peut calculer le temps que mettra le processeur pour terminer la boucle de décrémentation

III.4.1 Temporisation avec une boucle
Examinons l'exemple ci-dessous. On met une valeur N1 dans la case mémoire 70h et on la décrémente jusqu'à 0
movlw movwf decfsz goto 4 70h 70h,f ici

ici:

-

Les instructions movlw et movwf prennent 1 cycle chacune, L'instruction decfsz prend un cycle si elle ne saute pas et 2 cycles quand elle saute, L'instruction goto prend 2 cycles, chaque passage dans la boucle prend (1+2) cycle sauf le dernier qui prend 2 cycle T = 2 + (N1-1)×3 + 2 = 3×N1 + 1 cycles .

La valeur max de T est obtenue pour N1 = 0 (= 256). L'instruction decfsz décrémente d'abords et teste ensuite. Décrémenter 0 donne 255. Donc N1=0 équivaut à N1=256, ce qui donne une temporisation max de Tmax= 769 cycles. Avec Fosc = 4 Mhz, 1 cycle = 4/Fosc = 1 µs, ce qui donne une temporisation max de 769 µs Pour faciliter l'utilisation de cette temporisation on va l'utiliser comme une fonction que l'on appellera tempo1. On note AN1 la case mémoire qui sert de compteur, il faut la déclarer au début avec la directive EQU. W sert de paramètre d'entrée.
tempo1: t1: movwf decfsz goto AN1 AN1,f t1

Microcontrôleur PIC16F887
return

A.OUMNAD

36

Cette fonction doit être placée après le programme principal. Chaque fois qu'on veut introduire une temporisation, on place une valeur dans W et appelle la fonction. W sert de paramètre à la fonction.
movlw Call valeur tempo1

Pour le calcul il faut rajouter 2 cycles pour l'instruction call et 2 cycles pour l'instruction return. T1 = 3×W + 5 cycle . 1 cycle = 4/Fosc

Le maximum est obtenu pour W =256, soit T1max = 773 cycles.

III.4.2 Temporisation avec 2 boucles imbriquées
Avec deux boucles imbriquées, on a deux paramètre N1 pour la boucle intérieure te N2 pour la boucle extérieure. Pour faciliter l'utilisation, nous allons fixer le paramètre N1 à 0 ce qui nous le savons, correspond à N1=256. C’est N2 qui constituera le paramètre de la fonction, Il faut le placer dans W avant de l’appeler.
tempo2: t2: movwf decfsz goto decfsz goto return AN2 AN1,f t2 AN2,f t2

T2 = 2 + 2 + [W(t1+3)-1] + 2,

avec t1 = 256×3 – 1 = 767 on obtient : T2 = 770 W +5 cycles . 1 cycle = 4/Fosc

Le maximum est obtenu pour N2 =256, soit T2max = 197125 cycles

III.4.1 Temporisation avec 3 boucles imbriquées
Les boucles intérieures (N1 et N2) se font toujours 256 fois. La boucle extérieure se fait N3 fois. C’est N3 qui constituera le paramètre de la fonction, Il faut le placer dans W avant de l’appeler.
tempo3: t3: movwf decfsz goto decfsz goto decfsz goto return AN3 AN1,f t3 AN2,f t3 AN3,f t3

T3 = 2 + 2 + W(t2+3)-1 + 2 avec t2=256*(767+3)-1 on obtient : T3 = 197122 W +5 cycles . 1 cycle = 4/Fosc

Le maximum est obtenu pour N3 =256, soit T3max = 50463237 cycles

Microcontrôleur PIC16F887

A.OUMNAD

37

Remarques : 1) La précision de ces fonctions peut être améliorée en y insérant des instructions nop, dans ce cas il faut revoir les formules. 2) Si les Variables AN1, AN2 et AN3 sont placée dans la zone commune, aucune précaution particulière ne s'impose. Par contre, si on choisi de les placer ailleurs pour réserver la zone commune au programme principal, il faudra faire attention que le bank soit bien configuré durant l'appel de ces fonctions. Si on choisit par exemple de les placer en bank0 aux positions 20h, 21h et 22h. Deux approches peuvent être envisagées: a. Une approche simple qui consiste à se rappeler que les fonctions de temporisation utilisent le bank0. A chaque fois qu'on veut appeler une de ces fonctions, il faut se place dans ce bank avant de le faire. b. Une approche plus robuste consiste à ajouter au début de chaque fonction, deux instructions bcf STATUS,RP0 et bcf STATUS,RP1 pour se placer dans le banko. Il faut aussi sauvegarder le registre STATUS au début de la fonction et le restituer à la fin de sorte que, au retour de la fonction, on se retrouve dans le bank initial. Les instructions rajoutées doivent être comptabilisée dans les formules des temporisations.

Microcontrôleur PIC16F887

A.OUMNAD

38

Chapitre IV LES PORTS d’ENTRÉE SORTIES
Le PIC 16F887 dispose de 36 broches d’entrée sortie regroupés dans 5 ports PORTA, PORTB, PORTC, PORTD et PORTE. Chaque broche d’un port peut être configurée soit en entrée soit en sortie { l’aide des registres de direction TRISA, TRISB, TRISC et TRISD et TRISE:

Bit k de TRISx = Bit k de TRISx =

0 1

 broche k de PORTx =  broche k de PORTx =

SORTIE ENTRÉE

TRISx

0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1

PORTx

S/E S/E S/E S/E S/E S/E S/E S/E

Certains ports ont quelques particularités que nous allons détailler ci-dessous,

IV.1

Le port d' E/S PORTA

Le port A désigné par PORTA est un port bidirectionnel de 8 bits RA0 à RA7. La direction de chaque bit est contrôlée par le bit correspondant du registre TRISA  RA6 et RA7 peuvent être configurées en E/S numérique ou peuvent être affectées au générateur d’horloge  RA4 est une E/S numérique. En sortie, RA4 a une structure drain ouvert. Pour l'utiliser comme sortie, il faut ajouter une résistance de pull-up externe. Le schéma illustre (pour les non électroniciens) le principe d'une sortie drain ouvert (ou collecteur ouvert) : si RA4 est positionnée à 0, l'interrupteur est fermé, la sortie est reliée à la masse, c'est un niveau bas. Si RA4 est placée à 1, l'interrupteur est ouvert, la sortie serait déconnectée s'il n'y avait pas la résistance externe qui la place au niveau haut.  RA0, RA1, RA2, RA3 et RA5 peuvent être utilisées soit comme E/S numériques soit comme entrées analogiques. Quand elles sont configurées en entrée { l’aide de TRISA, le choix entre entrée Analogique ou Numérique se fait à l’aide des bits ANS0, ANS1, ANS2, ANS3 et ANS4 du registre ANSEL (bank3). o ANSi = 0  L’entrée correspondante est configurée en Numérique o ANSi = 1  L’entrée correspondante est configurée en Analogique

Vdd 1k RA4

IV-1: drain ouvert

Microcontrôleur PIC16F887 ANSEL

A.OUMNAD

39

ANS7 ANS6 ANS5 ANS4 ANS3 ANS2 ANS1 ANS0 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 RA5 N/A RA3 N/A RA2 N/A RA1 N/A RA0 N/A

Les broches configurées en sortie fonctionnent toujours en numérique quelque soit l'état des bits correspondant dans ANSELH. Il est toutefois fortement conseillé de les configurer en numérique en mettant les bits ANSEL correspondant à 0. En effet, toutes les instructions agissant sur registres, font une opération Lecture-Modification-Ecriture. Or une broche dont le bit ANSEL est égal à 1 fonctionne en analogique dans le sens de l'entrée, sa lecture retourne une valeur numérique mal définie. A part les instructions MOVWF et CLRF dont le résultat est indépendant de l'état actuel du registre, toutes les autres instructions donneront des résultats erronés

IV.2

Le port d'E/S PORTB

Le port B désigné par PORTB est un port bidirectionnel de 8 bits RB0 à RB7. La direction de chaque bit est contrôlée par le bit correspondant du registre TRISB.  RB6 et RB7 fonctionnent toujours en E/S numériques  RB0, RB1, RB2, RB3, RB4 et RB5 peuvent être utilisées soit comme E/S Numériques soit comme entrées Analogiques. Quand elles sont configurées en entrée { l’aide de TRISB, le choix entre entrée Analogique ou Numérique se fait { l’aide des bits ANS8, ANS9, ANS10, ANS11, ANS12 et ANS13 du registre ANSELH (bank3). o ANSi = 0  L’entrée correspondante est configurée en Numérique o ANSi = 1  L’entrée correspondante est configurée en Analogique ANSELH Entrées de PORTB ANS13 ANS12 ANS11 ANS10 ANS9 0/1 0/1 0/1 0/1 0/1 RB5 N/A RB0 N/A RB4 N/A RB1 N/A RB3 N/A ANS8 0/1 RB2 N/A

Les broches configurées en sortie fonctionnent toujours en numérique quelque soit l'état des bits correspondant dans ANSELH. Il est toutefois fortement conseillé de les configurer en numérique en mettant les bits ANSEL correspondant à 0. Ceci pour les mêmes raisons spécifiées pour le registre ANSEL

IV.3

Le port d' E/S PORTC

Le port C désigné par PORTC est un port bidirectionnel de 8 bits RC0 à RC7. Ce port fonctionne toujours en numérique. La direction de chaque bit est contrôlée par le bit correspondant du registre TRISC

IV.4

Le port d' E/S PORTD

Le port D désigné par PORTD est un port bidirectionnel de 8 bits RD0 à RD7. Ce port fonctionne toujours en numérique. La direction de chaque bit est contrôlée par le bit correspondant du registre TRISD.

Microcontrôleur PIC16F887

A.OUMNAD

40

IV.5

Le port d'E/S PORTE

Le port E désigné par PORTE est un port bidirectionnel de 4 bits RE0 à RE3. La direction de chaque bit est contrôlée par le bit correspondant du registre TRISE  RE3 peut fonctionner soit en Entrée numérique soit comme entrée de Reset MCLR. Le choix se fait à l’aide du switch MCLRE du registre de configuration CONFIG1  RE0, RE1, et RE2 peuvent être utilisées soit comme E/S numériques soit comme entrées analogiques. Le contrôle se fait { l’aide des bits ANS5, ANS6 et ANS7 du registre ANSEL (bank3). o ANSx = 0  L’entrée correspondante est configurée en Numérique o ANSx = 1  L’entrée correspondante est configurée en Analogique ANSEL ANS7 ANS6 ANS5 0/1 0/1 0/1 RE2 N/A RE1 N/A RE0 N/A

IV.6

Situation au démarrage

Au démarrage :  Tous les ports sont configurés en entrée  Les entrées Analogique/Numériques sont configurés en analogique

IV.7

Programmes types

IV.7.1 Faire clignoter une LED
Nous y sommes, avec ce que nous avons appris jusqu'ici, nous somme en mesure d'écrire un premier programme qui peut être vérifié soit sur un vrai PIC®, soit en simulation sur un logiciel qui dispose d'un modèle pour le PIC16F887. C'est le cas de Proteus-Isis. Nous allons réaliser un petit programme qui fait clignoter une LED branchée sur la broche RA3 avec une temporisation voisine de 0.5 secondes. Pour l'horloge du PIC®, nous travaillerons avec Fosc = 8 MHz qui sera délivrée par l'oscillateur interne.

IV.7.1.1

Préparation

Regardons laquelle des trois fonctions tempo1, tempo2 ou tempo3 convient pour obtenir T= 0.5 s = 500 000 µs. Avec Fosc = 8 MHz, on a TCY = 4 / Fosc = 0.5 µs

 Avec tempo1 on obtiendrait au maximum 773 × 0.5µs = 386.5 µs, largement insuffisant  Avec tempo2 on obtiendrait au maximum 773 × 0.5µs = 98563 µs, encore insuffisant  Avec tempo3 on peut aller jusqu'à 50463237 × 0.5µs = 25.232 s , largement suffisant  Le paramètre de tempo3 pour avoir 0.5s est déterminé par : (197122 × W + 5 ) ×0.5 µs = 500000µs. On obtient W = 5.073, on prend W=5 qui donne une temporisation de 0.493s  Pour les switchs de configuration nous utiliseront la configuration générique, (§I.4.1, page14)

Microcontrôleur PIC16F887
__CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF

A.OUMNAD

41

 Pour choisir Fosc = 8 Mhz, il faut configurer le registre OSCCON (bank1) (I.3.4.1, page 11) OSCCON = 0 111 000 1 = 0x71
movlw movwf 0x71 OSCCON

 Il faut configurer la broche RA3 en Analogique à l'aide du registre ANSEL (bank3) (IV.1,§IV.1, page38) et en sortie à l'aide du registre TRISA (bank1)  Pour le corps du programme, rien de sorcier. On allume en plaçant RA3 à 1, on attend 0.5s, on éteint en plaçant RA3 à 0, on attend 0.5s et on recommence indéfinitivement. Voici ce que ça donne :
LED-RA3.asm INCLUDE LIST __CONFIG __CONFIG INCLUDE AN1 EQU AN2 EQU AN3 EQU

p16f887.inc p=16f887, r=dec 0x2007 , 0x23E4 0x2008 , 0x3EFF mesmacros.asm 0x20 ; ces 3 positions mémoires 0x21 ; sont utilisées par les 3 0x22 ; compteurs de tempo3

;============================= fin déclarations, début programme ========== BANK1 movlw 0x71 movwf OSCCON ; Oscillateur interne, Fosc=8MHz bcf TRISA,3 ; RA3 en sortie BANK3 bcf ANSEL,ANS3 ; RA3 numérique BANK0 ici: bsf PORTA,3 ; allumer movlw 6 call tempo3 ; attendre 0.6 s bcf PORTA,3 ; éteindre movlw 6 call tempo3 goto ici ; recommencer ;================== fin programme, début définition fonctions ========== tempo3: movwf AN3 t3: decfsz AN1,f goto t3 decfsz AN2,f goto t3 decfsz AN3,f goto t3 return END

Saisir ce programme, le sauvegarder sous le nom clignoled.asm, le compiler, vérifier qu'il n'y a pas d'erreur, l'implanter sur un PIC®. Brancher comme le montre la figure ci-dessous, vérifier.

Microcontrôleur PIC16F887
5V

A.OUMNAD

42

1k

PIC Vdd MCLR Vss RA3 1k

LED

Figure IV-2 : PIC® commandant une LED

Vous avez sans doute remarqué qu'il n'est pas très commode de saisir la fonction tempo3 à la fin du programme chaque fois qu'on en a besoin. Nous allons placer toutes les fonctions couramment utilisées dans un fichier mesfonctions.inc qu'il suffira d'inclure après le programme principal juste avant la directive END Plus tard, chaque fois que nous écrirons de nouvelles fonctions susceptibles d'être réutilisées, nous les ajouterons au fichier mesfonctions.inc. Un listing de ce fichier est présenté en fin de document. L'extension (.inc) choisie pour les fichiers à inclure n'est pas obligatoire. Les extensions (.asm) ou (.txt) conviennent parfaitement Ce programme eut être légèrement simplifié. Au lieu d'allumer la LED, attendre, éteindre la LED, attendre, on peut faire: changer l'état de la LED, attendre. Pour cela, on utilise la propriété d'inversion de l'opérateur XOR: X ⨁ 1 Exercice 10) LED-xor.asm Donner la version du programme qui utilise l'opérateur XOR pour changer l'état de la LED Exercice 11) Dans les deux programmes précédents, supprimer l'instruction
bcf ANSEL,ANS3 ; RA3 numérique

Le premier programme continue à fonctionner mais pas le deuxième. Expliquer pourquoi

IV.7.2 Commande d'un relai
Le programme qui nous a permis de faire clignoter la LED peut très bien servir à faire clignoter une lampe alimentée par le secteur ou tout autre type de charge. Ce qui doit changer c'est l'électronique qui contrôle la charge. Le schéma ci-dessous illustre un exemple de commande par l'intermédiaire d'un relai. Il est à utiliser avec les charges qui nécessitent une tension ou un courant d'alimentation important. La tension Vrelai dépend du relai, ça peut être 5V, 12V ou 24V. La diode de récupération est obligatoire, sans elle, le transistor serait détruit au premier fonctionnement. La valeur de la résistance R dépend de la tension d'alimentation du relai, de sa résistance statique et du gain du transistor. On peut utiliser la formule ci-dessous ou faire quelques essais. Il ne faut pas qu'elle soit trop faible pour éviter que la sortie du PIC® ne fournisse un courant trop important. Une sortie du PIC® peut fournir jusqu'à 25 mA et le courant fournit par toutes les sorties réunies ne doit pas dépasser 90mA.

Microcontrôleur PIC16F887

A.OUMNAD
Vrelai Vdd=5V

43

1k

PIC Vdd MCLR Vss RA3 R=4.7k

Relai

Lampe

2N2222

Figure IV-3 : commande d'un relai

Exercice 12)(patern.asm) Avec Fosc = 8Mhz, donner le Programme qui utilise les instructions bsf, bcf et nop pour générer le signal suivant sur la sortie RB0. La largeur minimale d'une impulsion est 0.5µs

Exercice 13) (scrutation.asm) Programme qui surveille l'état de l'entrée RA1 à l'aide de l'instruction btfsc ou btfss : - Si RA1 = 0  faire RA3 = 1, PORTB = 00001111 - Si RA1 = 1  faire RA3 = 0, PORTB = 11110000 Exercice 14) (print.asm) Transférer le contenu de la mémoire EEPROM de données sur PORTB. Pour chaque octet, on utilisera le protocole suivant: o Copier un octet sur PORTB o Générer une impulsion négative (STROBE) de largeur 2µs sur RA0 o Attendre une impulsion négative (ACK) de largeur inconnue sur RA1 Exercice 15) Compteur d’impulsions 8 bits Programme qui : – Allume la LED branchée sur RB3 – Compte 150 impulsions ⎍ sur l'entrée RA4 (la case mémoire 70h servira de compteur) – Eteint la LED branchée sur RB3

Microcontrôleur PIC16F887

A.OUMNAD

44

IV.8

Commande d'un afficheur sept segments
f

a b g e d c

Un afficheur 7 segments est constitué de 7 LEDs organisées comme indiqué sur la figure ci-contre. Les segments sont appelés a, b, c, d, e, f et g. Pour minimiser le nombre de broches de l'afficheur, les anodes ou les cathodes sont reliées à intérieure de l'afficheur. On parle alors d'afficheur anode commune (AC) ou d'afficheur cathode commune (CC)

a b c

d e

f

g

AC

CC

a b c

d e

f

g

Cathode Commune

Anode commune

Figure IV-4 : organisation interne des afficheurs sept segments

Pour piloter un afficheur sept segments, on a besoin d'un décodeur bcd-sept segments pour convertir le code bcd du chiffre à afficher en une combinaison de 7 bits pour piloter les sept entrées a, b, c, d, e, f, et g de l'afficheur. Pour un afficheur cathode commune (figure ci-dessous), si on veut afficher le chiffre 4, le décodeur doit convertir le code bcd de 4 (DCBA = 0100) en code 7 segment (gfedcba = 1100110) pour allumer les segments b, c, f et g
b A Décodeur c B Bcd d C 7segments e D f a

g

g

f

e

d

c

b

a

CC
Figure IV-5 : pilotage d'un afficheur cathode commune

Pour un afficheur anode commune (figure ci-desso), la commande se fait par niveau bas, pour allumer un segment, il faut lui appliquer 0. Pour afficher le chiffre 4, le décodeur doit convertir le code bcd de 4 (DCBA = 0100) en code 7 segment (gfedcba = 0011001) pour allumer les segments b, c, f et g

Microcontrôleur PIC16F887

A.OUMNAD
Vcc

45

a b c d

e

f

g

A B C D

a b Décodeur c Bcd d 7segments e f g
Figure IV-6: pilotage d'un afficheur anode commune

Avec le PIC®, on n'a pas besoin de décodeur bcd 7 segments. Le décodage peut se faire par programme. On va écrire un programme qui pilote un afficheur anode commune par l'intermédiaire du port C. Dec g f e d c b a 5V 0 1 0 0 0 0 0 0 40h AC 1 1 1 1 1 0 0 1 79h a 2 0 1 0 0 1 0 0 24h RC0 a b 3 0 1 1 0 0 0 0 30h RC1 b f 4 0 0 1 1 0 0 1 19h c RC2 5 0 0 1 0 0 1 0 12h d g PIC RC3 6 0 0 0 0 0 1 0 02h e 7 1 1 1 1 0 0 0 78h RC4 e c 8 0 0 0 0 0 0 0 00h f RC5 9 0 0 1 0 0 0 0 10h d g RC6 A 0 0 0 1 0 0 0 08h Figure IV-7: pilotage d'un afficheur AC par un PIC b 0 0 0 0 0 1 1 03h C 1 0 0 0 1 1 0 46h Le plus important est de réaliser la fonction décodage. Le tableau d 0 1 0 0 0 0 1 21h ci-dessous montre, pour chaque chiffre hexadécimal, le code 7 E 0 0 0 0 1 1 0 06h segments qu'il faut appliquer à l'afficheur. Pour afficher le chiffre F 0 0 0 1 1 1 0 0Eh 2, il faut envoyer 00100100 = 24h sur PORTC. Le bit de plus fort poids de PORTC n'est pas utilisé, on va le considérer toujours égal à 0. On aurait pu l'utiliser pour commander le segment p (point) disponible sur certains afficheurs. La fonction ci-dessous permet de faire le transcodage entre le code bcd d'un chiffre et son code 7 segments. Son utilisation est simple, on place un chiffre dans W, on appelle la fonction qui retourne le code 7 segment dans W. La fonction utilise le principe du goto calculé qui consiste à changer la valeur du compteur programme PCL. On va juste rappeler que quand le PIC® est en train d'exécuter une instruction, PCL contient (pointe) l'adresse de la ligne suivante. Quand le PIC® termine une instruction, il va exécuter l'instruction pointée par PCL et ce dernier s'incrémente automatiquement. D'où le nom de compteur programme. Si on appelle cette fonction avec W=4, Le PIC® commence à exécuter l'instruction, addwf PCL,f et PCL pointe sur la ligne suivante retlw 40h. Or, l'instruction addwf PCL,f demande au PIC® de rajouter le contenu de W à celui de PCL. Comme W=4, cela revient à dire au PCL d'aller pointer 4 lignes plus loin, c.à.d. sur l'instruction retlw 19h. Quand le PIC® termine l'instruction en cours, il se branche

Microcontrôleur PIC16F887

A.OUMNAD

46

directement à l'instruction retlw 19h qui lui dit de retourner au programme appelant en ramenant la valeur 19h dans W. Il se trouve que 19h est le code 7 segments du chiffre 4
Bcd7seg: Addwf retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw PCL,f 40h 79h 24h 30h 19h 12h 02h 78h 00h 10h 08h 03h 46h 21h 06h 0Eh ; ajouter le contenu de W au Compteur programme

Pour l'écriture de la fonction, on peut utiliser la directive DT qui permet de générer une suite d'instructions retlw. La fonction devient:
Bcd7seg: Addwf DT PCL,f ; ajouter le contenu de W au Compteur programme 40h,79h,24h,30h,19h,12h,02h,78h,00h,10h,08h,03h,46h,21h,06h,0Eh

Exercice 16)aff7seg.asm Programme qui affiche un compteur modulo 16 (de 0 à F) sur l'afficheur 7 segments avec une temporisation voisine d'une seconde Exercice 17)(aff7seg-dec.asm) Modifier le programme aff7seg.asm pour obtenir un compteur modulo 10
LM016L

IV.9

Commande d'un afficheur LCD

VSS VDD VEE

RS RW E 4 5 6

 Le mode 8 bits utilise tous les bits du port. Les données sont échangées avec l'afficheur octet par octet.

1 2 3

 Le mode 4 bits utilise seulement les 4 bits de poids fort D7 D6 D5 D4, les autres ne sont pas branchés. Les données sont échangées ½ octet par ½ octet, en commençant par le plus fort poids.  Une donnée envoyée vers l'afficheur peut être soit un caractère à afficher soit une commande à interpréter (effacer écran, changer de ligne …). Pour faire la différence entre les deux, on utilise la broche RS: o RS = 0 => la donnée envoyée est une commande o RS = 1 => la donnée envoyée est un caractère à afficher

7 8 9 10 11 12 13 14

D0 D1 D2 D3 D4 D5 D6 D7

L'afficheur LCD deux lignes le plus courant dispose d'un port de 8 bits D7 D6 D5 D4 D3 D2 D1 D0, Il a deux modes de fonctionnement:

Microcontrôleur PIC16F887

A.OUMNAD

47

 Pour envoyer un octet (ou ½ octet) vers l'afficheur, il faut le placer sur le port de données, positionner la broche RS pour préciser s'il s'agit d'une commande ou d'un caractère à afficher. Ensuite il faut envoyer une impulsion positive ⎍ d'au moins 450 ns sur la broche E.  A la mise sous tension, Le LCD démarre en mode 8 bits. Même si seulement 4 bits sont branchés, les première commande sont envoyé en mode 8 bits où seuls les 4 bits de poids fort comptent.  Avant d'utiliser l'afficheur il faut l'initialiser en lui en voyant quelques commandes. C'est l'étape la plus délicate. Ensuite l'utilisation est très simple  L'afficheur 2 lignes dispose d'une mémoire d'affichage (DD RAM) de 80 caractères organisé en deus lignes. La fenêtre d'affichage ne peut afficher que 16 caractère de chaque ligne. On peut utiliser la commande Cursor or display shift pour déplacer l'affichage à gauche ce qui revient à déplacer la fenêtre à droite. Les adresse du premier caractère de chaque lignes son respectivement 0 et 64. Pour les afficheurs quatre lignes les adresses du premier caractère de chaque ligne sont 0, 64, 20 et 84.

IV.9.1 Initialisation de l'afficheur en mode 8 bits
Toutes les commandes doivent être envoyées avec RS=1  Mise sous tension  Mettre le port à 00000000 et attendre un délai de 15ms pour donner le temps à l'afficheur de booter  Envoyer trois fois de suite la commande Function Set, pour demander le mode 8 bits en n'utilisant que les 4 bits de poids fort. Chaque commande sera suivie d'un délai de 4.1 ms.  0011xxxx (30h) → E=⎍→ 4.1 ms  0011xxxx (30h) → E=⎍→ 4.1 ms  0011xxxx (30h) → E=⎍→ 4.1 ms  Maintenant on est en mode 8 bits, en va utiliser de nouveau la commande Function Set, mais cette fois sur 8 bits pour demander : Mode 8bits, afficheur deux lignes, fonte 5×7  0011 1000(38) → E=⎍→ 40µs  On envoie la commande Display ON/OFF. On va mettre Display:ON, vous avez le choix pour le Curseur et le clignotement  0000 1100(0Ch) → E=⎍→ 40µs  Envoyer la commande Entry mode set : Ecriture de gauche à droite, le curseur se déplace vers la droite après l'affichage d'un caractère  0000 0110(06h) → E=⎍→ 40µs  Envoyer la commande Clear Screen.  0000 0001(01h) → E=⎍→ 1.64ms

IV.9.2 Initialisation de l'afficheur en mode 4 bits
Même si 4 bits seulement sont connectés, l'afficheur démarre en mode 8 bits. Donc là aussi on va envoyer trois fois la commande 3h sur les 4 bits supérieurs pour s'assurer qu'il est en mode 8 bits.  Mise sous tension  Mettre le port à 0000---- et attendre un délai de 15ms pour donner le temps à l'afficheur de booter

Microcontrôleur PIC16F887

A.OUMNAD

48

 Envoyer trois fois de suite la commande Function Set, pour demander le mode 8 bits en n'utilisant que les 4 bits de poids fort. Chaque commande sera suivie d'un délai de 4.1 ms.  0011---- (3h) → E=⎍→ 4.1 ms  0011---- (3h) → E=⎍→ 4.1 ms  0011---- (3h) → E=⎍→ 4.1 ms  Maintenant on va utiliser la commande Function Set, mais pour demander le mode 4 bits  0010 ----(2h) → E=⎍→ 40µs  A partir d'ici on est en mode 4 bits. Chaque commande doit être envoyée en deux phases. On envoie le ½ octet de poids fort, on valide par une impulsion ⎍ sur E, on envoie le ½ octet de poids faible, on valide par une impulsion ⎍ sur E, on attend le délai nécessaire  On envoie la commande Function Set : Mode 4bits, afficheur deux lignes, fonte 5×7: 0010 1000(38)  0010 → E=⎍  1000 → E=⎍ → 40µs  On envoie la commande Display ON/OFF. (Display: ON, Cursor: votre choix, Blink: votre choix)  Soit la commande 0000 1100(0Ch)  0000 → E=⎍  1100 → E=⎍ → 40µs  Envoyer la commande Entry mode set : Ecriture de gauche à droite, le curseur se déplace vers la droite après l'affichage d'un caractère : 0000 0110(06h)  0000 → E=⎍  0110 → E=⎍ → 40µs  Envoyer la commande Clear Screen : 0000 0001(01h)  0000 → E=⎍  0001 → E=⎍ → 1.64ms
Commande Clear Screen Return home Entry mode set D7 D6 D5 D4 D3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 D2 D1 D0 0 0 1 0 1 I/D 1 X S Description Efface écran, curseur début première ligne Curseur en début de première ligne Sens de l'affichage I/D=1→ gauche à droite, I/D=0 → droite { gauche S=0→ curseur se déplace, S=1→ texte se déplace D: affichage ON/OFF, C: curseur ON/OFF, B: clignotement ON/OFF Décale le curseur ou tout l'affichage à droite ou à gauche S/C=0→ décaler curseur, S/C=1→ décaler affichage R/L=0→ vers la gauche, R/L=1 vers la droite Définit taille de l'interface, de l'afficheur est des caractères DL=0→ mode 4 bits, DL=1→ mode 8 bits N=0→ afficheur 1 ligne, N=1→ afficheur 2 ou 4 lignes F=0→ fonte 5x 7, F=1→fonte 5x 10. Délai 1,64ms 1,64ms 40 µs

Display on/off Cursor or display shift

0 0

0 0

0 0

0 1

1

D

C X

B X

40 µs 40 µs

S/C R/L

Function set

0

0

1

DL

N

F

X

X

40 µs

Set CG address Set DD address

RAM RAM

0 1

1

A5 A4 A3

A2 A2 A2

A1 A0 A1 A0 A1 A0

Définit la position courante dans la CG RAM qui peut servir à 40 µs la création de nouveaux caractères Définit la position courante dans la mémoire d'affichage DD 40 µs RAM. L'adresse de première position de la 2ème ligne est 64 Lit le drapeau BF et l'dresse courante (position curseur) BF=0→ afficheur prêt, BF=1→afficheur occupé 1 µs

A6 A5 A4 A3

Read Busy Flag & BF A6 A5 A4 A3 address

Tableau IV-1: Commandes de l'afficheur LCD

Microcontrôleur PIC16F887

A.OUMNAD

49

IV.9.3 Exemple de branchement
Nous avons l'embarras du choix pour commander un afficheur LCD au PIC16F887. L'exemple cidessous est celui adopté sur les cartes de développement EasyPIC5 et EasyPIC6. L'intérêt est que les programmes de test que nous allons écrire fonctionneront sur ces cartes. Le lecteur pourra aisément les adapter pour un autre branchement. La librairie mesfonctions.inc présentée en annexe contient quelques fonctions pour utiliser l'afficheur LCD : lcd_init: lcd_char: lcd_cmd: lcd_locate: lcd_clrscr : lcd_byte_d : lcd_word_d: Initialisation de l'afficheur. Doit être invoquée avant tout accès à l'afficheur Affiche le caractère présent dans W à la position du curseur Envoie l'octet de commande présent dans W Positionne le curseur à la position présente dans W Efface l'écran affiche l'octet présent dans W en décimal Affiche le word présent dans les variables AH, AL en décimal

LCD

R/W

E

RS

D7

D6

D5

D4 D3 D2 D1 D0

RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0

PIC16F887
Figure IV-8 : Commande d'un afficheur LCD en mode 4 bits

Exercice 18) LCD.asm Programme qui affiche la chaine PIC16F877 sur la première ligne et les nombres 200 et 2011 sur la 2ème ligne

Microcontrôleur PIC16F887

A.OUMNAD

50

Chapitre V LES MÉMOIRES PERMANENTES
Le PIC 16F887 dispose de 2 mémoires permanentes. La mémoire EEPROM PROGRAMME de capacité 8k mots de 14 bits et la mémoire EEPROM DE DONNÉES de capacité 256 octets. On dispose de deux méthodes pour écrire dans ces mémoires. La première consiste à flasher le PIC avec l'exécutable (.hex). Les instructions sont flashés dans la EEPROM programme et les donnée sont flashés dans la EEPROM de données. Le flashage se fait { l’aide d’un programmeur et le soft qui va avec. Voir les directive DE et ORG (II.7.8, page 26) et d’autres directives comme DA, DW … dans le manuel d’utilisation de MPASM. La deuxième méthode consiste à accéder aux mémoires EEPROM à partir du programme durant la phase d'exécution. C’est cette qui est détaillée dans les paragraphes suivants.

V.1

La mémoire EEPROM de données

Le PIC 16F887 dispose de 256 octets de mémoire EEPROM de donnée. Son implantation physique commence à l’adresse absolue 2100h. Mais pour y accéder à partir d'un programme, on utilise l’adressage relatif par rapport { la première position. La première position aura l’adresse 0, la deuxième aura l’adresse 1, et la dernière aura l’adresse 255. Pour accéder à la EEPROM de données, on utilise 4 registres particuliers :  EEADR : registre d’adresse (relative)  EEDAT : registre de donnée  EECON1 : registre de contrôle  EECON2 : 2ème registre de contrôle
r/w(x) U

(bank 2) (bank 2) (appelé aussi EEDATA) (bank 3) (bank 3)
U U r/w(x) r/w(0) r/s(0) r/s(0)

Le registre EECON1 :

EEPGD

WRERR

WREN

WR

RD

EEPGD : Accès à la mémoire EEPROM de données ou EEPROM Programme 0 : EEPROM de données 1 : EEPROM programme (flash) WRERR : Erreur d'écriture 0 : Pas d'erreur, l'écriture s'est terminée normalement 1 : Une erreur s'est produite, l'écriture s'est arrêtée prématurément WREN : Validation de l'écriture dans l'EEPROM 0 : Ecriture interdite 1 : Ecriture autorisée WR : Write Enable. Ce bit doit être mis à 1 pour démarrer l'écriture d'un octet. Il est remis à zéro automatiquement à la fin de l'écriture. Ce bit ne peut pas être mis à zéro par une instruction.

Microcontrôleur PIC16F887

A.OUMNAD

51

RD : Read Enable. Ce bit doit être mis à 1 pour démarrer la lecture d'un octet. Il est remis à zéro automatiquement à la fin de la lecture. Ce bit ne peut pas être mis à zéro par une instruction Remarque : Les bits WREN et WR ne peuvent être positionnés dans la même instruction. Le bit WR ne peut être positionné que si le bit WREN a été positionné avant.

V.2

Procédure de lecture dans la EEPROM

Pour lire le contenu d’une position de la mémoire EEPROM, on place l’adresse dans le registre EEADR, on lance l’opération de lecture { l’aide du bit RD du registre EECON1, la donnée désirée est tout de suite disponible dans le registre EEDAT :

1) Mettre le bit EEPGD à 0 pour pointer sur la EEPROM de donnée, 2) Placer l’adresse relative de la position { lire dans EEADR, 3) Mettre le bit RD à 1 pour démarrer la lecture. Ce bit revient à 0 automatiquement tout de suite
après le transfert de la donnée vers EEDAT, (moins d'un cycle),

4) Traiter la donnée disponible dans EEDAT, 5) Recommencer au point 2 si on a d'autres données à lire,

V.3

Procédure d'écriture dans la EEPROM

Pour écrire une donnée dans une position de la mémoire EEPROM, on place l’adresse dans le registre EEADR, la donnée dans le registre EEDAT, on lance l’opération d’écriture { l’aide du bit WR de EECON1 et du registre EECON2. La donnée présente dans EEDAT est alors copiée dans la EEPROM. Cette opération dure 10 ms. A la fin de l'écriture le bit WR revient à zéro automatiquement, le drapeau EEIF est levé ce qui peut déclencher l'interruption EEI si elle a été validée au préalable :

1) 2) 3) 4) 5)

Interdire les interruptions (si elles ont été validées avant : bit INTCON.GIE) Mettre le bit EEPGD à 0 pour pointer sur la EEPROM de donnée Positionner le bit WREN pour autoriser l'écriture dans la EEPROM de donnée Placer l’adresse relative de la position à écrire dans EEADR Placer la donnée à écrire dans le registre EEDAT

6) - Ecrire 55h dans EECON2 (commande de process hardwares) 7) - Ecrire AAh dans EECON2 (commandes de process hardwares) 8) - Positionner le bit WR pour démarrer l'opération d'écriture, 9) Attendre que WR revienne à 0 (≈ 10ms) 10) Recommencer au point (4) si on a d'autres données à écrire,
Les étapes 6, 7 et 8 doivent obligatoirement être exécutées dans cet ordre. L'ordre des étapes 1 à 5 n'a pas d'importance. A la fin de l'écriture de chaque octet, le drapeau d'interruption EEIF passe à 1. L'interruption EEI est déclenchée si elle a été validée au préalable par les bits GIE, PEIE et EEIE. Le drapeau EEIF doit être remis à 0 par programme. L'interruption EEI peut sortir le PIC® du mode sleep. Voir Erreur ! Source du renvoi introuvable., page Erreur ! Signet non défini. Exercice 19) Ecrire l'alphabet dans l'EEPROM de donnée à partir de la position 20h

Microcontrôleur PIC16F887

A.OUMNAD

52

Exercice 20)EEPROM vers la RAM Programme qui utilise la directive DE pour écrire la chaîne "BONJOUR CHER AMI" dans la EEPROM de données à partir de la position 2140h. Le programme doit ensuite lire les caractères de cette chaine à partir de la EEPROM et les copier dans la RAM à partir de la position 110h. Exercice 21) Chercher minimum dans la EEPROM Programme qui cherche la valeur minimale des 10 premières cases mémoire de la EEPROM et l'affiche sur l'afficheur LCD

V.4

La mémoire EEPROM Programme ou mémoire flash

Cette mémoire de 8 × 1024 mots de 14 bits sert à stocker le programme. Elle est aussi accessible par programme, elle peut donc être utilisée comme une extension de la mémoire EEPROM de données. Elle est non volatile et reprogrammable à souhait. Chaque position de 14 bits contient une instruction. L'emplacement du programme peut se situer à n'importe quel endroit de la mémoire. Cependant, il faut savoir que lors de la mise sous tension ou suite à un RESET, le PIC commence l'exécution à l'adresse 0000H. De plus, lorsqu'il y a une interruption, le PIC va à l'adresse 0004H. Il est donc nécessaire de bien organiser l’emplacement du programme principal, des programmes d’interruption et des données affin d’éviter tout chevauchement qui serait de toute évidence fatal au bon déroulement de l’application. L'accès à la mémoire flash durant la phase d'exécution se fait de la même façon que l'accès à la EEPROM de données, à l'exception des points suivant :  Le bit EEPGD doit être placé à 1  Le registre EEADR (8 bits) seul ne suffit pas à adresser les 8k de mémoire programme, on lui accole le registre EEADRH dans lequel il faut écrire la partie haute de l'adresse. On obtient ainsi les 13 bits nécessaires pour adresser 8k.  Le registre EEDAT (8 bits) seul ne suffit pas pour contenir les 14 bits contenus dans une position de la mémoire programme. On lui accole le registre EEDATH qui contiendra les 6 bits supérieurs.

 Il faut insérer deux instructions NOP dans les cycles de lecture/écriture. Pendant la phase d'écriture, le processeur arrête l'exécution des instructions. Il n'est donc pas nécessaire d'attendre la fin de l'écriture pour continuer car ceci se fait automatiquement, à la fin de l'écriture, l'exécution reprend à l'instruction qui suit le 2ème NOP,

V.5
1) 2) 3) 4) 5) 6)

Procédure de lecture dans la mémoire programme
Mettre le bit EEPGD à 1 pour pointer sur la mémoire programme Placer l’adresse de la position à lire dans EEADRH:EEADR Mettre le bit RD à 1 pour démarrer la lecture Exécuter deux instructions NOP Lire le contenu des registres EEDATH:EEDAT Recommencer au point 2) si on a d'autres données à lire

Remarques: a) Les nomenclatures EEADRH:EEADR et EEDATH:EEDAT sont des écritures papier, dans un programme, tous les registre font 8 bits et chaque registre doit être traité à part. Pour écrire l'adresse 1856h dans le doublet EEADRH:EEADR, il faut placer 18h dans EEADRH et 56h dans EEADR. Si l'adresse est exprimée en décimal, le mieux est d'utiliser les directive LOW et HIGH

Microcontrôleur PIC16F887

A.OUMNAD

53

pour isoler la partie basse et la partie haut. Par exemple, si on veut placer la valeur décimale 3579 dans le doublet EEDATH:EEDAT, il faut écrire:
movlw movwf movlw movwf LOW EEDAT HIGH EEDATH .3579 .3579

b) Quand on écrit séquentiellement dans la mémoire programme en incrémentant EEADR à chaque fois. Il faut faire attention car, au débordement de EEADR (255 0), EEADRH ne s'incrémente pas automatiquement. Il faut le faire soit même:
incfsz EEADR,f goto $+2 incf EEADRH,f ~~~~~~~~

V.6
1) 2) 3) 4) 5) 6) 7) 8) 9)

Procédure d'écriture dan la mémoire programme
Interdire les interruptions (si elles ont été validées auparavant), Mettre le bit EEPGD à 1 pour pointer sur la mémoire programme, Positionner le bit WREN pour valider l'écriture dans la mémoire programme, Placer l’adresse de la position { écrire dans EEADRH:EEADR, Placer la donnée à écrire dans le registre EEDATH:EEDAT, Ecrire 55h dans EECON2 (commande de process hardwares), Ecrire AAh dans EECON2 (commandes de process hardwares), Positionner le bit WR pour démarrer l'opération d'écriture, Exécuter 2 instructions NOP,

10) Recommencer au point 4 si on a d'autres données à écrire,

V.7

Mécanisme d'écriture dan la mémoire programme

La mémoire programme est organisée par blocs de 16 mots constitué chacun de deux blocs de 8 mots. Si on observe les bits de poids faible du registre d'adressage EEADR, on remarque: Un bloc de 16 mots commence toujours à 0000 et se termine à 1111, Un bloc de 8 mots commence toujours 000 et se termine à 111 Quand que nous écrivons un mot EEDATH:EEDAT dans la mémoire programme avec la procédure citée ci-dessus, il n'est pas flashé directement dans la mémoire permanente. Il est d'abord stocké dans une mémoire tampon de type RAM (buffer) qui a une capacité de 8 mots dont les adresses de 0 à 7 correspondent aux 3 bits les plus faibles du registre EEADR. C'est quand on écrit dans la 8ème position du buffer (EEADR=xxxxx111), que la totalité du buffer est flashée dans la mémoire programme. Quand-il s'agit de la première moitié du bloc de 16 mots, le processeur commence par effacer la totalité du bloc de 16 avant de flasher le contenu du buffer dans la première moitié du bloc. Quand il s'agit de la deuxième moitié, le processeur se contente de flasher car le bloc de 16 a déjà été effacé lors du flashage de sa première moitié.
EEADR

000 001 010 011 100 101 110 111 xxxx0000 xxxx0001 xxxx0010 xxxx0011 xxxx0100 xxxx0101 xxxx0110 xxxx0111 xxxx1000 xxxx1001 xxxx1010 xxxx1011 xxxx1100 xxxx1101 xxxx1110 xxxx1111 xxxx0000 xxxx0001 xxxx0010 xxxx0011 xxxx0100 xxxx0101 xxxx0110 xxxx0111 xxxx1000 xxxx1001 xxxx1010 xxxx1011 xxxx1100 xxxx1101 xxxx1110 xxxx1111

Buffer de 8 mots

Bloc de 8 mots Bloc de 8 mots

Bloc de 8 mots Bloc de 8 mots

Microcontrôleur PIC16F887

A.OUMNAD

54

Effacer la mémoire programme revient à mettre tout les bits à 1. Flasher le buffer dans un bloc de 8 mot ne signifie pas le copier, en fait le processeur fait un ET bit par bit entre le buffer et le bloc de 8 mots. C'est pour cette raison que l'effacement préalable et obligatoire. Si on commence par écrire dans la deuxième moitié d'un bloc de 16 qui n'a pas encore été effacé, on obtient un ET entre ce qu'on a écrit et ce qu'il y avait avant. Chaque fois que le buffer de 8 mots est flashé dans la mémoire programme, le drapeau d'interruption EEIF passe à 1. L'interruption EEI se déclenche si elle a été validée au préalable par les bits GIE, PEIE et EEIE. Le drapeau EEIF doit être remis à 0 par programme. L'interruption EEI peut sortir le PIC® du mode sleep. Voir § Erreur ! Source du renvoi introuvable., page Erreur ! Signet non défini.. La tâche d'effacement d'un bloc de 16 se prolonge pendant 4ms durant lesquelles le processeur arrête d'exécuter le programme. A la fin, l'exécution reprend normalement à l'instruction qui suit le 2ème NOP.  Si on écrit 8 mots M1, M2 …M8 à partir du début d'un bloc de 16, EEADR=xxxx0000. Au moment où l'on écrit le mot M8 dans la position EEADR=xxxx 0111, tous le bloc de 16 est effacée, ensuite les 8 mots seront flashés dans le premier bloc de 8. Le deuxième bloc de 8 reste vide.  Si on commence à écrire dans la deuxième moitié d'un bloc de 16 sans toucher la première moitié. Au moment de l'écriture dans la dernière position EEADR=xxxx1111, le buffer est flashé sans que bloc ne soit effacé. Le résultat obtenu correspond à un ET entre ce qu'on a écrit et ce qu'il y avait dans le bloc avant.  Si on écrit un ou plusieurs mots sans toucher la position EEADRH:EEADR=xxxxxxxx xxxxx111 correspondant au 8ème mot du buffer, rien ne se passe, les mots resteront dans le buffer. La mémoire programme n'est pas modifiée.  Si on écrit un seul mot M dans dernière position du premier bloc. EEADR=xxxx0111, le bloc de 16 mots sera effacée et le buffer de 8 mots sera flashé. On se retrouve avec un bloc de 16 qui contient 7 mots indéterminés suivis du mot M suivi 8 mots 3FFFh (effacés)  Si par exemple on écrit l'alphabet (1 caractère par position) à partir de la position 1020h. Les caractères de A à H seront écrits dans le bloc [ 1020h, 1027h]. Les caractères de I à P seront écrits dans le bloc [1028h, 102Fh]. Les caractères de Q à X seront écrits dans le bloc [ 1030h, 1037h]. les caractères Y et Z ne seront pas écrit dans la mémoire programme, car le programme s'arrête après l'écriture de Z dans la position 001 du buffer. Le buffer ne sera pas flashé car il faut écrire dans la position 7=111 pour déclencher le flashage. Pour y remédier, le plus simple et d'écrire 32 caractères quiet à ignorer les 6 caractères qui suivent le Z Exercice 22) alphabet_2memprog.asm Ecrire l'alphabet dans la mémoire programme à partir de la position 1020h Exercice 23) memprog2ram.asm Programme qui lit 20 positions de la mémoire programme débutant à la position 12FAh et les copie dans la RAM à partir de la position 110h. Attention :  Le contenu d’une position mémoire programme permet de remplir 2 positions de la RAM.  Le débordement de EEADR n’affecte pas EEADRH

Microcontrôleur PIC16F887

A.OUMNAD

55

Chapitre VI LES INTERRUPTIONS
Une interruption est un événement qui provoque l’arrêt du programme principal pour aller exécuter une procédure d'interruption. A la fin de cette procédure, le microcontrôleur reprend le programme principal { l’endroit où il l’a laissé. A chaque interruption sont associés deux bits, un bit de validation et un drapeau. Le premier permet d'autoriser ou non l'interruption, le second permet au programme de savoir de quelle interruption il s'agit. Sur le 16F887, l'es interruptions sont classées en deux catégories, les interruptions primaires et les interruptions périphériques. Elles sont gérées par les registres :
INTCON PIE1 (bank1) PIR1 (bank0) PIE2 (bank1) PIR2 (bank0) IOCB (bank1) OPTION_REG(bk1) GIE OSFIE OSFIF IOCB7 PEIE ADIE ADIF C2IE C2IF IOCB6 INTEDG T0IE RCIE RCIF C1IE C1IF IOCB5 INTE TXIE TXIF EEIE EEIF IOCB4 RBIE SSPIE SSPIF BCLIE BCLIF IOCB3 T0IF CCP1IE CCP1IF ULPWUIE ULPWUIF IOCB2 INTF TMR2IE TMR2IF IOCB1 RBIF TMR1IE TMR1IF CCP2IE CCP2IF IOCB0

 Toutes les interruptions peuvent être validées/interdites par le bit INTCON,GIE  Toutes les interruptions périphériques peuvent être validées/interdites par le bit INTCON,PEIE  Chaque interruption peut être validée/interdite par son bit de validation individuel En résumé, pour valider une interruption périphérique (par exemple), il faut positionner 3 bits, GIE, PEIE et le bit individuel de l’interruption.

VI.1

Déroulement d'une interruption

Lorsque l'événement déclencheur d'une interruption intervient, alors son drapeau passe à 1 (levé). Si l'interruption a été validée au préalable (bits de validations = 1), elle est alors déclenchée: Le programme arrête ce qu'il est en train de faire et va exécuter la procédure d'interruption qui se trouve à l'adresse 4. Le déroulement se fait comme suit:  Le processeur termine l'instruction qu'il est en train d'exécuter,  Le bit GIE est placé "0" pour inhiber toutes les interruptions (afin que le PIC ne soit pas dérangé pendant l'exécution de la procédure d'interruption).  l'adresse contenue dans le PC (Program Counter) est sauvegardée dans la pile, puis remplacée par la valeur 0004 (adresse de la routine d'interruption).  Le processeur exécute la routine d'interruption.  A la fin de la procédure d'interruption (instruction RETFIE), le bit GIE est remis à 1 (autorisant ainsi un autre événement). Le contenu du PC est rechargé à partir de la pile ce qui permet au programme de reprendre là où il s'est arrêté Deux remarques importantes sont à faire :

Microcontrôleur PIC16F887

A.OUMNAD

56

Le drapeau reste { l’état haut même après le traitement de l’interruption. Par conséquent, il faut toujours le remettre à "0" à la fin de la routine d'interruption sinon l'interruption sera déclenchée de nouveau juste après l'instruction RETFIE Seul le PC est empilé automatiquement. Si cela est nécessaire, les registres W et STATUS doivent être sauvegardés en RAM puis restaurés à la fin de la routine pour que le microcontrôleur puisse reprendre le programme principal dans les mêmes conditions où il l'a laissé.

VI.2

Les sources d'interruption
Sources d’interruption Transition sur l’entrée RB0/INT Transition sur une entrée du PORTB. (Interrupt On change on PORTB) Débordement du Timer TMR0 Fin de conversion A/N Changement à la sortie des comparateurs analogiques Détection d’une défaillance sur un élément externe de l’horloge (Fail-Safe Clock Monitor Interrupt) Un Octet est reçu sur l'USART Fin transmission d'un octet sur l'USART Débordement de Timer TMR1 Timer TMR2 a atteint la valeur programmée Capture/comparaison de TMR1 avec module CCP1 Capture/comparaison de TMR1 avec module CCP2 Fin d'écriture en EEPROM Collision sur bus SSP en mode I2C Sorties périodiques du mode sleep (Ultra Low-Power Wake-up interrupt) Validation individuelle INTE IOCBx T0IE ADIE CxIE OSFIE RCIE TXIE TMR1IE TMR2IE CCP1IE CCP2IE EEIE BCLIE ULPWUIE Validation Globale GIE GIE RBIE GIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE GIE PEIE Drapeau INTF RBIF T0IF ADIF CxIF OSFIF RCIF TXIF TMR1IF TMR2IF CCP1IF CCP2IF EEIF BCLIF ULPWUIF

VI.3

L'interruption INT (Entrée RB0 de PORTB)

Cette interruption est provoquée par un changement d'état sur l'entrée RB0 de PORTB. Celle-ci doit être programmée en entrée. En plus de son bit de validation INTE et son drapeau INTF, elle est gérée aussi par le bit INTEDG (OPTION_REG) qui détermine le front sur lequel l'interruption se déclenche, 1=montant, 0=descendant. Cette interruption peut sortir le PIC du mode sleep si le bit INTE a été positionné au préalable.

VI.4

L'interruption IOCB

Cette interruption est provoquée par un changement d'état sur n’importe laquelle des entrées de PORTB. Le front n'a pas d'importance. Elle doit être validée (globalement) par les bits GIE et RBIE, et individuellement (pour chaque entrée de PORTB) par les bits du registre IOCB (bank1) : IOCBx = 0 ⇒ interruption IOCB inhibée sur l’entrée RBx IOCBx = 1 ⇒ interruption IOCB validée sur l’entrée RBx

Microcontrôleur PIC16F887

A.OUMNAD

57

Attension: Le drapeau RBIF ne peut être remis à zéro sans la lecture préalable de PORTB (MOVF PORTB,w). Si on ne veut pas modifier le contenu de W, on peut copier PORTB sur lui-même (MOVF PORTB,f).

VI.5

Les autres interruptions

Les autres interruptions seront abordées au moment de l'étude des modules qui les déclenchent. Exercice 24) Int.asm Chaque fois qu'une transition 10 apparait sur l'entrée RB0, la LED branchée sur la sortie RB1 clignote 5 fois au rythme de la ½ seconde. PIC
RB0 RB1 1k

LED

Figure VI-1:

Exercice 25) Div-freq.asm Programme qui réalise une division de fréquence par une valeur DIV qui sera lue sur PORTD. Le signal d'entrée est appliqué sur l'entrée RB0. Le signal de sortie est généré sur la sortie RB1. On utilisera l'interruption IOCB pour détecter les transitions du signal d'entrée.

PIC
RB0 PORTD RB1

DIV Figure VI-2: diviseur de fréquence

L'algorithme est simple. On compte les transitions du signal d'entrée. Chaque fois qu'on a compté DIV transitions, on change l'état du signal de sortie.

Figure VI-3: division de fréquence par 3

Exercice 26) Diviseur de fréquence 16 bits Refaire le programme mais cette fois avec la possibilité d'avoir DIV supérieur à 255. Le compteur 16 bits sera lu sur les ports PORTC et PORTD PIC
RB0 PORTD RB1 PORTC

DIV

Microcontrôleur PIC16F887

A.OUMNAD

58

Chapitre VII LES TIMERS
VII.1 Le Timer TMR0
C’est un compteur 8 bits ayant les caractéristiques suivantes :  Il est incrémenté en permanence soit par l’horloge interne Fosc/ 4 (mode timer) soit par une horloge externe appliquée à la broche RA4 du port A (mode compteur). Le choix de l'horloge se fait à l'aide du bit T0CS du registre OPTION_REG o T0CS = 0  horloge interne o T0CS = 1  horloge externe appliquée à RA4  Dans le cas de l'horloge externe, Le bit T0SE du registre OPTION_REG permet de choisir le front sur lequel le TIMER s'incrémente. PS2 PS1 PS0 Div o T0SE = 0  incrémentation sur fronts montants 0 0 0 2 o T0SE = 1  incrémentation sur fronts descendants 0 0 1 4 0 1 0 8  Quelque soit l'horloge choisie, on peut la passer dans un diviseur de 0 1 1 16 fréquence programmable (prescaler) dont le rapport DIV est fixés par les bits PS0, PS1 et PS2 du registre OPTION_REG (tableau ci-contre). 1 0 0 32 L'affectation ou non du prédiviseur se fait à l'aide du bit PSA du registre 1 0 1 64 OPTION_REG 1 1 0 128 1 1 1 256 o PSA = 0  on utilise le prédiviseur o PSA = 1  pas de prédiviseur (affecté au chien de garde)  Le contenu du timer TMR0 est accessible par le registre qui porte le même nom. Il peut être lu ou écrit à n'importe quel moment. Après une écriture, le timer ne s’incrémente pas pendant deux cycles machine.  Au débordement de TMR0 (FFh  00h), le drapeau INTCON,T0IF passe à 1. Ceci peut déclencher l'interruption T0I si celle-ci a été validée par les bits INTCON,GIE et INTCON,T0IE OPTION_REG
T0SE RA4
0 1

RBPU
T0CS
1 0

INTEDG

T0CS

T0SE

PSA

PS2

PS1

PS0

TH

PSA
1 Prédiviseur programmable 0

TF0 T0 TMR0 T0IF

Générateur D’horloge Fosc

÷4

Fosc/4
PS2 PS1 PS0

TF0 = 256 x (DIV x TH)

Figure VII-1 : Schéma bloc du timer TMR0

Microcontrôleur PIC16F887

A.OUMNAD

59

En résumé, chaque fois que le compteur complète un tour, le drapeau T0IF se lève. Si on note TH la période de l'horloge source, T0 l'horloge de TMR0 et TF0 le temps qui sépare 2 levés de drapeau successifs :  Sans prédiviseur : TF0 = 256 × T0 = 256 × TH  Avec prédiviseur : TF0 = 256 × T0 = 256 × (DIV × TH)  Si on rajoute une variable de comptage CTR dans le programme les levés de drapeau on obtient : T = CTR × TF0 = CTR × 256 × (DIV ×TH)

VII.1.1 Programmes types: Clignoter LED, scrutation du drapeau T0IF
Le programme ci-dessous fait clignoter une LED branchée sur la broche RB0. Le temps d'allumage/extinction de l'ordre de 0,5 secondes est obtenu grâce au timer TMR0. Avec Fosc = 8 MHz, TH = Tosc = 0,5µs. Il faut chercher un couple (CTR, DIV) qui vérifie: CTR × 256 × DIV × 0,5 µs = 500 000µs. CTR peu prendre toutes les valeurs entre 1 et 256. DIV peut prendre les valeurs 2, 4, 8, 16, 32, 64, 128 ou 256. Il n'y a pas de solutions exactes. Les couple (CTR, DIV) qui donne le meilleur résultat sont ( 244, 16) (122, 32) et (61, 64). Avec ses valeurs on obtient une temporisation de 0,4997 s Dans cette première version du programme, on détecte le débordement de TMR0 en scrutant le drapeau T0IF à l'aide de l'instruction btffs.
LED-TMR0-scrut.asm ;======================================================================= ; Programme qui fait clignoter une LED branchée sur RB0 avec une temporisation voisine ; de 0.5s obtenue par scrutation du drapeau T0IF. Fosc = 8 MHz => Tcy = 0.5µs ; 500 000 µs = CTR × DIV × 256 × 0.5µs => CTR = 122, DIV = 32 ;====================================================================== ERRORLEVEL -302 ; pour masquer les messages de compilation INCLUDE p16f887.inc INCLUDE mesmacros.inc LIST p=16f887, r=dec __CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF CTR equ BANK1 movlw movwf bcf bcf movlw movwf BANK0 movlw movwf btfss goto bcf decfsz goto movlw xorwf goto END 70h 0x71 OSCCON TRISB,0 INTCON,GIE B'00000100' OPTION_REG

; Oscillateur interne, Fosc=8MHz ; RB0 en sortie ; interdire les interruption ; TOCS=0, PSA=0, div=32

debut: 122 CTR INTCON,T0IF $-1 INTCON,T0IF CTR,f ici B'00000001' PORTB,f debut ; CTR = 122 ; attendre drapeau de débordement de TMR0 ; baisser le drapeau ; compter le nombre de débordement ; le compte n'y est pas ; masque de RB0 ; inverser RB0 ; recommencer

ici:

Microcontrôleur PIC16F887

A.OUMNAD

60

VII.1.2 Programme type: Clignoter LED, interruption de TMR0
Dans cette deuxième version du programme, on détecte le débordement de TMR0 grâce à l'interruption T0I

LED-TMR0-int.asm ;======================================================================= ; Programme qui fait clignoter une LED branchée sur RB0 avec une temporisation voisine ; de 0.5s obtenue par l'interruption de TMR0. Fosc = 8 MHz => Tcy = 0.5µs ; 500 000 µs = CTR × DIV × 256 × 0.5µs => CTR = 61, DIV = 64 ;====================================================================== ERRORLEVEL -302 ; pour masquer les messages de compilation INCLUDE p16f887.inc INCLUDE mesmacros.inc LIST p=16f887, r=dec __CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF CTR equ 0x70 org goto 0 main ; à la mise sous tension, ou au RESET ; aller au programme principal

; ============= sous programme d'interruption ======================= org 4 bcf INTCON,T0IF ; baisser le drapeau decfsz CTR,f ; compter le nombre de débordement retfie ; le compte n'y est pas movlw 1 ; masque de RB0 xorwf PORTB,f ; inverser RB0 movlw 61 ; CTR = 61 movwf CTR retfie ;==== Programma principal ============ main: BANK1 movlw 0x71 movwf OSCCON ; Oscillateur interne, Fosc=8MHz bcf TRISB,0 ; RB0=LED en sortie movlw B'00000101' movwf OPTION_REG ; TOCS=0, PSA=0, div=64 BANK0 bcf PORTB,0 ; LED éteinte au départ movlw 61 movwf CTR ; CTR = 61 bsf INTCON,GIE ; valider interruptions bsf INTCON,T0IE ; valider interruption T0I goto $ ; rester planté ici à attendre l'interruption END

Microcontrôleur PIC16F887

A.OUMNAD

61

VII.2 Le Timer TMR2

Figure VII-2 : fonctionnement du timer TMR2 (source : Microchip DS41291F)

TMR2 est un timer 8 bits accessible en lecture écriture par l'intermédiaire du registre qui porte le même nom. Il est constitué de :  Un compteur 8 bits TMR2,  Un registre de contrôle T2CON (bank0),  Un diviseur de fréquence programmable PRESCALER dont le rapport de division PREDIV peut prendre une des valeurs 1, 4 ou 16  un registre de période PR2 (bank1) accessible en lecture/écriture  un comparateur qui compare le contenu de TMR2 avec celui de PR2  un deuxième diviseur de fréquence POSTSCALER dont le rapport de division POSTDIV peut prendre toutes les valeurs comprises entre 1 et 16. Fonctionnement:  TMR2 est incrémenté par l'horloge interne Fosc/4 éventuellement prédivisée par le PRESCALER. Quant il atteint la valeur du registre PR2, au coup d'horloge suivant, le comparateur génère un signal qui : o Remet TMR2 à 0, o incrémente le diviseur de fréquence POSTSCALER,  Le comptage commence à 0 et se termine à PR2. Le comparateur annonce une égalité tous les PR2+1 coups d’horloge,  Au débordement du POSTSCALER, le drapeau TMR2IF est positionné, l'interruption correspondante et déclenchée si elle est validée,  TMR2 est remis à zéro à chaque RESET,  Le PRESCALER et le POSTSCALER qui sont aussi des compteurs sont réinitialisés à chaque écriture dans TMR2 ou dans T2CON et au RESET du processeur  La configuration de TMR2 se fait à l'aide du registre de contrôle T2CON :

VII.2.1 Cycle de comptage
La périodicité du drapeau TMR2IF est donnée par : TF2 = PREDIV × (PR2+1) × POSTDIV × Tcy .

Microcontrôleur PIC16F887

A.OUMNAD

62

VII.2.2 Le registre T2CON:
— TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0

TOUTPS3:TOUTPS0 : rapport du POSTSCALER 0000 : division par 1 0001 : division par 2 ... 1111 : division par 16 TMR2ON : démarrer arrêter TMR2 0 : TMR2 off 1 : TMR2 on T2CKPS1,T2CKPS0 : rapport du PRESCALER 00 : division par 1 01 : division par 4 1x : division par 16 Remarque : Dans le cas de la scrutation du drapeau TMR2IF par les 2 instructions suivantes : ici btfss PIR1,TMR2IF ; attendre drapeau goto ici Les temporisations obtenues peuvent être erronées { cause de l’instruction goto qui prend deux cycles pour s’exécuter ce qui peut retarder la détection du drapeau. La solution est d’utiliser l’interruption liée au drapeau TMR2IF, dans ce cas, les temporisations obtenues sont exactes Exercice 27) TMR2 a) Si le PIC est cadencé par Fosc = 8 MHz, quelle la temporisation maximale que l'on peut obtenir à l'aide du timer TMR2 b) Que devient cette valeur si on ajoute un compteur CTR (1 seul registre) dans le programme

VII.2.3 Programme type : Clignoter une LED, Interruption de TMR2
On désire faire clignoter une LED branchée sur RD4 au rythme de la ½ seconde. Le PIC® est cadencé par l'horloge interne Fosc=8MHz. Il faut réaliser CTR × PREDIV × (PR2+1) × POSTDIV x Tcy = 500 000 µs o Le compteur CTR peut prendre toutes les valeurs entre 1 et 256 (256=0) o PREDIV peut prendre une des valeurs 1, 4 ou 16 o PR2 peut prendre toutes les valeurs entre 0 et 255 o POSTDIV peut prendre toutes les valeurs entre 1 et 16 o Fosc = 8 MHz => Tcy = 0.5 µs Plusieurs combinaisons sont possibles. Les utilisateurs de MATLAB peuvent utiliser la fonction cidessous pour afficher toutes les combinaisons possibles. Il suffit de l'invoquer par la ligne de commande : tmr2(8, 500000)
function tmr2(fosc_mhz,Tus) % tmr2(fosc_mhz,Tus)

Microcontrôleur PIC16F887
disp(' CTR PREDIV PR2+1 POSTDIV'); disp('---------------------------------'); for ctr=256:-1:1 for div1=[1 4 16] for pr2=0:255 for div2=1:16 t2=ctr*div1*(pr2+1)*div2*4/fosc_mhz; if t2 == Tus disp([ctr div1 pr2+1 div2]); end end end end end

A.OUMNAD

63

Prenons CTR=200, PREDIV=4, PR2=249, POSTIV=5. On obtient le programme ci-dessous,
LED-RD4-TMR2-int.asm ;======================================================================= ; Clignoter la LED branchée sur RD4 au rythme de la ½ seconde ; Fosc = 8 MHz, TMR2: CTR=200, PREDIV=4, PR2+1 = 250, POSTDIV = 5 ;====================================================================== ERRORLEVEL -302 ; pour masquer les messages de compilation INCLUDE p16f887.inc INCLUDE mesmacros.inc LIST p=16f887, r=dec __CONFIG 0x2007 , 0x23E4 __CONFIG 0x2008 , 0x3EFF CTR EQU 70h org goto 0 main

; ========= sous programme d'interruption ======= org 4 bcf PIR1,TMR2IF ; baisser le drapeau decfsz CTR,f ; compter les débordement de TMR2 retfie ; le compte n'y est pas movlw B'00010000' ; masque de RD4 xorwf PORTD,f ; inverser RD4 movlw 200 ; réinitialiser le compteur movwf CTR retfie ; ===== Programma principal ============= main: BANK1 movlw 0x71 movwf OSCCON ; Oscillateur interne, Fosc=8MHz bcf TRISD,4 ; RD4 en sortie movlw 249 movwf PR2 bsf PIE1,TMR2IE ;valider l'interruption TMR2I BANK0 movlw B'00100101' ; PREDIV=4, PR2+1 = 250, POSTDIV = 5 movwf T2CON movlw 200 ; initialiser compteur (premier passage uniquement) movwf CTR bsf INTCON,GIE ; valider les interruptions bsf INTCON,PEIE ; valider les interruptions périphériques goto $ END

Microcontrôleur PIC16F887

A.OUMNAD

64

VII.2.4 Programme type : Signal asymétrique
On désire générer un signal de rapport cyclique quelconque sur la sortie RD3.
T1 20 µs T2 50 µs T1 T2

On va utiliser le timer TMR2 pour ajuster les temps. Avec Fosc = 8 MHz, on a Tcy = 0.5 µs. Pour obtient un temps T µs, il suffit de prendre PREDIV=1, POSDIV=2 et PR2 = T-1. On va laisser le (-1) de coté pour faciliter l'explication qui suit. Pour obtenir le signal asymétrique représenté ci-dessus, on commence par PR2=T1, ensuite il faut basculer à PR2=T2 et continuer à basculer ainsi d'une valeur à l'autre. Pour réaliser l'opération de basculement d'une façon simple, on va utiliser cette propriété de l'opérateur XOR : A ⨁ A = 0. On commence par définir un masque M = T1 ⨁ T2. Au début il faut obligatoirement que PR2 soit initialisé à l'une des deux valeurs T1 ou T2  Si PR2 = T1, si on fait l'opération PR2 = PR2⨁ M, on obtient PR2 = T1⨁ T1⨁ T2 = T2  Si PR2 = T2, si on fait l'opération PR2 = PR2⨁ M, on obtient PR2 = T2⨁ T1⨁ T2 = T1 On remarque que la même opération permet de basculer entre les deux valeurs T1 et T2

Exercice 28) Ecrire le programme qui permet de générer le signal de la figure ci-dessus

Microcontrôleur PIC16F887

A.OUMNAD

65

Chapitre VIII LE MODULE DE CONVERSION ANALOGIQUE NUMÉRIQUE

Ce module est constitué d'un convertisseur Analogique Numérique 10 bits de type approximations successives. L'entrée est issue d'un multiplexeur analogique permettant de choisir un canal analogique parmi 16. 14 de ces canaux viennent de l'extérieur sur les E/S AN0 à AN13. Les 2 canaux restants sont issus du générateur de tension de référence utilisé avec les comparateurs analogiques. Le choix d'un canal se fait à l'aide des 4 bits CHS<3:0> situés dans le registre de contrôle ADCON0.
CHS<3:0> AN0/RA0 AN1/RA1 AN2/RA2 AN3/RA3 AN4/RA5 AN5/RE0 AN6/RE1 AN7/RE2 AN8/RB2 AN9/RB3 AN10/RB1 AN11/RB4 AN12/RB0 AN13/RB5 CVREF FVREF 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 RA2/VREFVss Tosc VCFG1 1 0 GO/DONE DIV VrefCLK Tad S CAN ADRESL ADRESH 1 0 VCFG0 Vref+ RA3/VREF+ Vdd ADCON0 ADCON1

ADCS0 ADCS1

Figure VIII-1 : Convertisseur Analogique Numérique

Les E/S utilisées doivent être configurées en entrée à l'aide des registres TRISA, TRISE et TRISB. Elles doivent aussi être configurées en analogiques grâce aux registres ANSEL et ANSELH

Microcontrôleur PIC16F887

A.OUMNAD

66

ANSEL

ANS7 0/1 RE2 N/ A

ANS6 0/1 RE1 N/ A

ANS5 0/1 RE0 N/ A

ANS4 0/1 RA5 N/ A

ANS3 0/1 RA3 N/ A

ANS2 0/1 RA2 N/ A

ANS1 0/1 RA1 N/ A

ANS0 0/ 1 RA0 N/ A

ANSELH

ANS13 ANS12 ANS11 ANS10 ANS9 0/ 1 0/1 0/1 0/1 0/1 RB5 N/ A RB0 N/ A RB4 N/ A RB1 N/ A RB3 N/ A

ANS8 0/1 RB2 N/ A

L’échantillonneur bloqueur est intégré, il est constitué d’un interrupteur d’échantillonnage et d’une capacité de blocage de 10 pF. Les tensions de références permettant de fixer la dynamique du convertisseur. Elles peuvent être choisies parmi Vdd, Vss, VREF+ et VREFLe résultat numérique est accessible dans les deux registres ADRESL et ADRESH. Le contrôle se fait par les deux registres ADCON0 et ADCON1

VIII.1 Les registres ADCON0 et ADCON1
ADCON0 ADCS1 ADCS0 CHS3 CHS2 CHS1 CHS0 GO/DONE ADON

ADCS1:ADCS0 : Choix de l'horloge de conversion, Tad = Tosc × div doit être ≥ 1.6µs 00 : div = 2 01 : div = 8 10 : div = 32 11 : Oscillateur RC dédié au CAN, Tad est de l'ordre de 4 µs <CHS3:CHS0> : Choix du canal analogique à convertir (Voir Figure VIII-1) GO/DONE : En plaçant ce bit à 1, on démarre une Conversion. A la fin de la conversion, ce bit revient automatiquement à 0 ADON : Ce bit permet d'activer/désactiver le CAN 0 : CAN désactivé 1 : CAN activé ADCON1 ADFM VCFG1 VCFG0 -

ADFM : justification à droite ou à gauche du résultat dans les registre ADRESH et ADRESL ADRESH ADRESL 1 : justifié à droite 000000xx xxxxxxxx 0 : justifié à gauche xxxxxxxx xx000000 VCFG1 : Choix de la tension de référence inférieure 0 : Vref- = Vss 1 : Vref- = AN2 = RA2

Microcontrôleur PIC16F887 VCFG+ : Choix de la tension de référence supérieure 0 : Vref+ = Vdd 1 : Vref+ = AN3 = RA3

A.OUMNAD

67

VIII.2 Déroulement d’une Conversion
Pendant la conversion, la tension Ve à l'entrée du convertisseur A/N doit être maintenue constante. Pour cette raison, le PIC® dispose d’un échantillonneur bloqueur intégré constitué d'un interrupteur S et d'une capacité de maintien C=10 pF. Au départ, l'interrupteur S est fermé pour permettre à la capacité de se charger jusqu'à la valeur du signal d'entrée. C'est la phase d'acquisition. Après la fin de l’acquisition, on peut démarrer une conversion en positionnant le bit GO/DONE. L'interrupteur S s’ouvre pour assurer le blocage de la tension d'entrée par la capacité. La conversion commence, elle est réalisée en 12 coups d'horloge (12 TAD). A la fin, le bit GO/DONE repasse à 0, le drapeau ADIF passe à 1 et le résultat est chargé dans les registres ADRESL et ADRESH. Le module met 2 TAD supplémentaires pour fermer l'interrupteur S ce qui démarre une nouvelle phase d’acquisition pendant laquelle la tension Ve rejoint la tension analogique d'entrée Va. Après la fin de l’acquisition, on peut démarrer une nouvelle conversion et ainsi de suite. Le temps d'acquisition dépend de la constante de temps RC, R étant la somme des résistances entre le module de conversion et la source de la tension analogique. A la fin de chaque conversion, le drapeau ADIF peut déclencher l'interruption ADI si elle a été validée au préalable par les bits GIE, PEIE et ADIE. L'interruption peut être utilisée pour sortir le PIC® du mode sleep. Ve

Va Va S 10 pF Ve CAN

2Tad

12Tad

Tacq

GO/DONE nous ADIF
Figure VIII-2 : déroulement d'une conversion

automatique

VIII.3 Temps de conversion
Le temps de conversion est : TCONV = 12 TAD

TAD est la période de l'horloge appliquée au convertisseur A/N. Sa valeur dépend de l'horloge de base Tosc et du prédiviseur Div :

Microcontrôleur PIC16F887

A.OUMNAD TAD = Div × Tosc

68

Div peut prendre 4 valeurs possibles. Le choix se fait à l'aide des bits ADCS0 et ADCS1 du registre ADCON0. Des limitations dues à la technologie CMOS du PIC font que Div doit être ajusté de sorte que TAD soit ≥ { 1,6 µs. Le tableau ci-dessous donne la valeur de TAD pour quelques valeurs de Fosc. ADCS1 ADCS0 Div 00 2 01 8 10 32 11 RC 20Mhz 0,1 µs 0,4 µs 1,6 µs Fosc 5Mhz 8MHz 4Mhz 0,4 µs 0,25 µs 0,5 µs 1,6 µs 1 µs 2 µs 6,4 µs 4 µs 8 µs Non utilisable 2Mhz 1 µs 4 µs 16 µs 1Mhz 2 µs 8 µs 32 µs 4 µs

Tableau VIII-1 : TAD (les cases grisées sont hors plage d’utilisation)

Avec un quartz de 4 MHz, on peut choisir Div = 8 ou Div 32. Il est préférable de prendre Div=8 ce qui donne un temps de conversion plus court. TAD = 2 µs, soit un temps de conversion : TCONV = 24 µs. Avec Fosc = 20MHz, on est obligé de prendre Div=32, d'où TAD = 1.6 µs et TCONV = 19.2 µs

VIII.4 Temps d'acquisition
Le temps d'acquisition est : TACQ = Tc + CT +2 µs

Tc : temps de charge du condenseur = (Ric+Rss+Rs) C Ln(2047) Ric = Résistance d’interconnexions, elle est inférieure à 1kΩ Rss = Résistance du l’interrupteur S (Sampling switch), elle dépend de la tension d’alimentation Vdd. Elle est égale à 7kΩ pour Vdd=5V Rs : Résistance interne de la source du signal analogique. Il est recommandé de ne pas dépasser une valeur de 10kΩ C : Capacité de blocage = 10 pF CT : Coefficient de température = (Tp -25°C) 0.05 µs/°C Tp = Température Processeur, voisine de 50°C en temps normal Valeur nominale : Ric = 1kΩ, Rss = 7k, Rs = 10kΩ, Tp = 50 °C : Tc = 18kΩ x 10pF x Ln(2047) = 1.37 µs CT = 25 x 0.05 µs = 1.25 µs TACQ = 1.37 + 1.25 +2 µs = 4.62 µs ≈ 5 µs

VIII.5 Fréquence d'échantillonnage
Si on veut échantillonner un signal variable, on peut constater sur la Figure VIII-2 que la période d'échantillonnage Te doit être supérieure ou égale à : Temin = TCONV + 2 TAD + TACQ = 14 TAD + TACQ Avec Fosc = 20MHz, la période d’échantillonnage minimum est: Temin = 14 x 1.6 µs + 4.62 µs ≈ 27 µs La fréquence d’échantillonnage maximale est de l'ordre: Femax = 1/Temin = 37 kHz

Microcontrôleur PIC16F887

A.OUMNAD

69

Si on tient compte de la règle de Shannon (Fe  2 fmax), on constate que l’on peut échantillonner des signaux dont la fréquence peut atteindre 18 KHz ce qui est tout à fait respectable. On peut donc utiliser le PIC® pour numériser la voix et même la musique.

VIII.6 Valeur numérique obtenue
Quelle est la relation entre la tension analogique convertie et le nombre N recueilli dans le double registre ADRESH:ADRESL ? Si on note : Q = pas de quantification = (Vref+ - Vref-)/1024 Va = tension analogique à convertir N = valeur numérique obtenue, N = (Va – Vref-) \ Q Avec Vref- = Vss = masse, on obtient N = (Va \ Q) exemple : Vref+ = Vdd = 5V, Vref- = 0, Va = 4 V Q = 5V/1024 = 0,0048828125 V N = 4V \ 0,0048828125V = 819 (\ : division entière)

VIII.7 Programmation en bref
 Configurer les entrées analogiques à l'aide des registres ANSEL et ANSELH  Configurer les entrées analogiques en entrées à l'aide des registres TRISA, TRISB et TRISE  Configurer le registre ADCON1 pour définir les tensions de référence et la justification du résultat  Configurer le registre ADCON0 pour choisir le diviseur, le canal analogique et valider le module  Attendre le temps d’acquisition (≈ 5 µs )  Lancer la conversion en positionnant le bit GO_DONE,  Attendre fin de conversion en scrutant le bit GO_DONE  Traiter le résultat

VIII.8 Programmes types
VIII.8.1 Prendre une seule mesure
Programme qui converti la tension appliquée à RA0 et recopie ADRESL dans PORTC et ADRESH dans PORTD. On travaille ave Fosc = 4MHz, on obtient un temps de conversion meilleur qu'avec 8 MHz.
ADC-1ech.asm ;=================================================================== ; Prendre une mesure sur l'entrée RA0 et et envoyer le résultat sur PORTC et PORTD ;=================================================================== LIST p=16f887,r=dec INCLUDE <p16f887.inc> INCLUDE <mesmacros.inc> __CONFIG 0x2007 , 0x23E4 ; INTOSCIO __CONFIG 0x2008 , 0x3FFF EERORLEVEL -302 ;============================================================= BANK1 movlw 61h

Microcontrôleur PIC16F887
movwf bsf clrf clrf movlw movwf BANK3 movlw movwf clrf BANK0 movlw movwf nop nop nop nop nop bsf btfsc goto movf movwf BANK1 movf BANK0 movwf sleep END OSCCON TRISA,0 TRISC TRISD 80h ADCON1 B'00000001' ANSEL ANSELH 0x41 ADCON0

A.OUMNAD
; horloge interne 4 Mhz, Tosc=0.25µs, Tcy=1µs ; RA0 entrée ; PORTC en sortie ; PORTD en sortie ; résultat justifié à droite, Vr+=Vdd, Vr-=Vss

70

; RA0 analogique ; tout le reste numérique

; 01 0000 0 1 ; DIV=8,Tad=2ms, canal 0, AD:en service ; attendre temps d'acquisition

ADCON0,GO ADCON0,GO $-1 ADRESH,w PORTD ADRESL,W PORTC

; lancer la conversion ; attendre fin conversion

VIII.8.2

Relever 40 échantillons

Programme qui fait l'acquisition de 40 échantillons du signal appliqué sur RA0, et recopie les résultats dans la RAM à partir de la position 190h. L'échantillonnage se fera à la vitesse la plus rapide possible.
ADC-40ech.asm ;===================================================================== ; Relever 40 échantillons et stocker les résultats dans la RAM à partir de la position 190h ; le rythme d'échantillonnage le plus rapide possible (avec Fosc = 4MHz) ====================================================================== LIST p=16f887,r=dec INCLUDE <p16f887.inc> INCLUDE <mesmacros.inc> __CONFIG 0x2007 , 0x23E4 ; INTOSCIO __CONFIG 0x2008 , 0x3FFF ERRORLEVEL -302 CTR EQU 70h ;============================================================= BANK1 movlw 61h movwf OSCCON ; horloge interne 4 Mhz, Tosc=0.25µs, Tcy=1µs bsf TRISA,0 ; RA0 entrée movlw 80h ; résultat justifié à droite, Vr+=Vdd, Vr-=Vss movwf ADCON1 BANK3 movlw B'00000001' ; RA0 analogique movwf ANSEL ; tout le reste numérique clrf ANSELH BANK0 movlw 0x41 ; 01 0000 0 1 movwf ADCON0 ; DIV=8,Tad=2ms, canal 0, AD:en service

Microcontrôleur PIC16F887

A.OUMNAD

71

; à partir d'ici, il faut attendre au moins 5 µs avant de lancer la conversion ; les 5 instructions suivantes font l'affaire movlw .40 movwf CTR ; compteur d'échantillons bsf STATUS,IRP ; adressage indirect , page 2 movlw 90h ; pointeur d'adressage indirect movwf FSR ici: bsf btfsc goto BANK1 movf movwf incf BANK0 movf movwf incf decfsz goto sleep END ADCON0,GO ADCON0,GO $-1 ADRESL,W INDF FSR,f ADRESH,w INDF FSR,f CTR,f ici ; lancer la conversion ; attendre fin conversion

Après la fin dune conversion, le temps de traitement pour copier le résultat dans la RAM dépasse la durée d'acquisition. Aucune attente supplémentaire n'est nécessaire avant de lancer une nouvelle conversion.

VIII.8.3

Relever 40 échantillons, fe=8000 Hz

On refait le travail précédent avec une fréquence d’échantillonnage fe = 8000Hz, soit Te=125µs. On utilise TMR2 pour déclencher une interruption toutes 125 µs
ADC-40ech-8000Hz ;============================================================== ; Relever 40 échantillons avec fe=8000Hz ( Te=125µs), et stocker les résultat ; dans la RAM à partir de la position 190h ; le rythme d'échantillonnage est cadencé par l'interruption de TMR2 ============================================================== LIST p=16f887, r=dec INCLUDE <p16f887.inc> INCLUDE <mesmacros.inc> __CONFIG 0x2007 , 0x23E4 ; INTOSCIO __CONFIG 0x2008 , 0x3FFF ERRORLEVEL -302 CTR EQU 70h ;============================================================= ORG 0 goto main ; ========= procédure d'interruption ============= ORG 4 bsf ADCON0,GO ; lancer la conversion btfsc ADCON0,GO ; attendre fin conversion goto $-1 BANK1 movf ADRESL,w movwf INDF incf FSR,f BANK0 movf ADRESH,w movwf INDF incf FSR,f bcf PIR1,TMR2IF ; baisser le drapeau decf CTR,f ; décrémenter le compteur, Z est positionné retfie

Microcontrôleur PIC16F887

A.OUMNAD

72

; ========= Programme principal ============= main: BANK1 movlw 61h movwf OSCCON ; horloge interne 4 Mhz, Tosc=0.25µs, Tcy=1µs bsf TRISA,0 ; RA0 entrée movlw 80h ; résultat justifié à droite, Vr+=Vdd, Vr-=Vss movwf ADCON1 movlw .124 ; avec PREDIV et POSTDIV=1, on obtient 125µs movwf PR2 bsf PIE1,TMR2IE ; validation interruption TMR2I BANK3 movlw B'00000001' ; RA0 analogique movwf ANSEL ; tout le reste numérique clrf ANSELH BANK0 movlw B'00000100' ; configuration TMR2, postdiv=1, prediv=1 movwf T2CON movlw 0x41 ; 01 0000 0 1 movwf ADCON0 ; DIV=8,Tad=2ms, canal 0, AD:en service movlw .40 movwf CTR ; 40 échantillons bsf STATUS,IRP ; adressage indirect Pointeur = 190h movlw 90h movwf FSR bsf INTCON,GIE ; valider les interruptions bsf INTCON,PEIE ; valider les interruptions périphériques bcf STATUS,Z btfss goto clrf sleep END STATUS,Z $-1 INTCON
Tourner ici tant que le drapeau Z=0. A chaque interruption de TMR2, la procédure d'interruption prend un échantillon et décrémente le compteur. Au retour de l'interruption après le dernier échantillon, on aura CTR=0 donc Z=1. On quitte la boucle qui teste Z et on rentre dans mode sleep

Microcontrôleur PIC16F887

A.OUMNAD

73

Chapitre IX L'USART
L'USART (Universal Synchronous Asynchronous Receiver Transmitter) est l'un des deux modules de communication série dont dispose le PIC16F887. L'USART peut être configuré comme système de communication asynchrone full duplex ou comme système synchrone half duplex (non étudié). La communication se fait sur les deux broches RC6/TX et RC7/RX qui doivent être configurés toutes les deux en ENTREE par TRISC. Les signaux sont compatible TTL, il faut utiliser un circuit d'interface du genre MAX232 pour générer un signal conforme au standard RS232. La vitesse de communication est fixée par un générateur de rythme programmable BRG (Baud rate generator). L'accès au module en lecture et en écriture se fait par les registres RCREG et TXREG. Le contrôle du module se fait par les registres TXSTA, RCSTA, SPBRG, SPBRGH et BAUDCTRL

IX.1

Mode Asynchrone

Si on place le bit SYNC du registre TXSTAT à 0, l'USART fonctionne dans le mode asynchrone. Deux modes sont disponibles, le mode 8 bits standard et un mode 9 bits qui peut s'avérer intéressant dans le cas de communication point à multipoints.  La transmission se fait sur la broche RC6/TX et la réception sur la broche RC7/RX  La configuration et le contrôle du port se fait par les registres TXSTA, RCSTA et BAUDCTL  La vitesse de communication est fixée par les registre SPBRG, SPBRGH et les bits BRGH et BRG16  La parité n'est pas gérée d'une façon matérielle, elle peut être gérée par soft si son utilisation est nécessaire.  L'accès au port en lecture ou écriture se fait par les registres d'accès RCREG et TXREG. La transmission et la réception se font par deux registres à décalage, un pour la transmission ( TSR) et un pour la réception (RSR). L'accès au registres d'accès peut se faire alors que les registres à décalage sont en train de transmettre/recevoir une donnée.  L'USART peut déclencher deux interruptions différente par le biais des drapeaux PIR1.RCIF et PIR1.TXIF. Ces drapeaux sont très utiles pour gérer la lecture/écriture dans le port. o RCIF est positionné quand le port a terminé la réception d'un octet, RCREG plein. o TXIF est positionné quand le registre d'accès TXREG est vide.

IX.1.1 Mode 8 bits
Dans ce mode, 10 bits sont transmis ou reçus dans l'ordre ci-dessous : o 1 bit de START (toujours 0) o 8 bits de donnée (LSB d'abord) o 1 bits de STOP (toujours 1)

Microcontrôleur PIC16F887

A.OUMNAD

74

IX.1.2 Mode 9 bits
Dans ce mode, 10 bits sont transmis ou reçus dans l'ordre ci-dessous : o 1 bit de START (toujours 0) o 9 bits de donnée (LSB d'abord) o 1 bits de STOP (toujours 1)

IX.2

Le port en transmission
TXREG

BRG

TSR

RC6/TX

Figure IX-1 : schéma très simplifié du module de transmission

Pour transmettre un octet D, il faut s'assurer que le registre d'accès TXREG est libre en vérifiant que le drapeau TXIF est égal à 1. Ensuite, il suffit de copier l'octet D dans le registre TXREG, le drapeau TXIF passe à 0 pour indiquer que le registre TXREG est occupé. Ensuite, deux situations sont possibles :  Le registre de transmission TSR n’est pas occupé, alors la donnée D est transférée immédiatement dans le registre à décalage TSR qui commence sa transmission bit bar bit. Le drapeau TXIF repasse à 1 pour indiquer que le registre d'accès TXREG est de nouveau libre.  Le registre de transmission TSR est occupé à transmettre un octet. La donnée D attend dans TXREG, et le drapeau TXIF reste à 0 jusqu’{ ce que TSR termine de transmettre l’octet précédent. La donnée D est alors transférée dans TSR qui commence sa transmission bit bar bit. Le drapeau TXIF repasse à 1 pour indiquer que le registre TXREG est libre. En mode 9 bits, le 9ème bit (MSB) doit être placé dans le bit TX9D du registre TXSTA et ceci avant de placer les 8 autres bits dans TXREG. écriture D0 écriture D1 dans TXREG dans TXREG

TXIF

Transmission D0

Transmission D1

chargement TXREGTSR

chargement TXREGTSR

Figure IX-2 : illustration de la transmission de deux octet successifs D0 et D1

Comme on vient de le voir, le drapeau TXIF est géré automatiquement, on ne peut pas le modifier directement par programme.

IX.2.1 Le registre de contrôle TXSTA
R/W(0) R/W(0) R/W(0) R/W(0) R/W(0) R/W(0) R(1) R/W(0)

CSRC

TX9

TXEN

SYNC

SENDB BRGH TRMT

TX9D

Microcontrôleur PIC16F887

A.OUMNAD

75

CSRC : non utilisé en mode asynchrone TX9 : Validation du mode 9 bits 0 : mode 8 bit 1 : mode 9 bits TXEN : permet d'activer/désactiver la transmission, 0 : désactivée 1 : activée SYNC : Choix entre mode synchrone ou asynchrone 0 : mode asynchrone, 1 : mode synchrone SENDB : permet de transmettre un break. Revient à 0 après la transmission du Break BRGH : utilisé par le générateur de rythme BRG. Multiplie la vitesse par 4 TRMT : Indicateur de l’activité du registre { décalage de transmission TSR 0 : registre á décalage TSR en activité 1 : registre á décalage TSR libre, TX9D : en mode 9 bits, Le 9ème bit de doit être placé ici

IX.3

Le port en réception
RCREG

BRG

RSR

RC7/RX

Figure IX-3 : schéma très simplifié du module de réception

La réception est validée par le bit CREN La réception d'un octet démarre à la réception du START bit qui commence toujours par une transition 10 A la réception du stop bit, le contenu du registre à décalage de réception RSR est recopié dans le registre tampon de réception RCREG. Le drapeau RCIF (PIR1.5) est positionné, l'interruption associée est déclenchée si elle est validée. Le drapeau RCIF est remis à 0 automatiquement au moment où le registre RCREG est vidé. Le registre RCREG est un registre double (pile FIFO à 2 positions). On peut donc avoir 2 octets en attente dans ce registre et être en train de recevoir un 3ème dans le registre à décalage RSR. A la fin de la réception du 3ème octet, si RCREG est toujours plein, alors le dernier octet reçu est perdu et le bit OERR (Overrun ERRor bit) est positionné ce qui provoque l'arrêt des transferts du registre à décalage RSR vers le buffer RCREG. Pour reprendre la réception il faut réinitialiser le module de réception en mettant à 0 puis à 1 le bit CREN (). Le drapeau PIR1.RCIF ne passe à 0 que quand la pile RCREG est vide Si on reçoit un 0 à la position du STOP bit qui doit être toujours à 1, alors le bit FERR (Framing ERRor) du registre RCSTA est positionné. Comme la pile FIFO de réception peut contenir deux octets, chaque octet a son propre bit framing error. Les deux bits sont aussi empilés. Le bit FERR du registre RCSTA permet accéder au bit d'erreur correspondant à l'octet qui est au sommet de la pile RCREG. Chaque fois qu'on lit un octet dans RCREG, FERR est remplacé bar le bit d'erreur de l'octet à lire prochainement.

Microcontrôleur PIC16F887

A.OUMNAD

76

FERR

RCREG

RCIF

FERR

RCREG

RCIF

FERR

RCREG

RCIF

0 F0
(1) Pile vide RCIF

1 D0 F0 F1 D0 D1

1

(2) Après l'arrivé de l'octet D0 FERR RCREG RCIF

(3) Après l'arrivé de l'octet D1

FERR

RCREG

1 F1 D1
(5) Après lecture de l'octet D1

0

(4) Après lecture de l'octet D0

Figure IX-4 : fonctionnement de la pile de réception

La figure ci-dessus illustre le fonctionnement de la pile de réception,  Au début la pile est vide donc drapeau RCIF=0  Le module reçoit l'octet D0, il le copie dans la pile RCREG. Son bit d'erreur F0 est copié dans la pile FERR. Le drapeau RCIF passe à 1 pour indiquer qu'au moins un octet nous attend dans la pile.  Le module reçoit un deuxième octet D1, il le copie dans la pile RCREG. Son bit d'erreur F1 est copié dans la pile FERR. Le drapeau RCIF reste à 1 pour indiquer qu'au moins un octet nous attend dans la pile.  Nous lisons le registre RCREG. C'est l'octet D0 qui est lu. L'octet D1 ainsi que sont bits d'erreur F1 sont décalé vers le haut dans la pile. Le drapeau RCIF reste à 1 car il reste un octet dans la pile. On remarque que le bit F0 a été écrasé par le bit F1. Donc si on désire contrôler les bits framing error, il faut toujours lire le bit FERR avant de lire le registre RCREG, car la lecture de ce dernier provoque le décalage des piles vers le haut.  Nous lisons le registre RCREG. C'est l'octet D1 qui est lu. La pile est vide, le drapeau RCIF passe à 0.

IX.3.1 Lecture du 9ème bit
En mode 9 bits, à la fin de la réception d'une donnée, 8 bits sont copiés de le buffer de réception RCREG. Le 9ème bit et copié dans la position RX9D du registre RCSTA. Le bit RX9D doit être lu avant la lecture du registre RCSTA sinon il est perdu. Ceci, comme on l'a déjà vu avec le bit FERR, est dû au fait que le buffer RCSTA est une pile à deux positions. Chaque lecture décale la pile vers le haut d'une position. Comme on peut le voir sur la figure ci-dessous, Si on reçoit deux octets, chacun a son 9ème bit. Si on commence par lire RCREG, la pile est décalée vers le haut. Le bit 9b0 est écrasé par le bit 9b1 alors qu'on ne l'a pas encore lu.
RX9D RCREG

9b0 9b1

Octet 0 Octet 1

Figure IX-5 : buffer de réception en mode 9bits

IX.3.2 Le registre de contrôle RCSTA
R/W(0) R/W(0) R/W(0) R/W(0) R/W(0) R(0) R() R(x)

SPEN

RX9

SREN

CREN

ADDEN

FERR

OERR

RX9D

Microcontrôleur PIC16F887 SPEN : Validation du port série 0 = Inhibé 1 = validé RX9 : Validation du mode 9 bits, 0 = mode 8 bits 1 = mode 9 bits

A.OUMNAD

77

SREN : validation de réception d'u seul octet (non utilisé en mode asynchrone) CREN : Validation du mode réception continue, 0 = Inhibé 1 = validé ADDEN : détection d'adresse, en mode 9 bits FERR : Erreur de synchronisation, lecture seule. (Voir ci-dessus) OERR : Erreur débordement du buffer de réception, lecture seule. (Voir ci-dessus) RX9D : en mode 9 bits, le 9ème bit (MSB) doit être lu ici.

IX.3.3 Mode détection d'adresse
Ce mode fonctionne en réception mode 9 bits. Il est activé/désactivé à l'aide du bit ADDEN du registre RCSTA. Ce mode est utile dans le cas d'une communication point à multipoints dans laquelle un maitre communique avec plusieurs esclaves sur la même ligne. Chaque esclave étant identifié par une adresse. On peut ainsi réaliser un système de communication à travers une liaison RS-485.

Maitre

Esclave 1

Esclave 2

Esclave 3

Interface RS-485

Interface RS-485

Interface RS-485

Interface RS-485

Figure IX-6 : Communication point à multipoints

Dans un tel système, le maitre envoie des messages sous formes de trames. Chaque trame commence par l'adresse du slave auquel elle est destinée, suivie d'un champ de données. Selon le protocole utilisé, la trame peut être de longueur fixe ou peut se terminer par un caractère particulier faisant office de fanion fin de message. Pour distinguer entre l'octet adresse et les octets de données, l'octet adresse est envoyé avec le 9ème bit égal à 1, les octets de données sont envoyés avec le 9ème bit égal à 0. Les esclaves fonctionnent en mode détection d'adresse qu'ils peuvent activer désactiver à l'aide du bit ADDEN du registre RCSTA. Quand ce mode est activé, seul les octets reçus avec le 9ème bit égal à 1 sont acceptés et transférés dans le buffer RCREG, les autres sont ignorés. Quand ce mode est désactivé, la réception se fait normalement. Au départ, tous les esclaves sont en mode écoute. Ils ont activé la détection d'adresse et placé leur interface de transmission en haute impédance. Ils recevent l'octet adresse envoyé par le maitre. Chacun le compare avec sa propre adresse. Un seul se reconnaitra et continuera l'échange. Les autres restent en mode écoute. L'esclave concerné doit désactiver le mode de détection d'adresse affin de recevoir le reste des données. Il peut aussi activer son interface de transmission pour envoyer des donnés vers le maitre. Selon le protocole utilisé, le slave détecte la fin du message et repasse en mode écoute.

Microcontrôleur PIC16F887

A.OUMNAD

78

IX.4

La vitesse de communication

La vitesse de communication est déterminée par le générateur de rythme BRG (Baud Rate Generator). Elle est dérivée de la fréquence Fosc selon la valeur des registres de contrôle SPBRG et SPBRGH ainsi que celle des bits BRGH (TXSTA,2) et BRG16 (BAUDCTL,3).

vitesse 

M  Fosc baud 64  (R  1)

R

M  Fosc -1 64  vitesse

M est un multiplicateur qui peut prendre une des valeurs 1, 4 ou 16. R est soit le contenu du registre SPBRG seul (précision 8 bits) soit le contenu du registre double SBRGH:SPBRG (précision 16 bits). Le choix se fait par les deux bits BRGH et BRG8 conformément au tableau ci-dessous.
BRG16 0 0 1 1 BRGH 0 1 0 1 M 1 4 4 16 R SPBRG SPBRG SPBRGH:SPBRG SPBRGH:SPBRG

précision 8 bits précision 16 bits

Tableau IX-1 : paramètres de la formule qui détermine la vitesse de communication

On remarque que  BRGH a un rôle de multiplicateur par 4,  BRG16 a un rôle de multiplicateur par 4, en plus, il permet de fonctionner en précision 16 bits.
Fosc 1MHz 4MHz 8MHz 20MHz Vitesse désirée SPBRG Obtenue Err% SPBRG Obtenue Err% SPBRG Obtenue Err% SPBRG Obtenue Err% 300 51 300 0,00 207 300 0,00 255 1221 1,75 1200 12 1202 0,17 51 1202 0,17 103 1202 0,17 2400 25 2404 0,17 51 2404 0,17 129 2404 0,17 9600 12 9615 0,16 32 9470 -1,35 19200 15 19531 1,72 57600 115200 Tableau IX-2 : quelques exemples avec BRG16 = 0, BRGH = 0 Fosc 1MHz 4MHz 8MHz 20MHz Vitesse désirée SPBRG Obtenue err % SPBRG Obtenue err % SPBRG Obtenue err % SPBRG Obtenue err % 300 207 300 0,00 1200 51 1202 0,17 207 1202 0,17 2400 25 2404 0,17 103 2404 0,17 207 2404 0,17 9600 6 8929 -6,99 25 9615 0,16 51 9615 0,16 129 9615 0,16 19200 2 20833 8,51 12 19231 0,16 25 19231 0,16 64 19231 0,16 57600 8 55556 -3,55 21 56818 -1,36 115200 10 113636 -1,36 Tableau IX-3 : quelques exemples avec BRG16 = 0, BRGH = 1 Fosc Vitesse désirée 300 1200 2400 4800 9600 19200 57600 115200 8MHz 20MHz SPBRGH Err SPBRGH Err SPBRGH Err SPBRGH Err SPBRG Obtenue % SPBRG Obtenue % SPBRG Obtenue % SPBRG Obtenue % 0 207 300 0 3 64 300 0 6 130 300 0 16 70 300 0 0 51 1202 0,17 0 207 1202 0,17 1 160 1199 -0,08 4 17 1200 0 0 25 2404 0,17 0 103 2404 0,17 0 207 2404 0,17 2 8 2399 -0,04 0 12 4808 0,17 0 51 4808 0,17 0 103 4808 0,17 1 3 4808 0,17 0 25 9615 0,16 0 51 9615 0,16 0 129 9615 0,16 0 12 19231 0,16 0 25 19231 0,16 0 64 19231 0,16 0 8 55556 -3,55 0 21 56818 -1,36 0 10 113636 -1,36 Figure IX-7 : quelques exemples avec BRG16 = 1, BRGH = 0 1MHz 4MHz

Microcontrôleur PIC16F887

A.OUMNAD

79

Fosc 8MHz 20MHz Vitesse SPBRGH Err SPBRGH Err SPBRGH Err SPBRGH Err désirée SPBRG Obtenue % SPBRG Obtenue % SPBRG Obtenue % SPBRG Obtenue % 300 3 64 300 0 13 4 300 0 26 10 300 0 65 26 300 0 1200 0 207 1202 0,17 3 64 1200 0 6 130 1200 0 16 70 1200 0 2400 0 103 2404 0,17 1 160 2398 -0,1 3 64 2401 0,04 8 34 2400 0 4800 0 51 4808 0,17 0 207 4808 0,17 1 160 4796 -0,08 4 17 4798 -0,04 9600 0 25 9615 0,16 0 103 9615 0,16 0 207 9615 0,16 2 8 9597 -0,03 19200 0 12 19231 0,16 0 51 19231 0,16 0 103 19231 0,16 1 3 19231 0,16 57600 0 16 58824 2,13 0 34 57143 -0,79 0 86 57471 -0,22 115200 0 8 111111 -3,6 0 16 117647 2,12 0 42 116279 0,94 Figure IX-8 : quelques exemples avec BRG16 = 1, BRGH = 1 1MHz 4MHz

IX.4.1 Le registre BAUDCTL
Certains bits de ce registre concernent le mode détection automatique de vitesse qui ne sera pas traité dans ce document.
R(0) R(1) U(0) R/W(0) R/W(0) U(0) R/W() R(x)

ABDOVF

RCIDL

-

SCKP

BRG16

-

WUE

ABDEN

ABDOV : indicateur de débordement du timer du détecteur de vitesse ABDOV : indicateur de l'activité du module de réception 0 : le module de réception est prêt 1 : le module de réception est en train de recevoir un caractère SCKP : pour fixer la polarité du signal de données sur la sortie RC6/TX 0 : signal non inversé (à utiliser avec un max232) 1 : signal inversé (conforme à la polarité de la norme RS232) BRG16 : détermine si le BRG utilise un registre 8 bits ou 16 bits pour déterminer la vitesse 0 : seul SPBRG est utilisé dans le calcul de la vitesse 1 : les deux registres SPBRGH et SPBRG sont utilisés dans le calcul de la vitesse WUE : validation du mode Wake up 0 : le module de réception fonctionne normalement 1 : le module de réception attend un front montant sur l'entrée RC7/RX pour sortir du mode sleep ABDEN : validation du mode détection automatique de vitesse (auto-baud). 0 : le mode auto-baud est désactivé 1 : démarre la séquence de détection de la vitesse. Revient à 0 une fois la détection terminée

IX.5

La transmission en bref (sans interruption)

 S’assurer que l’interruption TXI n’est pas validée  Configurer la broche TX/RC6 en entrée  Configurer le registre TXSTA (mode 8 bits, valider transmission, asynchrone, BRGH)  Configurer la vitesse par le registre SPBRG et éventuellement le registre SPBRGH et le bit BR16  Configurer le registre BAUDCTL  Valider le port avec le bit RCSTA.SPEN  Vérifier que le drapeau PIR1.TXIF=1 c.à.d TXREG est vide  Placer la donnée à transmettre dans le registre TXREG  Recommencer au point pour transmettre d'autres données

Microcontrôleur PIC16F887

A.OUMNAD

80

IX.6

La réception en bref (sans interruption)

 S’assurer que l’interruption RCI n’est pas validée  Configurer la broche RX/RC7 en entrée  Configurer le registre TXSTA (mode 8 bits, asynchrone, BRGH)  Configurer la vitesse par le registre SPBRG et éventuellement le registre SPBRGH et le bit BR16  Configurer le registre BAUDCTL  Configurer le registre RCSTA (validation port, mode 8 bits, réception continue)  Attendre que drapeau RCIF passe à 1 ce qui annonce la présence d'au moins un octet dans le buffer de réception,  Lire l’octet reçu dans le registre RCREG  recommencer au point tant qu’on a des données { recevoir

IX.7

Registres utilisés par l'USART
INTCON PIE1 PIR1 TXSTA RCSTA TXREG RCREG SPBRG SPBRGH TRISC BAUDCTL Bank all GIE PEIE T0IE INTE RBIE T0IF INTF 1 ADIE RCIE TXIE SSPIE CCP1IE TMR2IE 0 ADIF RCIF TXIF SSPIF CCP1IF TMR2IF 1 CSRC TX9 TXEN SYNC SENDB BRGH TRMT 0 SPEN RX9 SREN CREN ADDEN FERR OERR 0 Registre d'accès en transmission 0 Registre d'accès en réception 1 Détermination de la vitesse de transmission 1 Détermination de la vitesse de transmission en mode résolution 16 bits 1 TRISC7 TRISC6 TRISC5 TRISC4 TRISC3 TRISC2 TRISC1 3 ABDOVF RCIDL SCKP BRG16 WUE RBIF TMR1IE TMR1IF TX9D RX9D
RESET 0000 000x 0000 0000 0000 0000 0000 0010 0000 000x 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 01-0 0-00

TRISC0 ABDEN

Exercice 29) Programme qui transmet l'alphabet A à Z sur le port série à 9600 baud, avec une temporisation voisine de 1/2 seconde entre chaque caractère Exercice 30) Programme qui écoute le port série. Quand il reçoit un caractère, il ajoute 1 à son code ASCII pour avoir le caractère suivant puis le retransmet sur le port série. Programme à essayer ave le PIC® d'un coté et un PC avec le logiciel Tera-Term de l'autre. Placer le curseur dans la fenêtre du terminal, taper A, on voit B car le terminal affiche le caractère reçu. On peut configurer le terminal pour voir les caractères tapés localement. Dans ce cas on verra le caractère envoyé et le caractère reçu