PIC16F84
PIC16F84
PIC16F84
Les microcontrôleurs
PIC
de Microchip
Le 16F84
2
Sommaire
INTRODUCTION ...................................................................................................................... 3
I Le PIC 16F84 ....................................................................................................................4
I.1 Aspect externe du 16F84 ............................................................................................4
I.2 La mémoire programme (flash) ...................................................................................5
I.3 La mémoire RAM - Rrgistres........................................................................................5
I.4 L'ALU et le registre W .................................................................................................5
I.5 L'Horloge ...................................................................................................................6
I.6 Le ports d' E/S PORTA ................................................................................................6
I.7 Le ports d' E/S PORTB ................................................................................................7
I.8 Le Timer TMR0 ..........................................................................................................7
I.9 Le Timer Watchdog WDT (Chien de garde) ..................................................................8
I.10 Le mode SLEEP ..........................................................................................................8
I.11 La mémoire EEPROM de configuration .........................................................................9
I.12 La mémoire EEPROM de données................................................................................9
I.12.1 Procédure de lecture dans l'EEPROM de données ................................................ 10
I.12.2 Procédure d'écriture dans l'EEPROM de données ................................................. 10
I.13 Les interruptions ...................................................................................................... 10
I.13.1 Déroulement d'une interruption ......................................................................... 10
I.13.2 L'interruption INT (Entrée RBO DU PORTB) ........................................................ 11
I.13.3 L'interruption RBI (RB4 A RB7 DU PORTB).......................................................... 11
I.13.4 L'interruption T0I : Débordement du Timer TMR0 ............................................... 11
I.13.5 L'interruption EEI : Fin d'écriture dans l'EEPROM................................................. 11
I.14 L'adressage indirect.................................................................................................. 11
I.15 Le conteur programme ............................................................................................. 11
I.15.1 GOTO calculé.................................................................................................... 12
I.16 Les indicateurs ......................................................................................................... 12
I.17 Les instructions du 16F84 ......................................................................................... 12
I.17.1 Les instructions « orientées octet » (adressage direct) ........................................ 12
I.17.2 Les instructions « orientées bits » ...................................................................... 13
I.17.3 Les instructions opérant sur une donnée (adressage immédiat) ........................... 13
I.17.4 Les instructions de saut et appel de procédures .................................................. 13
I.17.5 Le jeu d'instructions .......................................................................................... 14
I.17.6 Etat de quelque registre à l'initialisation.............................................................. 14
II Les outils de développement ............................................................................................ 15
II.1 Deux mot sur MPLAB ................................................................................................ 15
II.2 Les directives de MPASM .......................................................................................... 16
II.2.1 Les directives les plus utilisées ........................................................................... 16
II.3 Format des nombres ................................................................................................ 17
II.4 Structure d'un programme écrit en assembleur .......................................................... 17
II.5 Exemples de programme .......................................................................................... 19
II.6 Références............................................................................................................... 22
3
INTRODUCTION
Un PIC est un microcontrôleur, c’est une unité de traitement de l’information de type
microprocesseur à laquelle on a ajouté des périphériques internes permettant de faciliter
l'interfaçage avec le monde extérieur sans nécessiter l’ajout de composants externes.
Les PICs sont des composants RISC (Reduce Instructions Construction Set), ou encore
composant à jeu d’instructions réduit. L'avantage est que plus on réduit le nombre d’instructions,
plus facile et plus rapide en est le décodage, et plus vite le composant fonctionne.
La famille des PICs est subdivisée en 3 grandes familles : La famille Base-Line, qui utilise des
mots d’instructions de 12 bits, la famille Mid-Range, qui utilise des mots de 14 bits (et dont font
partie la 16F84 et 16F876), et la famille High-End, qui utilise des mots de 16 bits.
- C indique que la mémoire programme est une EPROM ou plus rarement une EEPROM
- CR pour indiquer une mémoire de type ROM
- F pour indiquer une mémoire de type FLASH.
• On trouve ensuite un nombre qui constitue la référence du PIC.
• On trouve ensuite un tiret suivi de deux chiffres indiquant la fréquence d’horloge maximale que
le PIC peut recevoir.
Donc, un 16F84-04 est un PIC Mid-Range donc la mémoire programme est de type FLASH de
référence 84 et capable d’accepter une fréquence d’horloge de 4MHz.
Notez que les PICs sont des composants STATIQUES, c’est à dire que la fréquence d’horloge
peut être abaissée jusque l’arrêt complet sans perte de données et sans dysfonctionnement. Une
version –10 peut donc toujours être employée sans problème en lieu et place d’une –04. Pas
l’inverse, naturellement.
I LE PIC 16F84
Les caractéristiques principales du 16F84 sont :
• Une mémoire programme de type flash de 1K (1024) mots de 14 bits
• Une mémoire RAM constituée :
o Des registres de control SFR (Special Function Registers)
o 68 octets de RAM utilisateur appelés aussi GPR (General Propose Resisters)
• Une mémoire EEPROM de donnée de 64 octets
• Deux ports d'entrée sortie, un de 8 bits et un de 5 bits
• Un timer/Compteur cadencé par une horloge interne ou externe
• Un chien de garde / compteur qui est un timer particulier
• Un prédiviseur de fréquence programmable permettant d'étendre les possibilités du Timer
TMR0 et du chien de garde WDT
• 4 sources d'interruption
• L'horloge peut être générée par 4 types d'oscillateurs sélectionnables
• Protection de code
• Fonctionnement en mode sleep pour réduction de la consommation
• Programmation par mode ICSP (In Circuit Serial Programming)
W 14 bits : config
PORTA PORTB
RA2 1 18 RA1
RA3 2 17 RA0
RA4/T0CKI 3 16 OSC1
MCLR 4 PIC 15 OSC2
VSS 5 16F8X 14 Vdd
RB0/INT 6 13 RB7
RB1 7 12 RB6
RB2 8 11 RB5
RB3 9 10 RB4
Fig. I-1 : brochage du 16 F84
5
Pour la mémoire utilisateur, l'utilisation des pages (Bank ) n'est pas nécessaire puisque le Bank
1 est "mapped" avec le Bank0. Cela signifie qu'écrire une donnée à l'adresse 0CH ou à l'adresse
8CH revient au même.
I.5 L'Horloge
L'horloge peut être soit interne soit externe.
L'horloge interne est constituée d'un oscillateur à
quartz ou d'un oscillateur RC.
Avec un quartz de 4 MHz, on obtient une horloge instruction de 1 MHz, soit le temps pour
exécuter une instruction de 1µs.
La broche RA4 est multiplexée avec l'entrée horloge du timer TMR0, elle peut donc être utilisée
soit comme E/S normale du port A, soit comme entrée horloge pour le Timer TMR0, le choix se fait
à l'aide du bit T0CS du registre OPTION_REG.
• T0CS = 0 Æ RA4 est une E/S normale
• T0CS = 1 Æ RA4 = horloge externe pour le timerTMR0 Vdd
RA4 est une E/S à drain ouvert, si on veut l'utiliser comme sortie (pour
allumer une LED par exemple), il ne faut pas oublier de mettre une 1k
RA4
résistance externe vers Vdd. Le schéma ci contre illustre (pour les non
électronicien) 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
LED
masse. Si RA4 est placée à 1, l'interrupteur est ouvert, la sortie est
déconnectée d'où la nécessite de la résistance externe pour amener le
courant de l'alimentation vers la LED. (la valeur de 1k est donnée à titre
indicatif, à vous d'ajuster selon votre application)
Registre OPTION_REG RBPU INTEDG TOCS TOSE PSA PS2 PS1 PS0
7
• 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 chois de l'horloge
se fait à l'aide du bit T0CS du registre OPTION_REG
o TOCS = 0 Æ horloge interne
o TOCS = 1 Æ horloge externe appliquée à RA4
• Dans le cas de l'horloge externe, on peut choisir le front sur lequel le TIMER s'incrémente.
o TOSE = 0 Æ incrémentation sur fronts montants
o TOSE = 1 Æ incrémentation sur fronts descendants PS2 PS1 PS0 Div
0 0 0 2
• Quelque soit l'horloge choisie, on peut la passer dans un diviseur de 0 0 1 4
fréquence programmable (prescaler) dont le rapport est fixés par les
0 1 0 8
bits PS0, PS1 et PS2 du registre OPTION_REG (tableau ci-contre).
0 1 1 16
L'affectation ou non du prédiviseur se fait à l'aide du bit PSA du
registre OPTION_REG 1 0 0 32
o PSA = 0 Æ on utilise le prédiviseur 1 0 1 64
o PSA = 1 Æ pas de prédiviseur (affecté au chien de garde) 1 1 0 128
1 1 1 256
• 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,
l'incrémentation est inhibée pendant deux cycles instruction
• Au débordement de TMR0 (FF Æ 00), le drapeau T0IF est placé à 1. Ceci peut déclencher
l'interruption T0I si celle-ci est validée
Registre OPTION_REG RBPU INTEDG TOCS TOSE PSA PS2 PS1 PS0
T0SE T0CS
PSA
RA4 1
1
TMR0 T0IF
0
Prédiviseur 0
Horloge
÷4 programmable
Système Fosc/4
Fosc
PS2 PS1 PS0
8
L'horloge du WDT est ajustée pour que Le Time-Out arrive toutes les 18 ms. Il est cependant
possible d'augmenter cette durée en faisant passer le signal Time-Out dans un prédiviseur
programmable (partagé avec le timer TMR0). l'affectation se fait à l'aide du bit
PSA du registre OPTION_REG PS2 PS1 PS0 Div
o PSA = 1 Æ on utilise le prédiviseur 0 0 0 1
o PSA = 0 Æ pas de prédiviseur (affecté à TMR0) 0 0 1 2
0 1 0 4
Le rapport du prédiviseur est fixé par les bits PS0, PS1 et PS2 du registre 0 1 1 8
OPTION_REG (voir tableau ci-contre) 1 0 0 16
1 0 1 32
L'utilisation du WDT doit se faire avec précaution pour éviter la 1 1 0 64
réinitialisation (inattendue) répétée du programme. Pour éviter un WDT 1 1 1 128
timeOut lors de l'exécution d'un programme, on a deux possibilités :
• Inhiber le WDT d'une façon permanente en mettant à 0 le bit WDTE dans l'EEPROM de
configuration
• Remettre le WDT à 0 périodiquement dans le programme à l'aide de l'instruction CLRWDT pour
éviter qu'il ne déborde
PSA
0 0
Horloge
WDT WDT WDT timeout
1 Prédiviseur 1
programmable
L'utilisation des interruptions pour réaliser un WAKE-UP doit être utilisée avec précaution. Voir
le data sheet [1][2] du 16F84 pour plus de précisions.
13 12 11 10 9 8 7 6 5 4 3 2 1 0
CP CP CP CP CP CP CP CP CP CP PWRTE WDTE FOSC1 FOSC0
La durée d’écriture d’un octet est de l’ordre de 10 ms, la fin de chaque écriture réussie est
annoncé par le drapeau EEIF et la remise à zéro du bit RW du registre EECON1. Le drapeau EEIF
peut déclencher l'interruption EEI si elle a été validée.
EECON2 n’en est pas véritablement un Registre. Microchip l’utilise en tant que registre de
commande. L’écriture de valeurs spécifiques dans EECON2 provoque l’exécution d’une commande
spécifique dans l’électronique interne du PIC.
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 RETFI
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 dans les mêmes conditions où il l'a laissé.
PCH PCL
• PCL (8 bits) est la partie basse de PC, il est accessible en lecture écriture
• PCH (5 bits) est la partie haute de PC, il n'est pas accessible directement. On peut toutefois le
modifier indirectement à l'aide du registre PCLATH qui est une registre SFR accessible en
lecture écriture et où seuls 5 bits sont utilisés.
PCH PCL
Dans les instructions de branchement, l'adresse de destination est codée sur 11 bits. Lors de
l'exécution de telles instruction, les 11 bits sont copiés dans PC les deux bits manquants sont pris
dans PCLATH. Pour le 16F84, On n'aura pas besoin de ces bits car pour adresser 1024 lignes de
programme, seuls 10 bits du Programme Counter sont utilisés.
PC
• C (Carry) : ce bit Il passe à "1" lorsque le résultat d'une opération dépasse la valeur FF ou si
le résultat est négatif.
• DC (Digital Carry) : ce bit passe à "1" lorsque une retenue s'est produite entre les bit 3 et 4.
• Z (Zero) : Ce bit passe à "1", pour indiquer que le résultat de l'opération est nul.
- 6 bits pour l’instruction : logique, car comme il y a 35 instructions, il faut 6 bits pour pouvoir
les coder toutes
- 1 bit (d) pour indiquer si le résultat obtenu doit être conservé dans le registre de travail
(accumulateur) W de l’unité de calcul (W pour Work) ou sauvé dans un registre F (F pour File).
Problème ! 7 bits ne donnent pas accès à la mémoire RAM totale, donc voici l’explication de la
division de la RAM en deux banks. Pour remplacer le bit manquant, on utilise le bit RP0 du registre
STATUS.
Bien qu'on ne l'utilise pas sur le 16F84, le bit RP1 est aussi réservé pour le changement de
bank, le 16F876 par exemple possède 4 banks.
INSTRUCTIONS GENERALES
CALL L Branchement à un sous programme de label L 2
GOTO L branchement à la ligne de label L 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
Nous allons réaliser un tout petit programme sans grand intérêt pour voir la procédure de
fonctionnement (avec MPLAB 6.30)
• Debugger → Select tool → MPLAB SIM (à faire une fois après installation de MPLAB)
• Configure → Select Device → PIC16F64A
• Ouvrir une nouvelle fenêtre (de l'éditeur) pour commencer à écrire un programme : file Æ
new ou cliquez sur l'icône feuille blanche
• Taper le petit programme ci-dessous dans la fenêtre qui vient de s'ouvrir. Ce programme
incrémente sans fin la position mémoire (RAM) 0CH
• Sauvegarder (file Æ save ) ce programme dans la directory de votre chois sous le nom
bidon.asm
• Nous pouvons maintenant exécuter notre programme en simulation pour voir s'il réalise bien la
tache demandée :
16
- Ouvrez la fenêtre qui visualise la mémoire RAM : view Æ FileRegisters. La case mémoire
0x0C se trouve sur la première ligne (ligne:0000, colonne:0C)
- Exécuter maintenant le programme PAS à PAS en cliquant à chaque fois sur le bouton Step
Into {"} en observant la case mémoire 0C . (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
• LIST : permet de définir un certain nombre de paramètres comme le processeur utilisé (p), la
base par défaut pour les nombres (r), le format du fichier hex à produire (f) ainsi que d'autres
paramètres. Exemple :
LIST p=16F84A, r=dec, f=inhx8m
• INCLUDE : permet d'insérer un fichier source. Par exemple le fichier p16f84A.inc contient la
définition d'un certain nombre de constante comme les noms des registres ainsi que les noms
de certain bits;
INCLUDE "p16f84A.inc"
• __CONFIG : permet de définir les 14 fusibles de configuration qui seront copié dans l'EEPROM
de configuration lors de l'implantation du programme dans le PIC (protection de code, type
d'oscillateur, chien de garde et temporisation du départ)
__CONFIG B'11111111111001'
__CONFIG H'3FF9'
si le fichier p16f84.inc a été inséré, on peut utiliser les constantes prédéfinies :
__CONFIG _CP_OFF & _XT_OSC & _PWRTE_OFF & _WDT_OFF
• ORG : définit la position dans la mémoire programme à partir de laquelle seront inscrites les
instructions suivantes.
• DE : pour 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
ORG 0x2100
DE "Programmer un PIC, rien de plus simple", 70, 'Z'
On peut à l'aide de la directive LIST ou RADIX définir Base Préfixe Exemple (36)
un format par défaut. Si par exemple on place une des Décimal D'nnn' D'36'
instructions suivantes au début du programme, tous les .nnn .36
nombres sans préfix seront interprétés en décimal : Hexadécimal H'nn' H'24'
LIST r = dec 0xnn 0x24
RADIX dec nnh 24h
(les radix valables sont dec, hex ou oct) Binaire B'….' B'00100100'
Octal O'nnn' O'44'
• Tout ce qui commence à la première colonne est considéré comme une étiquette (label)
permettant de faire des renvois et aussi des assignations de constantes et de variables.
• tout ce qui suit un point virgule est considéré comme un commentaire non interprété par le
compilateur
• Il existe différentes écoles indiquant comment doit être organisé un programme. Voici un
exemple d'organisation :
2) Configuration, exemple :
4) Si le programme utilise des interruptions, mettre à l'adresse 0000 (adresse du RESET) une
instruction de branchement au début du programme principal :
org 0
goto debut
ORG 4
écrire la routine d'interruption ici
RETFIE
Si le programme est configuré pour interdire les interruptions, on peut se passer des
étapes 4) et 5),
6) Ecrire les sous programmes (s'il y en a). Chaque procédure commence par une étiquette
qui représente son nom, et se termine par l'instruction RETURN
7) Ecrire le programme principal (commençant par l'étiquette début: si les étapes 4 et 5 sont
présentes)
end
;***********************************************************************************************************************************
; programme led-tmr0-1.asm
; faire clignoter une LED connectée sur une sortie du port B, la temporisation permettant d'ajuster la fréquence
; est obtenue par scrutation des débordement du timer TMR0
;***********************************************************************************************************************************
LIST p=16f84A, f = inhx8m, r = dec
__CONFIG_CP_OFF & _XT_OSC & _PWRTE_OFF & _WDT_OFF
INCLUDE "p16f84A.inc"
end
20
;************************************************************************************************************************
; programme led-tmr0-2.asm
; faire clignoter une LED connectée sur une sortie du port B. La temporisation permettant d'ajuster la
; fréquence est obtenue en comptant les débordements du timer TMR0 à l'interieur de l'interruption T0I
; TMR0 est utilisé en timer avec un prédiviseur de 256. En comptant 5 débordement on obtient une
; temporisation de 4 x 256 x 256 µs
;**********************************************************************************************************************
list p=16f84,f=inhx8m,r=dec
__config _PWRTE_OFF & _CP_OFF & _WDT_OFF & _XT_OSC
#include "p16f84.inc"
;********************************************************************************************************************
; Clignotement d'une LED reliée à la sortie 0 du port B. Les autres bits du port B ne sont pas affectés
; La temporisation est réalisée à l'aide du Watchdog timer
;*********************************************************************************************************************
list p=16f84, f=inhx8m, r = dec
__config _PWRTE_OFF & _CP_OFF & _WDT_ON & _XT_OSC
#include "p16f84A.inc"
end
;***************************************************************************
; Clignotement d'une LED reliée à n'importe quelle sortie du port B. La temporisation est réalisée à l'aide d'une boucle de
; retard à base de 3 boucles imbriquées N1 (256), N2 (256), N3 (à préciser)
; T1 : (N1-1) x (1+2) + 2 => N1=0=256 => T1 = 767 µs
; T2 : T1 + (N2-1) x (1+2+T1) + 2, N2=0 => T2 = 196352 µs
; T3 : T2+(N3-1) x (1+2+T2) + 2 + 2 = N3 x 196355 + 1 µs (je croix)
;***************************************************************************
list p=16f84, f=inhx8m, r=dec
#include "p16f84A.inc"
__config _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_OFF
;=================================Procédure de temporisation
tempo: movwf N3 ; copier W dans N3
tmp decfsz N1,f ; boucle intérieure
goto tmp
decfsz N2,f ; boucle médiane
goto tmp
decfsz N3,f ; boucle extérieure
goto tmp
return
end
22
II.6 Références
[1] PIC16F8X, document DS30430C, www.microchip.com
[2] PIC16F84a, document DS35007A, www.microchip.com
[3] Programmation des PIC, Première partie-PIC16F84-Révision 5, par BIGONOFF,
http://www.abcelectronique.com/bigonoff/organisation.php?2654c