# Utiliser les PIC 16F et 18F/Les ports et le langage C

Les PORTs sont des registres destinés à gérer les entrées sorties : allumer une led, lire si un capteur est à un ou zéro sont des actions que peuvent faire les PORTs.

## Manipulation des bits des ports et registres

Nous avons déjà présenté dans le chapitre précédent comment il était possible de manipuler les bits avec des masques. Il existe une autre méthode que nous allons présenter maintenant.
La manipulation des bits de registre dépend des compilateurs utilisés. Nous allons nous intéresser à trois compilateurs :
* mikroC pour les séries 16F et 18F
* Hitech C pour la série des 16F
* C18 réservé au 18F
L'installation de l'environnement de développement gratuit MPLAB de Microchip vous permet d’utiliser les deux derniers gratuitement (il faut payer pour avoir la version optimisée).

### On connaît seulement le bit par sa position

Jusqu'à présent nous avons désigné les positions de bits par b0 (poids faible) à b7 (poids fort).
* En mikroC, il est possible d'accéder à un bit particulier pour toute variable sur 8 bits avec B0..B7 ou F0..F7.

### On connaît le bit par son nom

La documentation des composants PIC donne des noms aux bits de la plupart des registres. Pour ces registres, on peut utiliser la même méthode ou utiliser les noms des bits.
* En MikroC : nom du bit suivi par _bit ou nom du registre "." nom du bit
* En C18 : nom du registre suivi de "bits." nom du bit
* En Hitech C : nom du bit. Attention les noms des bits ne sont pas forcément ceux de la documentation du matériel !
Si vous voulez connaître le nom des bits, je ne vois aucun autre moyen que de lire les fichiers d'en-têtes.

#### Exemple de fichier d'en-tête pour MikroC

À proprement parler, pour le compilateur MikroC, les définitions ne sont pas dans un fichier avec une extension (.h) mais dans des fichiers qui se trouvent dans un répertoire defs et qui ont l'extension (.c). On en présente un extrait maintenant :
Cela permet de connaître le nom des bits du registre STATUS et de confirmer le nom du registre OPTION (comme OPTION_REG). Rappelez-vous que le langage C est sensible à la casse des caractères.
Gardez en mémoire pour toute la suite, que le registre OPTION s’appelle OPTION_REG en MikroC.

#### Exemple de fichier d'en-tête pour Hitech C

Par exemple pour le PIC 16F84 de Microchip, on trouvera un ficher d'en-tête pour le compilateur Hitech C nommé pic1684.h dans lequel on peut lire :
qui vous donne le nom des bits du registre STATUS ! Vous vous seriez certainement attendu à "C" au lieu de "CARRY" si vous avez lu toutes les documentations présentées jusqu'à maintenant.

#### Exemple de fichier d'en-tête pour C18

Voici un autre exemple, pour le PORTA pour le compilateur C18 trouvé dans le fichier p18f4550.h.
Cet exemple nous montre la diversité des noms des bits pour un même port.

### Exemple pour comparer

Nous présentons un exemple pour comprendre :
| MikroC | C18 | Hitech C |
| char demo; demo.F5 = 1; // If RB0 is set, set RC0: if (PORTB.F0) PORTC.F0 = 1; // ou encore (MikroC pro seulement) if (RB0_bit) RC0_bit = 1; // utilisation du nom d'un bit INTCON.T0IF = 0; // Clear TMR0IF // ou encore (MikroC pro seulement) T0IF_bit = 0; // Clear TMR0IF | char demo; demo= demo |0x20; // If RB0 is set, set RC0: if (PORTBbits.RB0) PORTCbits.RC0 = 1; // utilisation du nom d'un bit INTCONbits.TMR0IF=0;// Clear TMR0IF | //Le nom du bit a changé !!! T0IF = 0; // Clear TMR0IF |
Remarquez les techniques différentes utilisées par trois compilateurs.

## Les PORTs du 16F84
### 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 PORT A et ses bits en MikroC

La définition du port A est faite dans le fichier :
Il n'y a aucune définition de noms de bits. Il vous faut donc utiliser PORTA.F0 à PORTA.F4

#### Le PORT A et ses bits en HitechC

Voici les noms du PORTA et de ses bits :
Rappelez-vous qu’il n'y a que 5 bits d'utilisables dans le PORTA dans le PIC 16F84.

### Le registre TRISA

Le registre TRISA (Bank 1) est le registre qui permettra de placer les broches indépendamment en entrée ou en sortie.
* Mettre un bit de TRISA à 1 placera la broche correspondante en entrée (et le circuit de sortie correspondant en haute impédance).
* Mettre un bit de TRISA à 0 placera la broche correspondante du PORTA en sortie.
Au reset du PIC®, toutes les broches sont mises en entrée, afin de ne pas envoyer des signaux non désirés sur les pattes. Les bits de TRISA seront donc mis à 1 lors de chaque reset.
Pour des exemples de manipulation du PORT A en assembleur, lisez Comment démarrer avec un PIC 16F84.

#### Le registre TRISA et ses bits en MikroC

La définition du port A est faite dans le fichier :
Il n'y a aucune définition de noms de bits. Il vous faut donc utiliser TRISA.B0 à TRISA.B4

#### Le registre TRISA et ses bits en HitechC

Voici les noms du TRISA et de ses bits :
Rappelez-vous qu’il n'y a que 5 bits d'utilisables dans le PORTA dans le PIC 16F84 de Microchip.

### Fonctionnement des PORTs

