Comptines/Monsieur l'ours
Comptines/Il était une fermière
Comment démarrer avec un PIC16F84
"Un livre appartenant à la série Programmation
et à l'étagère Informatique de Wikilivres". 
Introduction.
Le but de ce petit manuel est d’arriver simplement à prendre un microprocesseur en main, ici un microcontroleur de type PIC® 16F84, en ayant un minimum d’informations utiles et quelques exemples concrets utilisables rapidement.
En un mot, réduire le temps de mise en route du premier projet lorsque l’on pratique déjà un autre type de processeur.
En effet, il n’est pas rare de devoir lire, relire et feuilleter des kilos de documentation pour trouver une information aussi simple que la description d’un registre ou la fonction d’un bit de ce registre.
Pour plus de détail, il faudra se reporter à la documentation constructeur.
Architecture, Horloge, Mémoire de Données et de Programme.
Architecture interne du PIC 16F84:.
Les Mémoire Données et Mémoire Programme ont deux bus internes séparés en architecture Harvard, ce qui permet ici à l’UC d’accéder à chaque bloc dans le même cycle d’horloge. 
Ce modèle d’architecture permet également de ne pas mélanger le code et par exemple les données utilisateur, ce qui ne simplifiera pas forcement la programmation, mais assure un degré d’intégrité des données supérieur au modèle Von Neumann (données et code cohabitant dans le même espace mémoire).
Horloge:.
Le cycle d’horloge interne est donné pour 1/4 de la fréquence nominale du quartz, soit:
Quartz de 4MHz => 4 MHz / 4 = 1 MHz interne => 1/1MHz = 1 µS de temps de cycle 
Quartz de 10MHz => 10 MHz / 4 = 2,5 MHz interne => 1/2,5MHz = 400 nS de temps de cycle 
Le PIC utilisé ici est un 16F84-04P, avec un quartz de 4MHz.
Le PIC ayant une structure interne de type RISC (Reduced Instruction Set Computer), la plupart des instructions s’exécutent en un seul cycle d’horloge. Chaque instruction va donc s’exécuter en un temps record. Par contre, le peu d’instructions disponibles engendrera quelquefois une programmation tortueuse demandant un grand nombre d’instructions simples, et donc aussi un temps de traitement rallongé.
Il faudra en tenir compte lors du choix du µC, sachant que son espace mémoire programme est limité à 1K.
Mémoire de Données :.
Les SFR (Registres internes à Fonctions Spéciales) sont répartis en deux banques:
 de 00h à 0Bh en Bank0 
 de 80h à 8Bh en Bank1.
Certains registres sont accessibles en Bank0, d’autres en Bank1 alors que d’autres sont communs aux deux banques (ils sont remappés).
Il est donc nécessaire de changer de Bank avant d’accéder à un registre particulier, ce changement de Bank s’effectuant à l’aide des bits RP1:RP0 du registre STATUS.
La RAM GPR (RAM utilisateur d’usage Général ou encore General Purpose Registers) de 68 octets va de 0Ch à 4Fh, soient 68 octets disponibles pour les variables du programme.
Cette RAM est remappée en Bank0 et Bank1, il s’agit donc des mêmes emplacements mémoires qui sont accessibles par les deux Banks à deux adresses différentes.
Ceci permet d’éviter d’avoir à changer de bank avant d’accéder à une variable ou à une autre.
La mémoire EEPROM est indirectement mappée dans la zone de données et est donc accessible par un pointeur d’adresse indirect. Ces 64 octets d’ EEPROM se situe de 00h à 3Fh.
La pile est un stack hard à 8 niveaux, sans contrôle de débordement.
Seuls huit niveaux de sous programmes sont donc utilisables, interruptions comprises.
Mémoire de Programme :.
La mémoire programme Flash contenant le programme a une capacité de 1K x 14 bits et se situe aux adresses 0000h à 03FFh.
Vecteurs.
Le Reset se situe à l’adresse 0000h,
L’ Interrupt se situe à l’adresse 0004h.
Il ne s’agit pas à proprement parler de vecteurs.
En effet, le PIC va démarrer son programme à l’adresse 0000h, et non pas à l’adresse contenue en 0000h comme dans un micro avec reset vectorisé.
De ce fait, l’instruction qui sera placée à l’adresse 0000h sera très souvent un GOTO xxxxh mais peut être une instruction quelconque faisant partie du corps du programme si l’interruption n’est pas utilisée.
INCORPORER TABLE VECTEUR
Registres internes.
Les registres SFR (Registres internes à Fonctions Spéciales) sont répartis en deux banques. Cette partie de mémoire est suivie par 68 registres d'usage général pouvant être utilisés comme mémoire simple qui sont identiques sur les deux banques. Ensuite vient une série de registre généraux qui eux dépendent de la banque mémoire choisie et qui ne sont pas implémenté dans le 16F84 original.
La mémoire du 16F84 est organisée en banques sélectionnées par le(s) bit(s) RP0 (et RP1) du registre STATUS. Seul RP0 est utilisé pour le 16F84, soit deux banques.
Les SFR (Registres internes à Fonction Spéciale) vont de 00h à 0Bh en Bank0 et de 80h à 8Bh en Bank1.
Bank 0
 00h INDF Utilisé en adressage indirect avec FSR, il ne s’agit pas d’un registre physique
 01h TMR0 Timer/Compteur 8 bits
 02h PCL Poids faible du compteur programme (PC)
 03h STATUS Registre d’état dont les bits sont : IRP RP1 RP0 TO PD Z DC C
 04h FSR Pointeur d’adresse en adressage indirect.
 05h PORTA Port d’Entrée/Sortie A dont les bits sont : x x x RA4/T0CKI RA3 RA2 RA1 RA0
 06h PORTB Port d’Entrée/Sortie B dont les bits sont: RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0/INT
 07h Pas utilisé
 08h EEDATA Registre de données de l’ Eeprom
 09h EEADR Registre d’adresses de l’ Eeprom
 0Ah PCLATH 5 bits de poids fort du compteur programme
 0Bh INTCON Registre des Interruptions dont les bits sont: GIE EEIE T0IE INTE RBIE T0IF INTF RBIF
