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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]À 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 :
//***** MikroC fichier P18F84A.c ******
const unsigned short
W = 0x0000,
F = 0x0001,
IRP = 0x0007,
RP1 = 0x0006,
RP0 = 0x0005,
NOT_TO = 0x0004,
NOT_PD = 0x0003,
Z = 0x0002,
DC = 0x0001,
C = 0x0000,
....
unsigned short register volatile
STATUS absolute 0x0003;
....
unsigned short register
OPTION_REG absolute 0x0081,
....
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
[modifier | modifier le wikicode]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 :
/* STATUS bits */
volatile bit RP0 @ (unsigned)&STATUS*8+5;
volatile bit TO @ (unsigned)&STATUS*8+4;
volatile bit PD @ (unsigned)&STATUS*8+3;
volatile bit ZERO @ (unsigned)&STATUS*8+2;
volatile bit DC @ (unsigned)&STATUS*8+1;
volatile bit CARRY @ (unsigned)&STATUS*8+0;
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
[modifier | modifier le wikicode]Voici un autre exemple, pour le PORTA pour le compilateur C18 trouvé dans le fichier p18f4550.h.
extern volatile near union {
struct {
unsigned RA0:1;
unsigned RA1:1;
unsigned RA2:1;
unsigned RA3:1;
unsigned RA4:1;
unsigned RA5:1;
unsigned RA6:1;
};
struct {
unsigned AN0:1;
unsigned AN1:1;
unsigned AN2:1;
unsigned AN3:1;
unsigned T0CKI:1;
unsigned AN4:1;
unsigned OSC2:1;
};
struct {
unsigned :2;
unsigned VREFM:1;
unsigned VREFP:1;
unsigned :1;
unsigned LVDIN:1;
};
struct {
unsigned :5;
unsigned HLVDIN:1;
};
} PORTAbits;
Cet exemple nous montre la diversité des noms des bits pour un même port.
Exemple pour comparer
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]Le PORT A: RA0 … RA4
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]La définition du port A est faite dans le fichier :
//***** Extraits du fichier P16F84A.c (MikroC) *******
unsigned short register volatile
PORTA absolute 0x0005;
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
[modifier | modifier le wikicode]Voici les noms du PORTA et de ses bits :
//***** Extraits du fichier pic1684.h (HitechC) *******
....
volatile unsigned char PORTA @ 0x05;
....
/* PORTA bits */
volatile bit RA4 @ (unsigned)&PORTA*8+4;
volatile bit RA3 @ (unsigned)&PORTA*8+3;
volatile bit RA2 @ (unsigned)&PORTA*8+2;
volatile bit RA1 @ (unsigned)&PORTA*8+1;
volatile bit RA0 @ (unsigned)&PORTA*8+0;
Rappelez-vous qu’il n'y a que 5 bits d'utilisables dans le PORTA dans le PIC 16F84.
Le registre TRISA
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]La définition du port A est faite dans le fichier :
//***** Extraits du fichier P16F84A.c (MikroC) *******
unsigned short register
OPTION_REG absolute 0x0081,
TRISA absolute 0x0085,
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
[modifier | modifier le wikicode]Voici les noms du TRISA et de ses bits :
//***** Extraits du fichier pic1684.h (HitechC) *******
....
volatile unsigned char TRISA @ 0x85;
....
/* TRISA bits */
volatile bit TRISA4 @ (unsigned)&TRISA*8+4;
volatile bit TRISA3 @ (unsigned)&TRISA*8+3;
volatile bit TRISA2 @ (unsigned)&TRISA*8+2;
volatile bit TRISA1 @ (unsigned)&TRISA*8+1;
volatile bit TRISA0 @ (unsigned)&TRISA*8+0;
Rappelez-vous qu’il n'y a que 5 bits d'utilisables dans le PORTA dans le PIC 16F84 de Microchip.
Fonctionnement des PORTs
[modifier | modifier le wikicode]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 :
bsf PORTA , 1 ; mettre RA1 à 1
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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]//******* Extraits du fichier P16F84A.c (MikroC) ******
unsigned short register volatile
PORTB absolute 0x0006;
....
unsigned short register
OPTION_REG absolute 0x0081,
TRISA absolute 0x0085,
TRISB absolute 0x0086,
....
Encore une fois aucune définition de bits particuliers.
PORTB TRISB et leurs bits en Hitech C
[modifier | modifier le wikicode]Le compilateur Hitech C définit naturellement les registres correspondants et en plus donne un nom aux bits.
//****** Extraits du fichier pic1684.h (HitechC) ******
volatile unsigned char PORTA @ 0x05;
volatile unsigned char PORTB @ 0x06;
...
volatile unsigned char TRISA @ 0x85;
volatile unsigned char TRISB @ 0x86;
...
/* PORTB bits */
volatile bit RB7 @ (unsigned)&PORTB*8+7;
volatile bit RB6 @ (unsigned)&PORTB*8+6;
volatile bit RB5 @ (unsigned)&PORTB*8+5;
volatile bit RB4 @ (unsigned)&PORTB*8+4;
volatile bit RB3 @ (unsigned)&PORTB*8+3;
volatile bit RB2 @ (unsigned)&PORTB*8+2;
volatile bit RB1 @ (unsigned)&PORTB*8+1;
volatile bit RB0 @ (unsigned)&PORTB*8+0;
volatile bit INT @ (unsigned)&PORTB*8+0;
/* TRISB bits */
volatile bit TRISB7 @ (unsigned)&TRISB*8+7;
volatile bit TRISB6 @ (unsigned)&TRISB*8+6;
volatile bit TRISB5 @ (unsigned)&TRISB*8+5;
volatile bit TRISB4 @ (unsigned)&TRISB*8+4;
volatile bit TRISB3 @ (unsigned)&TRISB*8+3;
volatile bit TRISB2 @ (unsigned)&TRISB*8+2;
volatile bit TRISB1 @ (unsigned)&TRISB*8+1;
volatile bit TRISB0 @ (unsigned)&TRISB*8+0;
Brochage
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]Voir PIC 16F877 dans wikipédia en attendant.
Les PORTs du 18FXXXX
[modifier | modifier le wikicode]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.
Voir aussi
[modifier | modifier le wikicode]Liens internes
[modifier | modifier le wikicode]Lien externes
[modifier | modifier le wikicode]Faites ces exercices : Les ports et le langage C. |