# Comment démarrer avec un PIC16F84

* Programmation Assembleur
* Introduction
* Les différents processeurs :
* x86
* PowerPC
* Itanium
* Sparc
* Mips
* ARM
* Alpha
* HP-PA
* SuperH
* 68000
* PIC16F84
* Z80
* Modifier ce modèle
* Retour au livre Programmation
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.

### RAM et Registres du 16F84

    Adr.Banque 0Banque 1Adr. 00hIndirect addr.Indirect addr.80h 01hTMR0OPTION_REG 02hPCLPCL82h 03hSTATUSSTATUS 04hFSRFSR84h 05hPORTATRISA 06hPORTBTRISB86h 07h---- 08hEEDATAEECON188h 09hEEADREECON2 0AhPCLATHPCLATH8Ah 0BhINTCONINTCON 0Ch - 4Fh68 cases mémoiresidem banque 08Ch - CFH 50h - 7FhinutiliséinutiliséD0H - FFH
Les SFR (Registres internes à Fonction Spéciale) vont de 00h à 0Bh en Bank0 et de 80h à 8Bh en Bank1.
Bank 0
Bank 1
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: 00 pour la sélection Bank0 01 pour la Bank1 (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.

#### 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

#### INTCON (Bank 0 en 0Bh et Bank 1 en 8Bh)

Bits d’autorisation et Flags d’interruptions

## 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:
* f : adresse mémoire de registres (register file address) de 00 à 7F
* W : registre de travail
* d : sélection de destination : d=0 vers W, d=1 vers f
* pp : numéro de PORT entre 1 et 3 sur deux bits
* bbb : adresse de bit dans un registre 8 bits (sur 3 bits)
* k : champ littéral (8, ou 11 bits)
* PC compteur programme
Jeu d'instructions 14-bit pour PIC 16F84 :
| Opcode (binary) | Mnemonic | Description |
| 00 0000 0xx0 0000 | NOP | Pas d'opération |
| 00 0000 0110 0011 | SLEEP | arrête le processeur |
| 00 0000 0110 0100 | CLRWDT | Reset du timer watchdog |
| 00 1000 dfff ffff | MOVF f,d | Recopie de W dans f (adressage direct) |
| 00 0000 1fff ffff | MOVWF | déplacement de W vers f |
| 00 0001 0xxx xxxx | CLRW | Positionne W à 0 (idem à CLR x, W) |
| 00 0001 1fff ffff | CLRF f | Positionne f à 0 (idem à CLR f, F) |
| 00 0010 dfff ffff | SUBWF f, d | Soustrait W de (d = f − W) |
| 00 0011 dfff ffff | DECF f, d | Décrément f (d = f − 1) |
| 00 0100 dfff ffff | IORWF f, d | OU Inclusif W avec F (d = f OR W) |
| 00 0101 dfff ffff | ANDWF f, d | ET entre W et F (d = f AND W) |
| 00 0110 dfff ffff | XORWF f, d | OU Exclusif W avec F (d = f XOR W) |
| 00 0111 dfff ffff | ADDWF f, d | Additionne W avec F (d = f + W) |
| 00 1000 dfff ffff | MOVF f, d | recopie F (d = f) |
| 00 1001 dfff ffff | COMF f, d | Complement f (d = NOT f) |
| 00 1010 dfff ffff | INCF f, d | Incrément f (d = f + 1) |
| 00 1011 dfff ffff | DECFSZ f, d | Decrément f (d = f − 1) et saut si zero |
| 00 1100 dfff ffff | RRF f, d | Rotation droite F (rotation droite avec la retenue) |
| 00 1101 dfff ffff | RLF f, d | Rotation gauche F (rotation gauche avec la retenue) |
| 00 1110 dfff ffff | SWAPF f, d | échange de groupes 4-bit de f (d = lsb:f msb:f) |
| 00 1111 dfff ffff | INCFSZ f, d | Incrément f (d = f + 1) et saut si zero |
| 01 00bb bfff ffff | BCF f, b | RaZ d'un bit de f (Clear bit b of f) |
| 01 01bb bfff ffff | BSF f, b | Mise à 1 d'un bit de f (Set bit b of f) |
| 01 10bb bfff ffff | BTFSC f, b | test de bit de f, saute si zéro (Test bit b of f) |
| 01 11bb bfff ffff | BTFSS f, b | test de bit de f, saute si un (Test bit b of f) |
| 11 01xx kkkk kkkk | RETLW k | Positionne W à k et retour |
| 10 0kkk kkkk kkkk | CALL k | Sauve l'adresse de retour, charge PC avec k |
| 00 0000 0000 1001 | RETFIE | retour d'interruption |
| 00 0000 0000 1000 | RETURN | retour de sous-programme |
| 10 1kkk kkkk kkkk | GOTO k | saut à l'adresse k (9 bits!) |
| 11 111x kkkk kkkk | ADDLW k | Addition de W et k |
| 11 110x kkkk kkkk | SUBLW k | Soustraction de W et k |
| 11 00xx kkkk kkkk | MOVLW k | Chargement littéral de W (W = k) |
| 11 1000 kkkk kkkk | IORLW k | OU Inclusif littéral avec W (W = k OR W) |
| 11 1001 kkkk kkkk | ANDLW k | ET littéral avec W (W = k AND W) |
| 11 1010 kkkk kkkk | XORLW k | OU exclusif or littéral avec W (W = k XOR W) |
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 autre projet 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:

## 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:

### 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.
*** SCHEMA***
Exemple de code:
La temporisation utilisée peut être améliorée de la sorte, afin d’obtenir des temps calibrés:
L’appel se fera donc par CALL T_1s pour une temporisation de 1 seconde.

## Déclarations et Définitions principales sous MPLAB

MPLAB est l'environnement de développement intégré Assembleur gratuit de Microchip.
Voici les principales déclarations les plus utiles:

### ORG

Définit l’adresse de l’instruction qui va suivre, utilisé pour le Reset et l’Interruption.
Le Reset se situe à l’adresse 0x0000 et se déclare de la façon suivante :
Si on utilise l’ Interruption, elle se déclarera de la façon suivante à la suite du Reset:
Si l’IT n’est pas utilisée, la place mémoire ainsi libérée par sa non utilisation au niveau du vecteur sera utilisée par le code du programme lui-même.

### INCLUDE

Permet à l’assembleur d’inclure le texte d’un autre fichier dans le fichier source en cours.

### EQU

Assignation de constante qui peut se déclarer de la façon suivante :
Une variable peut également se déclarer de la façon suivante :

### CBLOCK …. ENDC :

On peut aussi déclarer des zones de plusieurs variables à l’aide de la directive CBLOCK …. ENDC
Ainsi,
défini plusieurs variables d’adresses consécutives: Mavariable à l’adresse 0x0C et La tempo à l’adresse 0x0D.

### CONFIG :

Permet de configurer les « fusibles » internes du PIC à activer par le programmateur.
Demande de ne pas positionner le fusible de protection en lecture et d’activer le WatchDog.

### Liste des bits du mot de Configuration:
### #DEFINE

Permet de définir une chaîne de substitution :

### LIST

Liste des directives à l’attention du pré-processeur.

### END

Définit la fin du programme.

## Description matérielle interne du PIC 16F84

Nous allons donner dans cette section un peu d'information sur l'architecture interne du PIC 16F84.
La documentation de cette section n'est pas une reprise de la documentation officielle de Microchip. Nous avons comme objectif de présenter des schémas internes complets. Comme pour tout schéma, il devient parlant lorsque les conventions sur lesquelles il s'appuie sont comprises par le lecteur.
Nous prenons le Timer 0 comme exemple.

### Le timer0

Le timer0 est un timer sur 8 bits. C'est totalement visible sur la figure ci-dessous. Les bits des registres 8 bits seront toujours repérés de b0 (poids faible) à b7 (poids fort).
Que voit-on sur cette figure ?
* C'est le registre OPTION qui permet une configuration du fonctionnement du timer0
* Lors d'un débordement (overflow) du timer 0, un bit nommé "TMR0IF" du registre INTCON est positionné. Ce bit n'est jamais remis à 0 par le matériel car c'est un drapeau (flag)
* Le bit "T0CS" du registre OPTION permet, à l'aide du multiplexeur en haut à droite de choisir l'entrée du timer 0. On voit qu'il peut s'agir du quartz interne du PIC ou du bit "T0CKI" du PORTA.
* Le ou exclusif (=1) permet une éventuelle inversion
* Les trois bits "T0PS2", "T0PS1" et "T0PS0" permettent un choix de division entre 2 et 256
* La fameuse division ci-dessus ne sera prise en compte que si le multiplexeur du bas est positionné correctement par le bit "PSA" du registre OPTION.
* Cette figure vous donne aussi la position de tous les bits. Par exemple, le fameux bit "T0CKI" du PORTA est le bit b4 du PORTA.

### L'interruption de débordement du timer 0

Mettre en route le timer0 est une chose, mais déclencher une interruption en est une autre. Il nous faut maintenant documenter ce mécanisme.
* Définition
* On appelle drapeau (flag en anglais), tout bit dont le nom se termine par F. Ces bits particuliers sont toujours mis à un par le matériel, mais mis à 0 par le logiciel.
Nous avons déjà rencontré un drapeau lors de la description du timer 0 : le bit "TMR0IF" du registre INTCON. Si vous voulez que ce bit soit à 0, c'est à vous, programmeur, de le faire.
Comme on peut le voir sur la figure ci-dessous, c'est le registre INTCON qui est responsable de la gestion des interruptions.
Pour réaliser l'interruption, il faut réaliser un front montant dans l'ellipse rouge : on en déduit immédiatement les bits à mettre à 1 dans INTCON, à savoir T0IE et GIE. Vous ne voyez pas de front montant ? C'est normal il est en fait réalisé par le bit "TMR0IF" du registre INTCON. Ce que permettent les bits T0IE et GIE, c'est tout simplement d'acheminer ce front d'horloge vers la fameuse ellipse rouge.
Remarque : Sur la documentation ci-dessus, vous trouvez l'appellation T0IF au lieu de TMR0IF. Malheureusement, le nom des bits dépend des compilateurs C ou assembleurs utilisés. Par exemple, le compilateur Hitech C appelle effectivement ce bit T0IF.

## Premiers pas avec un compilateur C

Vous pouvez lire la section Nos premiers programmes en C d'un autre projet pour découvrir la programmation en C. Vous y trouverez, par exemple, la gestion du timer0, y compris avec interruption.
Cette page est en travaux. Tant que cet avis n'aura pas disparu, veuillez en considérer le plan et le contenu encore incomplets, temporaires et sujets à caution. Si vous souhaitez participer, il vous est recommandé de consulter sa page de discussion au préalable, où des informations peuvent être données sur l'avancement des travaux.

## Voir aussi

* PIC 16F84 de Microchip
* Utiliser les PIC 16F et 18F, un cours de la Wikiversité
* Embarquer un PIC 16F84 dans un FPGA
* Mon site de ressources micro

## Contributeurs

* Frédéric SILLON
[il faut pratiquer pour apprendre mais pas le contraire]