Bank 1
 80h INDF Utilisé en adressage indirect avec FSR, il ne s’agit pas d’un registre physique
 81h OPTION_REG Registre d’options, bits : RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
 82h PCL Poids faible du compteur programme (PC)
 83h STATUS Registre d’état dont les bits sont : IRP RP1 RP0 TO PD Z DC C
 84h FSR Pointeur d’adresse en adressage indirect.
 85h TRISA Registre de Direction du Port A
 86h TRISB Registre de Direction du Port B
 87h Pas utilisé
 88h EECON1 Registre de Contrôle n°1 de l’ Eeprom : x x x EEIF WRERR WREN WR RD
 89h EECON2 Registre de contrôle n°2 de l’ Eeprom (il ne s’agit pas d’un registre physique)
 0Ah PCLATH 5 bits de poids fort du compteur programme
 0Bh INTCON Registre des ITs dont les bits sont: GIE EEIE T0IE INTE RBIE T0IF INTF RBIF
Certains registres sont accessibles en Bank0 et également en Bank1 (ils sont remappés).
Le changement de Bank s’effectue à l’aide de RP1:RP0 du registre STATUS:
</br>codice_1</br>
codice_2</br>(RP1 est utilisé pour la compatibilité avec d’autres PICS de la famille et restera à 0 sur le 16F84.)
Détail des registres internes.
STATUS (Bank 0 en 03h et Bank 1 en 83h).
Voici les bits du registre STATUS qui reflètent le status de l’ALU du PIC, le status du reset et permet également de changer de Bank de registres.
 b7: IRP non utilisé dans le 16F84
 b6-5: RP1 RP0 Sélection de la bank de registres active
 00: Bank0
 01: Bank1
 10: non utilisé sur le 16F84
 11: non utilisé sur le 16F84
 b4: TO\ Time Out du watch dog
 1: après un démarrage, CLRWDT ou SLEEP.
 0: après un time-out du watch dog
 b3: PD\ Power down bit
 1: après un démarrage ou après l’instruction CLRWDT
 0: après l’exécution de l’instruction SLEEP
 b2: Z bit Zero
 1: Résultat de l’opération précédente nul
 0: Résultat de l’opération non nul
 b1: DC Digital carry / borrow\
 1: Débordement du 4° bit du résultat de l’opération précédente
 0: Pas de débordement
 b0: C Carry / borrow\
 1: Débordement bit du résultat de l’opération précédente
 0: Pas de débordement
