Cours Microcontroleur PDF
Cours Microcontroleur PDF
RGHIOUI 1
LES MICROCONTROLEURS
PIC MidRange
Etude détaillée du
PIC® 16F887
Amine RGHIOUI
2023/2024
2 INTRODUCTION
Chapitre I ........................................................................................................................................................ 7
Chapitre II .................................................................................................................................................... 19
Chapitre III................................................................................................................................................... 28
Chapitre IV ................................................................................................................................................... 36
Chapitre V .................................................................................................................................................... 48
Chapitre VI ................................................................................................................................................... 51
LES INTERRUPTIONS.................................................................................................................................. 51
VI.1 Déroulement d'une interruption ..................................................................................................... 51
VI.2 Les sources d'interruption ............................................................................................................... 52
VI.3 L'interruption INT (Entrée RB0 de PORTB) .................................................................................... 52
VI.4 L'interruption IOCB .......................................................................................................................... 53
4 INTRODUCTION
Chapitre VII.................................................................................................................................................. 55
Chapitre IX ................................................................................................................................................... 67
L'USART ........................................................................................................................................................ 67
IX.1 Mode Asynchrone ............................................................................................................................. 67
IX.1.1 Mode 8 bits ............................................................................................................................... 67
IX.1.2 Mode 9 bits ............................................................................................................................... 68
IX.2 Le port en transmission ................................................................................................................... 68
IX.2.1 Le registre de contrôle TXSTA ................................................................................................. 68
IX.3 Le port en réception ......................................................................................................................... 69
IX.3.1 Lecture du 9ème bit.................................................................................................................... 70
IX.3.2 Le registre de contrôle RCSTA ................................................................................................. 70
IX.3.3 Mode détection d'adresse ........................................................................................................ 71
IX.4 La vitesse de communication ........................................................................................................... 72
IX.4.1 Le registre BAUDCTL ............................................................................................................... 73
IX.5 La transmission en bref (sans interruption) ................................................................................... 73
IX.6 La réception en bref (sans interruption)......................................................................................... 74
IX.7 Registres utilisés par l'USART .......................................................................................................... 74
Microcontrôleur PIC16F887 A. RGHIOUI 5
INTRODUCTION
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)
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.
6 INTRODUCTION
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.
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. RGHIOUI 7
Chapitre I
CONFIG1 : 2007
DEBUG LVP FCMEN IESO BOREN1 BOREN0 CPD CP MCLRE PWRTE WDTE FOSC2 FOSC1 FOSC0
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é
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é
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é
CONFIG2 : 2008
- - - WRT1 WRT0 BOR4V - - - - - - - -
Les bits non utilisés n’ont pas d’importance. On peut les placer à 0 ou à 1.
CONFIG2 :
WRT:OFF(11), BOR4V :4V(1)
➔ CONFIG2 = 11 1111 1111 1111 = 0x3FFF
Microcontrôleur PIC16F887 [Link] 11
I.4 L'horloge
… FOSC2 FOSC1 FOSC0 CONFIG1
OSC1/RA7 Oscillateur Hx
OSC2/RA6 Externe
Hxi
0
Fosc
Oscillateur Hi 1
Interne
Hi
Le PIC16F887 dispose d’un générateur intégré qui délivre l'horloge système utilisée par tous les
modules. Sa fréquence est appelée Fosc et sa période Tosc. Le processeur exécute les instructions du
programme au rythme de l'horloge Fosc/4 obtenue par division de fréquence. On l'appelle horloge
instruction car le PIC® exécute une instruction par période d'horloge. Cette 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.
❖ Les 3 bits FOSC2, FOSC1 et FOSC0 du registre de configuration permanent CONFIG1 permettent la
configuration de l’oscillateur externe et des broches RA7/OSC1 et RA6/OSC2. L’Oscillateur interne
reste opérationnel, le choix de sa fréquence se fait à l’aide du registre OSCON. On peut basculer
d’un oscillateur à l’autre à l’aide du bit SCS du registre OSCCON
000 → LP oscillator: Low-power crystal. Oscillateur externe à quartz faible fréquence (<200khz). Le
quartz doit être relié sur les broches RA6/OSC2 et RA7/OSC1 (Hxi = Hx), (Voir §I.4.1)
001 → XT oscillator: Crystal/resonator. Oscillateur Externe à quartz moyenne fréquence (≤ 8MHz).
Le quartz doit être relié sur les broches RA6/OSC2 et RA7/OSC1 (Hxi = Hx), (Voir §I.4.1)
010 → HS oscillator: High-speed crystal/resonator. Oscillateur Externe à quartz haute fréquence
(≥8MHz). Le quartz doit être relié sur les broches RA6/OSC2 et RA7/OSC1 (Hxi = Hx), (Voir
§I.4.1)
011 → EC External Clock. Horloge externe appliquée su RA7. RA6=E/S normale. (Hxi = Hx)
(Voir §I.4.3),
100 → INTOSCIO oscillator: Oscillateur Externe désactivé. RA6=E/S normale, RA7=E/S normale.
(Hxi = Hi).
101 → INTOSC oscillator: Oscillateur Externe désactivé. RA6=CLKOUT, RA7=E/S normale. (Hxi = Hi).
110 → RCIO oscillator: Oscillateur externe de type RC. R et C sont connectés sur RA7. La broche RA6
fonctionne comme E/S normale, (Hxi = Hx). (Voir §I.4.2)
111 → RC oscillator: Oscillateur externe de type RC. R et C sont connectés sur RA7. L'horloge
instruction Fosc/4 est accessible sur la broche RA6/OSC2 qui fonctionne en CLKOUT. On
peut ainsi mesurer sa fréquence et ajuster les valeurs de Rext et Cext . (Hxi = Hx). (Voir §I.4.2)
❖ Le registre OSCCON permet de gérer l’horloge interne. Les bits IRFC permettent de fixer la
fréquence alors que le bit SCS permet de basculer entre l’horloge interne et l’horloge externe.
12 LES ELEMENTS DE BASE DU PIC16F887
Le registre OSCCON est un registre SFR (Special Function Register) qui est situé dans la RAM et qui
peut être changé à tout moment lors de l'exécution du programme (Voir §I.4.6)
Le quartz (externe) doit être relié aux entrées RC7/OSC1 et RC6/OSC2. La fréquence Fosc peut aller
jusqu’à 20 MHz. 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 LP, XT ou HS.
Le bit SCS du registre OSCCON doit être égal à 0. Si ce bit est placé à 1, l’horloge système bascule sur
l’oscillateur interne mais l’oscillateur à quartz reste opérationnel.
Le réseau RC doit être connecté sur la broche RC7/OSC1 comme indiqué sur la figure. La fréquence
obtenue n'est pas très précise. Elle peut varier légèrement d'un PIC à l'autre.
Le registre CONFIG1 doit être configuré par la directive CONFIG dans le mode RC ou RCIO,
Le bit SCS du registre OSCCON doit être égal à 0. Si ce bit est placé à 1, l’horloge système bascule sur
l’oscillateur interne mais l’oscillateur RC reste opérationnel.
L’horloge externe est appliquée sur l’entrée RA7/OSC1. La broche RA6/OSC2 fonctionne en E/S
normale RA6. Le registre CONFIG1 doit être configuré dans le mode EC. Le bit SCS de OSCCON doit être
égal à 0, sinon c’est l’horloge interne qui est choisie.
A la mise sous tension, si on ne modifie pas le registre OSCCON, la valeur par défaut de ces 3 bits
IRCF est 110 ce qui correspond à une fréquence de 4MHz.
14 LES ELEMENTS DE BASE DU PIC16F887
Horloge
système
Figure I-6 : structure très simplifiée de l'unité de traitement
Microcontrôleur PIC16F887 [Link] 15
• 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
et RP1 et doivent être positionnés correctement avant toute instruction qui accède à la RAM par
l’adressage direct.
9 bits
Figure I-7 : 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-8 montre l’organisation de la RAM avec les zones
16 LES ELEMENTS DE BASE DU PIC16F887
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.
Bank 0 (00) Bank 1 (01) Bank 2 (10) Bank 3 (11)
00h INDF 80h INDF 100h INDF 180h INDF
01h TMR0 81h OPTION_REG 101h TMR0 181h OPTION_REG
02h PCL 82h PCL 102h PCL 182h PCL
03h STATUS 83h STATUS 103h STATUS 183h STATUS
04h FSR 84h FSR 104h FSR 184h FSR
05h PORTA 85h TRISA 105h WDTCON 185h SRCON
06h PORTB 86h TRISB 106h PORTB 186h TRISB
07h PORTC 87h TRISC 107h CM1CON0 187h BAUDCTL
08h PORTD 88h TRISD 108h CM2CON0 188h ANSEL
09h PORTE 89h TRISE 109h CM2CON1 189h ANSELH
0Ah PCLATH 8Ah PCLATH 10Ah PCLATH 18Ah PCLATH
0Bh INTCON 8Bh INTCON 10Bh INTCON 18Bh INTCON
0Ch PIR1 8Ch PIE1 10Ch EEDATA 18Ch EECON1
0Dh PIR2 8Dh PIE2 10Dh EEADR 18Dh EECON2
0Eh TMR1L 8Eh PCON 10Eh EEDATH 18Eh réservé
0Fh TMR1H 8Fh OSCCON 10Fh EEADRH 18Fh réservé
10h T1CON 90h OSCTUNE 110h 190h
11h TMR2 91h SSPCON2
12h T2CON 92h PR2
13h SSPBUF 93h SSPADD
14h SSPCON 94h SSPSTAT
15h CCPR1L 95h WPUB
16h CCPR1H 96h IOCB
17h CCP1CON 97h VRCON
18h RCSTA 98h TXSTA
19h TXREG 99h SPBRG
1Ah RCREG 9Ah SPBRGH
1Bh CCPR2L 9Bh PWM1CON
1Ch CCPR2H 9Ch ECCPAS
1Dh CCP2CON 9Dh PSTRCON
1Eh ADRESH 9Eh ADRESL
1Fh ADCON0 9Fh ADCON1
20h A0h 120h 1A0h
IRP FSR
0 00 1 00 SFR
SFR
1 0F (16)
(32)
0 1F 1 10
0 20 GPR
GPR (96)
(96) 1 6F
0 7F
0 80 1 80 SFR
SFR
1 8F (16)
0 9F
(32) 1 90
0 A0 GPR
GPR
(96)
(80)
0 EF 1 EF
0 FF 1 FF
page 0 page 1
Figure I-9 : 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
IRP FSR
pointeur 9 bits
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 [Link] 19
Chapitre II
AUTRES INSTRUCTIONS
CLRW Clear W Z 1
CLRWDT Clear Watchdoc timer TO', PD' 1
CALL etqt Branchement à un sous programme de label etqt 2
GOTO etqt branchement à la ligne de label etqt 2
NOP No operation 1
RETURN retourne d'un sous programme 2
RETFIE Retour d'interruption 2
RETLW K retourne d'un sous programme avec K dans W 2
SLEEP se met en mode standby TO', PD' 1
Microcontrôleur PIC16F887 [Link] 21
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 W
movf 35h,w ; Copier le contenu du GPR 35h dans l’accumulateur W
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
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
Btfss F,b ; bit test skip if set : teste le bit b du registre F et saute l’instruction suivante si le bit
testé est égal à 1
exemple :
sublw 100 ; 100 – W → W
btfss STATUS,Z ; tester le bit Z du registre STATUS et sauter une ligne si Z=1
clrf 70h ; le programme continue ici si Z=0
cmpf 70h,f ; le programme continue ici si Z=1
suite du programme
suite du programme
…
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.
deccfsz F,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.
22 LE JEUX D'INSTRUCTIONS DU PIC16F887
Instruction 1
Instruction 2
Goto bonjour
instruction 3
instruction 4
instruction 5
bonjour: instruction 6
instruction 7
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 ; aller à la ligne précédente
Instruction
Goto $+3 ; sauter 2 lignes
Instruction
Instruction
Instruction
Goto $ ; rester planté ici
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 [Link] 23
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.
F-W
oui
Z=1? F=W
non
C=1?
oui
F>W
non
F<W
Exercice 5)
Programme qui place les 4 octets suivants dans la RAM
35 dans la position 20h, 'A' dans la position A0h
-5 dans la position 110h, 35h dans la position 190h
Exercice 6)
Programme qui permute le contenu de la case A0h avec celui de la case 110h
Exercice 7)
Programme qui ajoute la valeur 4 au contenu des cases mémoires situées dans la zone [190h, 1ABh]
24 LE JEUX D'INSTRUCTIONS DU PIC16F887
Le nom du fichier peut être place entre "" ou entre <> mais ce n'est pas obligatoire
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.
CBLOCK 0x20
XX1, XX2, XX3, XX4
ENDC
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
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
26 LE JEUX D'INSTRUCTIONS DU PIC16F887
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’ ; le compilateur remplace cette ligne par lignes ci-dessous
RETLW .10
RETLW 35h
RETLW 'H'
RETLW 'e'
RETLW 'l'
RETLW 'l'
RETLW 'o'
Exemple :
CONFIG 0x2007 , 0x23E4
CONFIG 0x2008 , 0x3FFF
Nom_Macro macro
Instruction 1
Instruction 2
Instruction 3
…
endm
Exemple:
BANK0 macro
Bcf STATUS,RP0
Bcf STATUS,RP1
endm
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:
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.
28 LES OUTILS DE DEVELOPPEMENT
Chapitre III
5V
Port série
Vdd
TxD(3) MCLR
RTS(7) 22k RB6
PIC
DTR(4) 2.2k RB7
CTS(8) Vss
GND(5)
5V 5V 5V
Figure III-2 : PIC® en mode RUN, oscillateur interne, oscillateur à quartz, oscillateur RC
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 70h,1
goto looop
END
• Sauvegarder (file → save ) ce programme dans le dossier de votre chois sous le nom [Link]
• 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
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
[Link] dans le même dossier où se trouve [Link]. 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.
• Pour les switchs de configuration, on utilisera la configuration générique du paragraphe I.3.1, page
10. Les choix les plus importants sont WDT:OFF, LVP:OFF, horloge interne
CONFIG 0x2007 , 0x23E4
CONFIG 0x2008 , 0x3FFF
• Pour la fréquence, on choisira Fosc = 8 Mhz, à l'aide du registre OSCCON (bank1) (§I.4.6, page13) :
OSCCON = 0 111 000 1 = 0x71
Movlw 0x71
movwf 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 [Link] 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 [Link]
• 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
Programme ram_direct.asm
;==========================================================
; Accès à la RAM par l'adressage direct
;==========================================================
INCLUDE [Link]
LIST p=16f887, r=dec
CONFIG 0x2007 , 0x23E4
CONFIG 0x2008 , 0x3FFF
sleep
END
Figure III-4:
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 [Link]. On peut vérifier sur la Figure I-8 (page16)
que 0x3 est l'adresse du registre STATUS et sur le Tableau I-1 (page18) 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 instructions. 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 {⮧}
Exercice 8) macros
Ecrire les 4 macros. Les placer dans un fichier appelé [Link] et donner la version du
programme précédent en utilisant ces macros
movlw 5 ; N1=5
movwf 70h
ici: decfsz 70h,f
goto ici
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 dans le bank0 par exemple. W sert de paramètre d'entrée.
tempo1: BANK0
movwf AN1
Microcontrôleur PIC16F887 [Link] 35
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 valeur
Call tempo1
Pour le calcul il faut rajouter 2 cycles pour l'instruction call , 2 cycle pour les deux instructions de la
macro BANK0 et 2 cycles pour l'instruction return.
Exercice 13)
Dans le cas Fosc=8MHz, comment obtenir une temporisation voisine de 0.5 seconde
36 LES PORTS d’ENTRÉE SORTIES
Chapitre IV
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:
Certains ports ont quelques particularités que nous allons détailler ci-dessous,
ANSEL
ANS7 ANS6 ANS5 ANS4 ANS3 ANS2 ANS1 ANS0
PORTE
RE2 RE1 RE0
RE3
AN7 AN6 AN5
PORTA
RA5 RA3 RA2 RA1 RA0
RA7 RA6 RA4
AN4 AN3 AN2 AN1 AN0
ANSELH
ANS13 ANS12 ANS11 ANS10 ANS9 ANS8
PORTB
RB5 RB4 RB3 RB2 RB1 RB0
RB7 RB6
AN13 AN11 AN9 AN8 AN10 AN12
Figure IV-2: Control des entrée-Sorties Analogique/Numériques
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 775 × 0.5µs = 387.5 µs, largement insuffisant
• Avec tempo2 on obtiendrait au maximum 197127 × 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 + 7 ) ×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, (§Erreur ! Source du
envoi introuvable., pageErreur ! Signet non défini.)
• Pour choisir Fosc = 8 Mhz, il faut configurer le registre OSCCON (bank1) (I.4.6Erreur ! Source du
envoi introuvable., page13)
OSCCON = 0 111 000 1 = 0x71
movlw 0x71
movwf OSCCON
• Il faut configurer la broche RA3 en Numérique à l'aide du registre ANSEL (bank3) (IV.1,§IV.1,
page36) 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.
[Link]
INCLUDE [Link]
LIST p=16f887, r=dec
Microcontrôleur PIC16F887 [Link] 39
END
Saisir ce programme, le sauvegarder sous le nom [Link], 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.
5V
PIC
1k
Vdd
MCLR RA3
Vss 1k
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 [Link] qu'il suffira d'inclure après le programme principal juste
avant la directive END
40 LES PORTS d’ENTRÉE SORTIES
Plus tard, chaque fois que nous écrirons de nouvelles fonctions susceptibles d'être réutilisées, nous
les ajouterons au fichier [Link]. 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 = X¯
Exercice 15)
Dans les deux programmes précédents, supprimer l'instruction
Vrelai
Vdd=5V
220V
PIC Relai
1k
Vdd
R=4.7k
MCLR RA3 2N2222
Lampe
Vss
Exercice 16)([Link])
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
Microcontrôleur PIC16F887 [Link] 41
a b c d e f g
CC
Cathode Commune Anode commune
Figure IV-5 : organisation interne des afficheurs sept segments
Pour piloter un afficheur sept segments, on a besoin d'un décodeur bcd-7segments 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
a
A b
Décodeur c
B
Bcd d
C
7segments e
D f
g
g f e d c b a
CC
Pour un afficheur anode commune (figure ci-dessous), 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
Vcc
a b c d e f g
a
A b
Décodeur c
B
Bcd d
C
7segments e
D f
g
Avec le PIC®, on n'a pas besoin de décodeur bcd-7segments. 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.
5V Dec g f e d c b a
0 1 0 0 0 0 0 0 40h
AC 1 1 1 1 1 0 0 1 79h
a
RC0 a 2 0 1 0 0 1 0 0 24h
b 3 0 1 1 0 0 0 0 30h
RC1
c f b 4 0 0 1 1 0 0 1 19h
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
f 8 0 0 0 0 0 0 0 00h
RC5 9 0 0 1 0 0 0 0 10h
g d
RC6 A 0 0 0 1 0 0 0 08h
Figure IV-8: 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.
Microcontrôleur PIC16F887 [Link] 43
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
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 PCL,f ; ajouter le contenu de W au Compteur programme
retlw 40h
retlw 79h
retlw 24h
retlw 30h
retlw 19h
retlw 12h
retlw 02h
retlw 78h
retlw 00h
retlw 10h
retlw 08h
retlw 03h
retlw 46h
retlw 21h
retlw 06h
retlw 0Eh
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 PCL,f ; ajouter le contenu de W au Compteur programme
DT 40h,79h,24h,30h,19h,12h,02h,78h,00h,10h,08h,03h,46h,21h,06h,0Eh
Exercice 19)[Link]
Programme qui affiche un compteur modulo 16 (de 0 à F) sur l'afficheur 7 segments avec une
temporisation voisine d'une seconde
Exercice 20)([Link])
Modifier le programme [Link] pour obtenir un compteur modulo 10
44 LES PORTS d’ENTRÉE SORTIES
VDD
VSS
VEE
utiliser la commande Cursor or display shift pour déplacer
RW
RS
D7
D0
D1
D2
D3
D4
D5
D6
E
l'affichage à gauche ce qui revient à déplacer la fenêtre à
1
2
3
4
5
6
7
8
9
10
11
12
13
14
droite. Les adresse du premier caractère de chaque lignes
son respectivement 0 et 64. Pour les afficheurs quatre lignes
(4×20) les adresses du premier caractère de chaque ligne sont 0, 64, 20 et 84.
VEE
RW
RS
D0
D1
D2
D3
D4
D5
D6
D7
E
1
2
3
4
5
6
7
8
9
10
11
12
13
14
50%
lcd_init: Initialisation de l'afficheur. Doit être invoquée avant tout accès à l'afficheur
lcd_char: Affiche le caractère présent dans W à la position du curseur
lcd_cmd: Envoie l'octet de commande présent dans W
lcd_locate: Positionne le curseur à la position présente dans W
lcd_clrscr : Efface l'écran
lcd_byte_d : affiche l'octet présent dans W en décimal
lcd_byte_h : affiche l'octet présent dans W en Hexadécimal
lcd_word_d: Affiche le word présent dans les variables AH, AL en décimal
Microcontrôleur PIC16F887 [Link] 45
RADIX dec
INCLUDE [Link]
CONFIG 2007h,23E4h
CONFIG 2008h,3FFFh
INCLUDE ../lib/[Link]
movlw 'P'
call lcd_char
movlw 'I'
call lcd_char
movlw 'C'
call lcd_char
movlw '1'
call lcd_char
movlw '6'
call lcd_char
movlw 'F'
call lcd_char
movlw '8'
call lcd_char
movlw '8'
call lcd_char
movlw '7'
call lcd_char
movlw .64
call lcd_locate ; curseur début 2ème ligne
movlw .200
call lcd_byte_d ; afficher le nombre 200
movlw ''
call lcd_char
sleep
INCLUDE ../lib/PIC_lib.inc
END
Exercice 22)LCD_shift.asm
En utilisant les commandes de l'afficheur (voir tableau ci-dessus) et la fonction lcd_cmd, Choisir un
curseur clignotant et le placer au milieu de la 2ème ligne
48 LES MÉMOIRES PERMANENTES
Chapitre V
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 [Link] 49
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.
1) Interdire les interruptions (si elles ont été validées avant : bit [Link])
2) Mettre le bit EEPGD à 0 pour pointer sur la EEPROM de donnée
3) Positionner le bit WREN pour autoriser l'écriture dans la EEPROM de donnée
4) Faire les opérations suivantes pour chaque octet
a) Placer l’adresse relative de la position à écrire dans EEADR
b) Placer la donnée à écrire dans le registre EEDAT
c) - Ecrire 55h dans EECON2 (commande de process hardwares)
d) - Ecrire AAh dans EECON2 (commandes de process hardwares)
e) - Positionner le bit WR pour démarrer l'opération d'écriture,
f) Attendre que WR revienne à 0 (≈ 10ms) avant de pouvoir accéder de nouveau à la EEPROM
Les étapes c), d) et e) doivent obligatoirement être exécutées dans cet ordre et ne doivent pas être
interrompues par une interruption.
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.
Exercice 23)
Ecrire l'alphabet dans l'EEPROM de donnée à partir de la position 20h
50 LES MÉMOIRES PERMANENTES
Exercice 25)(lcd_puts.asm)
Programme qui utilise la directive DE pour écrire une chaine dans la EEPROM de données. La chaine
doit se terminer par le caractère Null (code ASCII 0). Le programme doit ensuite lire les caractères de
cette chaine à partir de la EEPROM et les affiche sur l’afficher LCD.
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 ( all) GIE PEIE T0IE INTE RBIE T0IF INTF RBIF
PIE1 (bank1) - ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE
PIR1 (bank0) - ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF
PIE2 (bank1) OSFIE C2IE C1IE EEIE BCLIE ULPWUIE - CCP2IE
PIR2 (bank0) OSFIF C2IF C1IF EEIF BCLIF ULPWUIF - CCP2IF
IOCB (bank1) IOCB7 IOCB6 IOCB5 IOCB4 IOCB3 IOCB2 IOCB1 IOCB0
OPTION_REG(bk1) INTEDG
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.
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é.
GIE
RCI Un Octet est reçu sur l'USART RCIE PEIE RCIF
GIE
TXI Fin transmission d'un octet sur l'USART TXIE PEIE TXIF
GIE
TMR1I Débordement de Timer TMR1 TMR1IE TMR1IF
PEIE
GIE
TMR2I Timer TMR2 a atteint la valeur programmée TMR2IE PEIE TMR2IF
GIE
CCP2I Capture/comparaison de TMR1 avec module CCP2 CCP2IE PEIE CCP2IF
GIE
EEI Fin d'écriture en EEPROM EEIE PEIE EEIF
GIE
CCLI Collision sur bus SSP en mode I2C BCLIE PEIE BCLIF
INTE . Déclenchement de
l'interruption
GIE
Attention:
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 ).
La levé du drapeau RBIF de cette interruption peut sortir le PIC du mode sleep si le bit de validation
RBIE a été positionné au préalable.
Les autres interruptions seront abordées au moment de l'étude des modules qui les déclenchent.
PIC
RB0 RB1
1k
LED
Figure VI-1:
54 LES INTERRUPTIONS
Exercice 29)[Link]
Programme qui fait sonner 5 fois l'alarme branchée sur RA5 chaque fois qu'un des 3 capteurs branchés
sur RB0, RB3 et RB7 est actionné
C1 RB0 PIC
C2 RB3 RA5
C3 RB7
Figure VI-2
PIC
RB5 RB4
PORTD PORTC
DIV
Chapitre VII
LES TIMERS
T0SE T0CS
PSA TF0
TH
RA4 1
1
T0
0 1
TMR0 T0IF
0 Prédiviseur 0
Générateur programmable
D’horloge ÷4
Fosc/4 TF0 = 256 x (DIV x TH)
Fosc
PS2 PS1 PS0
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)
[Link]
;=======================================================================
; 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 [Link]
INCLUDE [Link]
LIST p=16f887, r=dec
CONFIG 0x2007 , 0x23E4
CONFIG 0x2008 , 0x3FFF
END
Microcontrôleur PIC16F887 [Link] 57
[Link]
;=======================================================================
; 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 [Link]
INCLUDE [Link]
LIST p=16f887, r=dec
CONFIG 0x2007 , 0x23E4
CONFIG 0x2008 , 0x3FFF
CTR equ 0x70
END
58 LES TIMERS
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 :
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 32)
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
Exercice 33)
Si le PIC est cadencé par l’horloge Fosc= 8 MHz, Proposer une combinaison des variables CTR, PREDIV,
POSTDIV, PR2 pour avoir un temps de 0.5 s
Exercice 34)
Programme pour faire clignoter une LED branchée sur RB4 au rythme de la ½ seconde. Le PIC est
cadencé par l'horloge interne Fosc=8MHz.
Exercice 35)
On dispose d'un PIC doté d'un quartz de 8 MHz. Donner le programme qui génère le signal ci-dessous
sur la sortie RB2. On écrira deux versions du programme :
a) On scrute nous même le drapeau TMR2IF à l'aide de l'instruction btfss,
b) On exploite l'interruption TMR2I.
100 µs 100 µs
60 LES TIMERS
[Link]
;=======================================================================
; 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 [Link]
INCLUDE [Link]
LIST p=16f887, r=dec
CONFIG 0x2007 , 0x23E4
CONFIG 0x2008 , 0x3FFF
CTR EQU 70h
org 0
goto main
END
Microcontrôleur PIC16F887 [Link] 61
T1 T2 T1 T2
20 µs 50 µs
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 36)
Ecrire le programme qui permet de générer le signal de la figure ci-dessus
62 LE MODULE DE CONVERSION ANALOGIQUE NUMÉRIQUE
Chapitre VIII
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>
0000
AN0/RA0
RA3/VREF+ Vdd
0001
AN1/RA1
ADCON0
0010
AN2/RA2
1 0 ADCON1
0011
AN3/RA3 GO/DONE VCFG0
0100
AN4/RA5 Vref+
Start
0101
AN5/RE0
0110 S
AN6/RE1 ADRESL
0111
AN7/RE2 ADCS1 ADCS0 CAN ADRESH
1000 Tosc
AN8/RB2
Fosc DIV
1001 CLK
AN9/RB3 MXR
1010
AN10/RB1 Tad Vref-
1011 Oscillateur
AN11/RB4 RC dédié
VCFG1
1100 1 0
AN12/RB0
1101
AN13/RB5
1110
CVREF
1111 RA2/VREF- Vss
FVREF
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 [Link] 63
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 VREF-
Le 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
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
GO/DONE : En plaçant ce bit à 1, on démarre une Conversion. A la fin de la conversion, ce bit revient
automatiquement à 0
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
Ve
Va
S
Va Ve
CAN
10 pF
2Tad
12Tad Tacq
GO/DONE
nous automatique
Figure VIII-2 : déroulement d'une conversion
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 :
TAD = Div × Tosc
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.
Fosc
ADCS1 ADCS0 Div 20Mhz 5Mhz 8MHz 4Mhz 2Mhz 1Mhz
Microcontrôleur PIC16F887 [Link] 65
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
Valeur nominale :
Ric = 1kΩ, Rss = 7k, Rs ≈ 2kΩ, Tp = 50 °C :
Tc = 10kΩ x 10pF x Ln(2047) = 0,76 µs
CT = 25 x 0.05 µs = 1.25 µs
exemple :
Vref+ = Vdd = 5V, Vref- = 0, Va = 4 V
Q = 5V/1024 = 0,0048828125 V
N = 4V \ 0,0048828125V = 819
Exercice 37)
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.
Exercice 38)
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.
Exercice 39)
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
Microcontrôleur PIC16F887 [Link] 67
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
TXREG
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 chargement
TXREG→TSR 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.
RX9D RCREG
9b0 Octet 0
9b1 Octet 1
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 reçoivent 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.
72 L'USART
M Fosc M Fosc
vitesse = baud R = -1
64 (R + 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 BRGH M R
0 0 1 SPBRG
précision 8 bits
0 1 4 SPBRG
1 0 4 SPBRGH:SPBRG
précision 16 bits
1 1 16 SPBRGH:SPBRG
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
Vitesse 1MHz 4MHz 8MHz 20MHz
désirée SPBRG Obtenue Err% SPBRG Obtenue Err% SPBRG Obtenue Err% SPBRG Obtenue Err%
300 51 300 0,00 207 300 0,00
1200 12 1202 0,17 51 1202 0,17 103 1202 0,17 255 1221 1,75
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
Vitesse 1MHz 4MHz 8MHz 20MHz
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
1MHz 4MHz 8MHz 20MHz
Vitesse SPBRGH Err SPBRGH Err SPBRGH Err SPBRGH Err
désirée SPBRG Obtenue % SPBRG Obtenue % SPBRG Obtenue % SPBRG Obtenue %
300 0 207 300 0 3 64 300 0 6 130 300 0 16 70 300 0
1200 0 51 1202 0,17 0 207 1202 0,17 1 160 1199 -0,08 4 17 1200 0
2400 0 25 2404 0,17 0 103 2404 0,17 0 207 2404 0,17 2 8 2399 -0,04
4800 0 12 4808 0,17 0 51 4808 0,17 0 103 4808 0,17 1 3 4808 0,17
9600 0 25 9615 0,16 0 51 9615 0,16 0 129 9615 0,16
19200 0 12 19231 0,16 0 25 19231 0,16 0 64 19231 0,16
57600 0 8 55556 -3,55 0 21 56818 -1,36
115200 0 10 113636 -1,36
Figure IX-7 : quelques exemples avec BRG16 = 1, BRGH = 0
Microcontrôleur PIC16F887 [Link] 73
Fosc
1MHz 4MHz 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
Exercice 40)
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 41)
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.