Les PORTS fonctionnent toujours sur le principe
lecture->modification->écriture
Par exemple, si vous écrivez bsf PORTA,1, le PIC® procède de la manière suivante :
* Le PORTA est lu en intégralité (pins en entrée et en sortie)
* Le bit 1 est mis à 1
* Tout le PORTA est réécrit (concerne les pins en sortie).
Ainsi, supposons par exemple que le RA4 soit en sortie et mis à 1. Comme il est en sortie drain ouvert, si une électronique externe le force à 0, si vous effectuez l’opération suivante :
Lorsque le PORTA va être lu, RA4 sera lu comme 0, bien qu’il soit à 1. RA1 sera forcé à 1, et le tout sera replacé dans PORTA. RA4 est donc maintenant à 0, sans que vous l’ayez explicitement modifié.

### Le PORT B et le registre TRISB

Ces registres fonctionnent exactement de la même manière que PORTA et TRISA, mais concernent bien entendu les 8 broches RB. Tous les bits sont donc utilisés dans ce cas.
Voyons maintenant les particularités du PORTB. Les entrées du PORTB peuvent être connectées à une résistance de tirage au +5 V de manière interne, cette sélection s’effectuant par le bit 7 du registre OPTION (effacement du bit7 RBPU pour valider les résistances de rappel au +5 V).

#### PORTB TRISB et leurs bits en Mikro C

Encore une fois aucune définition de bits particuliers.

#### PORTB TRISB et leurs bits en Hitech C

Le compilateur Hitech C définit naturellement les registres correspondants et en plus donne un nom aux bits.

### Brochage

Le brochage du PIC 16F84A en boitier DIL est le suivant :
Comme on peut s'y attendre on retrouve tous les PORTs sur le brochage : les 5 bits du PORTA (RA4 ... RA0) et les 8 bits du PORTB (RB7 ... RB0).

## Des LEDs et des boutons poussoirs sur des PORTs

Le but de cette section est d'étudier quelques connexions électriques à partir des PORTs d'un microcontrôleur. Nous nous contenterons des Diode électroluminescente et des boutons poussoirs.

### Le PORT et sa modélisation électrique

Le modèle électrique est très simple : on le modélise comme d'habitude à l'aide de Thevenin.
Il est raisonnable de prendre un Imax de 10 mA pour 16F84 et 15 mA pour 16F877.

### Connecter et dimensionner des LEDs

Une LED (ou Diode électroluminescente) est une diode et par conséquent se modélise de la même manière :
Retenez les valeurs typiques notées dans la figure pour Ud=1,8 V et rd=0 Ohm.
Il y a deux façons typiques pour connecter des LEDs :
À gauche c’est le microcontrôleur qui est à l'origine du courant. À droite c’est lui qui reçoit le courant passant par la LED et provenant d'une alimentation. Évidemment, il faut un un logique sur le bit PA1 pour allumer la LED de gauche et un zéro logique sur le bit PA2 pour allumer la LED de droite.

### Connecter des boutons poussoirs

Il est naturellement possible de connecter des boutons poussoirs à un PORT et de demander au micro-contrôleur de dire si le bouton est appuyé ou relâché. (Sur un robot mobile on peut utiliser ce principe pour détecter des objets)
Regardez attentivement le dessin de gauche et en particulier la connexion sur le bit PB4 : la question importante est dans le dessin. On sait parfaitement ce qu’il se passe si le bouton est appuyé : on est relié à la masse, on aura donc un zéro logique en lecture. Mais qu'en est-il si on lâche le bouton poussoir ? Tout dépend de la technologie du PORT. Si l’on avait du TTL on aurait un un logique mais on n'a pas de TTL ! Il faut donc utiliser une résistance supplémentaire que l’on appelle résistance pullup (ou Résistance de tirage en français). Soit elle existe à l'intérieur du PORT, soit il faut l'ajouter à l'extérieur du PORT.
La gestion des résistances internes de tirage dépend fortement du processeur. Sur le PIC c’est un seul bit pour tous les PORTs.

## Les PORTs du 16F877

Voir PIC 16F877 dans wikipédia en attendant.

## Les PORTs du 18FXXXX

Voici la documentation:
| Addr | Name | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | Value on Power-on Reset |
| FF1h | INTCON2 | /RBPU | INTEDG0 | INTEDG1 | - | - | TMR0IP | - | RBIP | 111- -1-1 |
| F93h | TRISB | | | | | | | | | 1111 1111 |
| F92h | TRISA | - | | | | | | | | -111 1111 |
| F8Ah | LATB | | | | | | | | | xxxx xxxx |
| F89h | LATA | - | | | | | | | | -xxx xxxx |
| F81h | PORTB | RB7/PGD | RB6/PGC | RB5/PGM | RB4 | RB3/ CANRX | RB2/CANTX/INT2 | RB1/INT1 | RB0/INT0 | xxxx xxxx |
| F80h | PORTA | - | RA6/CLKO/OSC2 | RA5/ AN4 | RA4/ TOCKI | RA3/AN3/Vref+ | RA2/AN2/Vref- | RA1/ AN1 | RA0/AN0/CVref | -x0x 0000 |
On y remarque que le PORT A est sur 7 bits et que PORT B est sur 8 bits.
Notez également que, comme il n’y a que 7 pins utilisées sur le PORTA, seuls 7 bits (b0/b6) seront utilisés sur TRISA. Les bits de TRISA sont désignés par TRISAbits.TRISA0 ... TRISAbits.TRISA6 avec le compilateur C18.
Les bits de TRISB sont désignés par TRISBbits.TRISB0 ... TRISBbits.TRISB7 avec le compilateur C18.