OPTION_REG (Bank 1 en 81h).
Permet de configurer les résistances de rappel internes du PortB, et aussi l’INT externe, le Timer0 et le prescaler du Timer0 ou du watch-dog
 b7: RBPU\ Résistances de rappel des entrées du PortB
 1: Les résistances sont désactivées
 0: Les résistances du PortB sont activées
 b6: INTEDG Sélection du front actif de l’INT externe
 1: Interruption sur le front montant de RB0/INT
 0: Interruption sur le front descendant de RB0/INT
 b5: TOCS Source de l’horloge du Timer0
 1: Comptage sur la pin RA4/TOCKI
 0: Comptage sur l’horloge interne CLKOUT
 b4: TOCE Sélection du front actif pour le comptage sur RA4/TOCKI
 1: Comptage sur front descendant
 0: Comptage sur front montant
 b3: PSA Assignation du Prescaler
 1: Prescaler assigné au chien de garde WDT
 0: Assigné au Timer TMR0
 b2-b1-b0: PS2:PS1:PS0 Valeur du Prescaler du TMR0 ou du WDT
 Valeurs du prescaler
 PS2:PS1:PS0 Prescaler TMR0 Prescaler WDT
 000 1/2 1/1
 001 1/4 1/2
 010 1/8 1/4
 011 1/16 1/8
 100 1/32 1/16
 101 1/64 1/32
 110 1/128 1/64
 111 1/256 1/128
INTCON (Bank 0 en 0Bh et Bank 1 en 8Bh).
Bits d’autorisation et Flags d’interruptions
 b7: GIE Autorisation Globale des Interruptions
 1: Autorise toutes les interruptions
 0: Interdit toutes les interruptions
 b6: EEIE Autorisation de l’interruption de fin d’écriture en Eeprom
 1: Autorise l’interruption de fin d’écriture en Eeprom
 0: Interdit l’interruption de fin d’écriture en Eeprom
 b5: TOIE Autorisation de l’interruption de débordement de TMR0
 1: Autorise l’interruption de TMR0
 0: Interdit l’interruption de TMR0
 b4: INTE Autorisation de l’interruption sur RB0/INT
 1: Autorise l’interruption sur RB0/INT
 0: Interdit l’interruption sur RB0/INT
 b3: RBIE Autorisation de l’interruption lors d’un changement d’état sur le PortB
 1: Autorise l’interruption sur RB7:RB4
 0: Interdit l’interruption sur RB7:RB4
 b2: TOIF Flag de débordement de TMR0
 1: Le TMR0 a débordé (à effacer par programme)
 0: Le TMR0 n’a pas débordé
 b1: INTF Flag d’interruption sur RB0/INT
 1: Il y a eu une demande d’interruption sur RB0/INT
 0: Il n’y a pas d’interruption sur RB0/INT
 b0: RBIF Flag d’interruption sur le PortB
 1: Au moins une pin RB7:RB4 a changé d’état (doit être effacé par programme)
 0: Il n’y a pas de changement d’état sur RB7:RB4
Les instructions.
Nous présentons l'ensemble des 35 instructions du PIC® 16F84 codées sur 14 bits. Vous trouverez en colonne de gauche le code binaire de l'instruction se trouvant au centre puis une courte explication de ce que fait l'instruction.
Les opérandes peuvent être de plusieurs types:
Dans la terminologie Microchip, littéral signifie en adressage immédiat.
Voir aussi.
Le jeu d'instructions du PIC 16F84 est présenté dans un qui montre comment embarquer un PIC 16F84 dans un FPGA.
Architecture complète.
Nous présentons ci-dessous, sous forme de schéma, l'architecture complète du PIC 16F84. Arrivé à ce point, il n'est pas inutile de passer un peu de temps à la comprendre.
Brochage.
Le brochage du PIC 16F84A en boitier DIL est le suivant :
" Liste des broches, classées par catégories:"
 OSC1/CLKIN (pin 16) Quartz ou entrée de l’horloge externe
 OSC2/CLKOUT (pin 15) Quartz en mode cristal ou sortie d’horloge à 1/4 de la fréquence en mode RC
 MCLR\ (pin 4) Master Clear (Reset) ou tension de programmation. (Reset actif à l’état bas).
 Port A :
 RA0 (pin 17) Port A I/O TTL
 RA1 (pin 18) Port A I/O TTL
 RA2 (pin 1) Port A I/O TTL
 RA3 (pin 2) Port A I/O TTL
 RA4/T0CKI (pin 3) Port A I/O Entrée Trigger, sortie Drain ouvert. Entrée de comptage TMR0
 Port B : peut être programmé pour avoir des résistances de pull-up internes sur ses entrées.
 RB0/INT (pin 6) Port B I/O TTL en I/O et Entrée d’Interruption avec Trigger
 RB1 (pin 7) Port B I/O TTL
 RB2 (pin 8) Port B I/O TTL
 RB3 (pin 9) Port B I/O TTL
 RB4 (pin 10) Port B I/O TTL avec Interruption sur changement d’état de l’entrée
 RB5 (pin 11) Port B I/O TTL avec Interruption sur changement d’état de l’entrée
 RB6 (pin 12) Port B I/O TTL avec Interruption sur changement d’état de l’entrée.
 Serial programming clock avec entrée Trigger.
 RB7 (pin 13) Port B I/O TTL avec Interruption sur changement d’état de l’entrée.
 Serial programming data avec entrée Trigger.
 VSS (pin 5) Masse
 VDD (pin 14) Alimentation positive
Schémas de base.
Un système minimum peut être le suivant, avec simplement une alimentation 5Vdc, un quartz 4MHz de type AT (pas de quartz série), deux condensateurs 27pF céramique et un PIC 16F84 4MHz.
Dans ce cas, l’entrée de reset MCLR\ est connectée à l’alimentation positive +5V pour un reset de type POR (Power On Reset : reset à la mise sous tension) interne au PIC.
Ce circuit de reset est utilisable seulement dans le cas d’un oscillateur grande vitesse, et dans le cas d’une alimentation à excursion rapide (le niveau 5V doit être atteint rapidement, avec une pente raide).
De plus, il ne permet pas un redémarrage du système à chaud (sans couper l’alimentation).
Pour obtenir un reset à chaud, il suffirait dans ce cas de connecter MCLR\ à un circuit RC (résistance de 22Ko et condensateur de 100nF) qui assurerait le POR, et permettrait d’effectuer le reset à chaud avec un bouton poussoir relié à la masse :
La résistance de 470 ohms est recommandée par Microchip pour limiter le courant de décharge du condensateur dans MCLR\.
Une diode de type 1N4148 peut être mise en parallèle sur la résistance de rappel de 22K afin de décharger le condensateur plus rapidement en cas de coupure d’alimentation.
Ceci permettra au PIC de redémarrer plus sûrement après une coupure d’alimentation brève.
Les Ports d'entrées/sorties.
Le PORT A: RA0 … RA4.
Le PORT A est un des deux Ports du PIC 16F84, et comprend 5 lignes Entrées/Sorties.
Sa configuration et sa programmation passent par l’utilisation de deux registres qui sont PORTA et TRISA.
Le registre PORTA (Bank 0) est une copie des lignes RA0..RA4, tant en entrée qu’en sortie.
En effet, lire le PORTA revient à lire l’état des pins alors qu’une écriture place le niveau correspondant sur les pins qui auront été configurées en sorties (dans une séquence interne au PIC de Read-modify-write).
Les lignes RA0 .. RA3 sont des entrées à niveaux compatibles TTL et des sorties CMOS standards.
La ligne RA4 est une entrée à Trigger de Schmitt et une sortie à drain ouvert qui est multiplexée avec l’entrée de Timer TMR0.
Le registre TRISA (Bank 1) est le registre qui permettra de placer les pins indépendamment en entrée ou en sortie.
Mettre un bit de TRISA à 1 placera la pin correspondante en entrée (et le circuit de sortie correspondant en haute impédance).
Mettre un bit de TRISA à 0 placera la pin correspondante du PORTA en sortie.
Exemple de configuration du PORTA:
 BSF STATUS, RP0 ; Acces Bank1
 MOVLW 0xFB ; TRISA.b2 à 0 pour RA2 en sortie (% 1111.1011)
 MOVWF TRISA
 BCF STATUS, RP0 ; Acces Bank0
 …
 BCF STATUS, RP0 ; Acces Bank0
 BSF PORTA, RA2 ; Allume la Led connectée à la ligne RA2
Utilisation du PORT A: Allumage d’une Led.
Un premier exemple d’utilisation du Port A est de faire clignoter une Led connectée à RA2 par l’intermédiaire d’une résistance de 1 Kohms.
Exemple de code:
 ; Clignotement d'une Led sur RA2
 ;;;;;;; *** Configuration
 LIST p=16F84A ; Processeur 16F84A
 #INCLUDE <p16F84A.inc> ; Définition des registre internes du 16F84
 __CONFIG _CP_OFF & _WDT_OFF & _HS_OSC ; Option de programmation 
 ;;;;;;; *** Définitions
 RA2 EQU 0x02 ; PortA, sortie RA2
 ;;;;;;; *** Variables
 CBLOCK 0x0C
 vTempo1, vTempo2;
 ENDC
 ;;;;;;; *** Vecteurs
 ORG H'0000' ; Déclaration du Reset
 GOTO Start
 ; * Tempo de clignotement qui utilise deux variables pour obtenir une tempo longue
 Tempo MOVLW 0xFF ; Charge W avec 0xFF
 MOVWF vTempo2 ; pour charge la vTempo2
 _Tempo2 MOVWF vTempo1 ; et la vTempo1
 _Tempo1 DECFSZ vTempo1, f ; Décrémente vTempo et met le résultat dans vTempo
 GOTO _Tempo1 ; puis saute l'instruction suivante si 0. 
 DECFSZ vTempo2, f
 GOTO _Tempo2
 RETURN