Académique Documents
Professionnel Documents
Culture Documents
Industrielle
Microcontrôleur
PIC-16F887
03/04/2024 Hassan El Moussaoui 1
• https://www.mikroe.com/ebooks/pic-micr
ocontrollers-programming-in-c/the-basic
s-of-c-programming-language
https://www.mikroe.com/ebooks/pic-microcontro
llers-programming-in-c/introduction
Environnement
Restitution et
Acquisition Traitement
commande
données Système à
Système piloter
pilotant mesures
(ex : une chaîne
Autres électronique événements de production,
Autres
Autres
systèmes informatique une réaction
systèmes
systèmes chimique…)
commandes
• Memory Software
Sensors
A/D
ASIC/FPGA Processor(s) D/A
Actuators
Other Hardware
Human Interface
• Composants hardware :
• Processeurs RISC CISC
• DSP
• FPGA
• Périphérique de communication, afficheurs, interfaces
• Software :
• système d’exploitation embarqué
• Logiciels spécifique, compilateur, interpréteurs.
03/04/2024
Hassan El Moussaoui 12
Architecture de processeur Harvard
03/04/2024 13
Hassan El Moussaoui
Von Neumann vs. Harvard
03/04/2024 15
Hassan El Moussaoui
Différentes familles de processeurs : exemples types
• Microcontrôleurs :
• 8051
• 68HC11
• PIC
• MSP 430
• Processeurs :
• Intel 80XXX
• Motorola 68XX
• ARM
• DSP :
• TMS 320 C XX
• ADSP 21 XXX, SHARC
• 56 XXX
Processeur
Mémoires
Unités périphériques et interfaces d‘E/S
Faible consommation
Coût réduit
Encombrement réduit
- PIC 10 - PIC 12
- Certains PIC12F & PIC16F
- PIC 17
- PIC 18
PIC 16F887
• La lettre F indique que la mémoire programme de cette PIC est de type "Flash".
• Les derniers chiffres permettent d'identifier précisément la PIC, ici c'est une
PIC de type 887.
• Architecture RISC
– Seulement 35 instructions pour apprendre
– Toutes les instructions seul cycle sauf les branches
• D'utilisation de fréquence de 0-20 MHz
• Précision oscillateur interne
– Calibré en usine
– Bande de fréquences de logiciel de 8 MHz à 31 KHz
• 2.0 La tension d'alimentation de puissance-5.5V
– Consommation : 220uA (2,0 v, 4 MHz), 11uA (2,0 V, 32 KHz) 50nA (mode veille)
• Mode veille d'économie d'énergie
• Brown-out Reset (BOR) avec option de contrôle de logiciel
• 35 broches d'entrée/sortie
– Sources et de puits actuel élevé à entraînement direct de LED
– logiciel et résistance programmables individuellement pull-up
– Interruption-sur-Changez code
• 8 K de mémoire ROM en technologie FLASH
– Puce peut être reprogrammé jusqu'à 100.000 fois
• Programmation série en Circuit Option
Puce peut être programmé même incorporé dans l'appareil cible
03/04/2024 Hassan El Moussaoui 32
3.1 LES CARACTÉRISTIQUES DE BASE PIC16F887
• L’environnement de développement
MPLAB
Séance de
« Prise en main de MPLAB »
ET
MIKROC
POUR LES PICs
03/04/2024 Hassan El Moussaoui 38
Les ports parallèles d'entrée sortie
Le 16F877 possède 5 ports différents :
le port A (6 broches)
le port B (8 broches)
le port C (8 broches)
le port D (8 broches)
le port E (3 broches)
est de 25 mA.
Remarques:
o Avec le compilateur CC5X, vous pouvez accéder soit à un registre
entier (8 bits), soit à un seul bit d'un registre.
o Exemples :
PORTB = 0x08 ;
– Met à « 1 » le bit n° 3 et à « 0 » tout les
autres bits du registre PORTB.
PORTB.3 = 1 ;– Met à « 1 » le bit n°3 du registre PORTB … et
c'est tout ! L'état des autres bits du registre PORTB n'est
pas modifié, contrairement à la commande précédente.
03/04/2024 Hassan El Moussaoui 45
Interfaçage avec un microcontrôleur en sortie
– On a toujours VD = 2V et IC = 10mA
– Pour la résistance R2 :
de 10
IB = 10 * IC / β = 1mA
et VCE = 0.2V
• 5 LEDs max !
un montage de ce type :
PORTx=0b01000010;
TRISx=0;
PORTx=0b10011010;
TRISx=0b11100010;
RA4 possède un transistor de sortie MOS a drain ouvert, donc il faut placer une
résistance (10k) de cette patte au 5v, pour avoir un niveau logique 1 correct.
Placer cette résistance seulement si la ligne RA4 est en sortie.
Le portA par défaut ou lors d'un reset est configuré en entrée analogique sur certain
PIC comme le 16F876, 16F877.
Il faut initialiser les bits PCFG1, PCFG2, du registre ADCON1 à 1 avec le code suivant:
ADCON1=6;
Le port B des PIC 16F876, 16F877 dispose de résistances de tirage au 5V.
Placer le bit RBPU à 0 pour activer les résistances, ou 1 pour les désactiver.
Les résistances sont désactivées lors d'un reset.
Les résistances fonctionnent seulement sur les lignes du port placées en entrées.
RBPU=0;// Résistances activées
RBPU=1;// Résistances désactivées
Exemple:
MikroC vous permet un accès individuel dans les variables 8 bits (char
des identifiants F0, F1, ..., F7. Être F7 le bit le plus significatif
Exemple:
PORTC.F0 = 1;
PORTD.F5 = 0;
PORTB.F7 = 1;
RC0 Entrée
RC1 Entrée
RC2 Entrée
RC3 Entrée
RC4 Sortie
RC5 Sortie
RC6 Sortie
RC7 Sortie
TRISC = 0b’00001111’; o
TRISC = 0x0F; o
TRISC = 15;
Exemple:
Générer un délai de 1 seconde
void main(void)
{
// Définition des variables locales
// cycle infini
while ( 1 )
{
// programme principal
}
}
void main(void)
{
// Définition des variables locales
// cycle infini
for ( ; ; )
{
// programme principal
}
}
void main(void)
{
// Définition des variables locales
// cycle infini
do
{
// programme principal
} while ( 1 )
}
03/04/2024 Hassan El Moussaoui 75
Éclairage d’une LED
Créez un programme qui allume et éteint une led située sur le terminal
L’algorithme
Allumage du led
Eteindre la led
Répétez l'étape 2
03/04/2024 Hassan El Moussaoui 76
void main()
{
trisd= 0b00000000 ; // direction du port b (1 : Entrée, 0 : Sortie)
while(1) // boucle infinie
{
portd = 0b11111111; //les 8 leds allumées
delay_ms(200) ;
portd = 0b00000000;
delay_ms(200) ;
}
}
Manipulation
Suivre les instructions (jusqu'à l'exécution - run) avec les recommandations suivantes :
- nom du projet : tp1a
- Chemin du projet d:\rep_perso\tp1. Ce dossier doit être créé en remplaçant rep_perso par un nom
qui vous est propre
- Le type (device) est à lire sur la puce elle-même. En principe 16F887.
- Choisir les fusibles par défaut.
- Le programme suivant est à saisir :
1 void main () {
2 //ANSEL = ANSELH = 0; // Toutes le ports E/S sont configurés comme numériques
3 PORTC = 0;
4 TRISC = 0;
5 while (1) {
6 PORTC = ~PORTC; // toggle PORTC
7 Delay_ms(1000);
8}
9}
Si vous voulez un fonctionnement correct de Delay_ms, il faut configurer aussi la fréquence du
quartz (8 MHz) correctement.
Exemple
On vous donne un programme C qui fait clignoter une led (poids faible) sur le port C.
1 void main () {
2 ANSEL = ANSELH = 0; // Toutes le ports E/S sont configurés comme numériques
3 TRISC = 0; // tous les bits en sortie pour PORTC
4 PORTC = 0;
5 while(1) {
6 PORTC = 0x01;
7 Delay_ms(1000);
8 PORTC = 0x00;
9 Delay_ms(1000);
10 }
11 }
void main( )
{
for(;;) //Boucle fin
{
TRISB=0; //Configuration du PORTB en sortie
PORT.F0; //RP0=0
Delay_Ms(1000); //Pause d’une seconde
PORTb.f0=1. //RP0=1
Delay_Ms(1000); //Pause d’une seconde
} //Fin de la boucle
}
void main()
{
TRISB = 0; // PORTB est configuré en sortie
for(; ;) // Boucle sans fin
{
LED = ON; // LED est allumée (ON)
One_Second_Delay; // Retard 1 seconde
LED = OFF; // LED est désactivée (OFF)
One_Second_Delay; // Retard 1 seconde
}
}
Dans ce projet les huit LEDs sont connectées à PORTC d'un microcontrôleur.
Lorsqu'une tension est appliquée au microcontrôleur (ou est réinitialisé), les LEDs
s'allument en alternance. Il y a le délai d’une seconde de sorte qu’une LED peut
être vu tourner sur ON et OFF.
Le schéma de principe du projet est illustré à la figure suivante.
void main()
{
unsigned char J = 1;
TRISC = 0; // PORTC est configure en sortie
for(;;) // Boucle sans fin
{
PORTC = J; // Envoyer J au PORTC
Delay_ms(100); // Pause 100 ms
J = J << 1; // Décalage à gauche J
if(J == 0) J = 1; // Si la dernière LED, allumer la 1ère LED
}
}
L'étudiant allumera et éteindra alternativement deux LED situées dans les bits
2 et 3 du port B. Les retards seront de 500 millisecondes (les deux). Utilisation
de l'allocation directe aux bits
L'étudiant allume et éteint une led située dans le bit 5 du port C. Les retards
seront de 100 millisecondes et 2 secondes, respectivement. Utilisation de
l'allocation des octets
10.Retour à 2
100001
010010
001100
010010
100001
U1
1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
16 D1
2
RC1/T1OSI/CCP2
17
R1
RA0/AN0/ULPW U/C12IN0- RC2/P1A/CCP1
3 18
RA1/AN1/C12IN1- RC3/SCK/SCL 10
4 23 LED-GREEN
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20
33
RD1
21 D2
34
RB0/AN12/INT RD2
22
R2
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4 10
36 28 LED-GREEN
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6
10
RE2/AN7 D3
R4 R3
PIC16F887
10 10
LED-GREEN
R5
10
R6
10
void main()
{
TRISC=0X00;
PORTC=0X00;
TRISD=0XFF;
a1=a2=a3=0;
for(;;)
{
if(PORTD.B0==0) {a1=~a1; delay_ms(100);}
PORTC.B0=a1;
if(PORTD.B1==0) {a2=~a2; delay_ms(100);}
PORTC.B1=a2;
if(PORTD.B2==0) {a3=~a3; delay_ms(100);}
PORTC.B2=a3;
}
}
Les Interruptions
Généralités sur les interruptions
en C)
d'interruption).
Ces 34 bits sont accessibles dans les registres INTCON, PIE1, PIE2,
PIR1 et PIR2.
Au reset, tous ces bits sont placés à zéro (sauf le flag RBIF) ce qui
implique qu’aucune interruption n'est validée et qu’aucun flag n'est
levé.
Bits de validation et flag associés
Masquage des interruptions
● Toutes ces interruptions sont des interruptions masquables.
NON !
Où mettre le programme d'IT ?
Déclaration du programme d'interruption
Ces bits sont regroupés suivant le microcontrôleur cible dans des registres
appelés registres de configuration des interruptions tels que : INTCON, PIE1, PIE2,
utilisé.
Le registre INTCON est parfois différent d’un PIC à un autre. Il est impératif
de revenir au document constructeur pour chaque type de microcontrôleur.
Bit 7: GIE = Global Interrupt Enable bit
1 = Autorise toutes les interruptions non masquées par leur bit individuel.
0 = Désactive toutes les interruptions.
RB0 à RB7 du port B, le front n’a pas d’importance. Les bits associés sont RBIE
Pour autoriser l’interruption sur la broche Rbi le bit i du registre IOCB doit être
mis à 1.
Cette interruption est provoquée par un changement d’état sur l’entrée RB0 du
Elle est gérée par son bit de validation INTE et son drapeau INTF.
{
ANSEL = 0;
ANSELH = 0;
TRISD.B7=0;
TRISC=0;
PORTC=0;
while(1)
{
PORTD.B7=!PORTD.B7;
delay_ms(100);
}
PORTC=0;
}
void main()
{
ANSEL = 0;
ANSELH = 0;
TRISD.B7=0;
INTCON.GIE=1;
INTCON.INTE=1;
TRISC=0;
PORTC=0;
while(1)
{
PORTD.B7=!PORTD.B7;
delay_ms(100);
}
PORTC=0;
}
Programme d’Interruption Programme Principal
void interrupt() void main()
{ {
int i; ANSEL = 0;
for(i=0;i<10;i++) ANSELH = 0;
{ TRISD.B7=0;
PORTC=i; INTCON.GIE=1;
delay_ms(100); INTCON.INTE=1;
} TRISC=0;
PORTC=0;
PORTC=0; while(1)
} {
PORTD.B7=!PORTD.B7;
delay_ms(100);
}
PORTC=0;
}
Programme d’Interruption Programme Principal
void interrupt() void main()
{ {
int i; ANSEL = 0;
for(i=0;i<10;i++) ANSELH = 0;
{ TRISD.B7=0;
PORTC=i; INTCON.GIE=1;
delay_ms(100); INTCON.INTE=1;
} TRISC=0;
INTCON.INTF=0; PORTC=0;
PORTC=0; while(1)
} {
PORTD.B7=!PORTD.B7;
delay_ms(100);
}
PORTC=0;
}
R3
10k
R2 U1
1 15
10k RE3/MCLR/VPP RC0/T1OSO/T1CKI
16
RC1/T1OSI/CCP2
R1 2 17
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
RA1/AN1/C12IN1- RC3/SCK/SCL
4 23
10k RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
RA7/OSC1/CLKIN RD0
20
RD1
Affiche 'F' 33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
35 27
RB2/AN8 RD4
36 28
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C
38 30
Decompteur 39
RB5/AN13/T1G RD7/P1D D1
RB6/ICSPCLK R4
40 8
RB7/ICSPDAT RE0/AN5
9 100
RE1/AN6
10 LED-GREEN
RE2/AN7
PIC16F887
char
tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0
xF8,0x80,0x90};
int i;
if(portB.B0==1)
{
for(i=0;i<10;i++)
{
portC=tab[i] ;
delay_ms(50);
}
}
03/04/2024 Hassan El Moussaoui 132
int i;
void interrupt()
{
if( INTCON.INTF==1)
{
for(i=0;i<=9;i++)
{
PORTC=i;
delay_ms(100);
}
INTCON.INTF=0;
}
PORTC=0;
if( INTCON.RBIF==1)
{
if(PORTB.RB2==1)
{
PORTC=0xFF;
delay_ms(1000);
INTCON.RBIF=0;
}
if(PORTB.RB7==1)
{
for(i=9;i>=0;i--)
{
PORTC=i;
delay_ms(100);
INTCON.RBIF=0;
}
}
INTCON.RBIF=0;
PORTC=0;
}
INTCON.RBIF=0;
INTCON.RBIE = 1;
}
des réaliser
- mesure de temps
Fonctionnement du Timer
Les timers sont des compteurs formés généralement d’un pré-diviseur suivi d’un
timer. Il faut bien noter que le programmeur devra remettre à zéro cet indicateur
Timer2
Fonctionnement du Timer
Elément essentiel : Compteur qui s'incrémente à chaque front montant du signal
qui lui est appliqué
:
Lorsque le compteur dépasse la valeur maximale qu'il peut contenir (par exemple :
256 pour un compteur sur 8 bits), un drapeau (flag en anglais) se lève.
Ce drapeau a pour but d'indiquer au programme que le compteur a débordé (c'est à dire
qu'il a fini de compter). De la même manière que pour la boite aux lettres, c'est au
programme de rebaisser le drapeau pour recommencer un cycle de comptage (ça ne se fait
pas tout seul !).
1. Principe de fonctionnement
•Élément essentiel : Compteur qui s'incrémente à chaque front montant du signal qui
•Lorsque le compteur dépasse la valeur maximale qu'il peut contenir (par exemple: 256 pour
un compteur sur 8 bits), un drapeau (flag en anglais) se lève.
•Ce drapeau a pour but d'indiquer au programme que le compteur a débordé (c'est à
dire qu'il a ”fini” de compter).
•De la même manière que pour la boîte aux lettres, c'est au programme de rebaisser le
drapeau pour recommencer un cycle de comptage (ça ne se fait pas tout seul !).
2. Méthodes de configuration
•Un Timer doit pouvoir compter un temps défini par le programme (par exemple 1ms,
10ms, 50ms, etc).
•Pour cela, 2 paramètres peuvent être modifiés :
La fréquence du signal appliqué au compteur
Le compteur s'incrémentera ainsi plus ou moins vite.
Le nombre d'impulsions à compter
Le drapeau se lève toujours lorsqu'il y a débordement, on peut
donc faire partir le compteur d'une valeur non nulle pour
réduire le temps de comptage.
•Modification de la fréquence du signal appliqué au compteur : le pré-diviseur
(prescaler en anglais)
Exemple : pour compter 4 fois moins vite
•Calcul du temps mis par le Timer pour faire lever son drapeau :
Mode Timer
Mode Compteur
broche RA4
Composition du Timer0
Prédiviseur
Le pré-diviseur peut prendre une valeur parmi la liste suivante : 1, 2, 4, 8, 16, 32,
64, 128 ou 256.
La valeur initiale peut prendre n'importe quelle valeur entière comprise entre 0
et 255.
Calcul du temps maximum
Pour que le drapeau se lève le plus tard possible, il faut que la fréquence du signal
applique au compteur soit la plus faible possible. Il faut donc configurer le pré-diviseur le
plus grand : 256.
Il faut également faire démarrer le compteur avec la valeur la plus petite possible pour
qu'il compte le nombre d'impulsion le plus grand : valeur initiale = 0.
Calcul d'un temps de 10 ms
Registre de configuration du Timer0 : OPTION_REG
Registres associé au Timer0:
•TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons
rentrer la valeur de départ de notre compteur.
• INTCON seuls les bits 7, 6, 5 et 2 sont utiles pour le Timer0 (ce sont les seuls
non grisés). Dans ce chapitre, nous ne nous intéresserons qu'au bit 2 appelé T0IF et
qui correspond au flag permettant de tester la fin du comptage.
d'impulsion minimale ou le temps mort entre deux impulsions doit être 2 Tosc +
seulement de 10 nS.
microcontrôleur:
EXEMPLE.1
Dans cet exemple la minuterie, sur la base de registre TMR0, est utilisée
de sorte que toute pression sur Input provoque TMR0 à compter une impulsion.
nommé TEST, la valeur logique 1 (5V) apparaît sur le pin3 de PORTC. Cette
Originalité de ce Timer :
Le flag ne se lève pas systématiquement à chaque fin de comptage.
o Existance d'un post-compteur.
o Ce post-compteur peut prendre chaque
valeur entière entre 1 et 16.
Exemple pour un post-compteur de 4:
•La temporisation max de ce Timer est donc :
void main()
{
ANSEL=0;
ANSELH=0;
TRISB=0;
PORTB=0;
T2CON=0b00000111;
INTCON=0b11000000;
PIE1.B1=1;
PR2=255;
for(;;)
{
PORTB=b;
}
03/04/2024 Hassan El Moussaoui 175
}
03/04/2024 Hassan El Moussaoui 176
Le Timer1 du 16F887
Particularités de ce Timer 1:
Exemples :
o Compteur de pièces dans une machine industrielle
Timer 0:
bit T1OSCEN = 0
Timer 1 associé à un quartz
T1OSCEN = 1
void main()
{
ANSEL=0;
ANSELH=0;
TRISB=0;
PORTB=0;
T1CON=0b00110101;
for(;;)
{
PORTB=TMR1L;
}
}
char a;
void interrupt()
{
if(PIR1.TMR1IF==1)
{
a++;
}
PIR1.TMR1IF=0;
}
void main()
{
ANSEL=0;
ANSELH=0;
TRISB=0x00;
PORTB=0;
T1CON=0b00000101;
INTCON=0b11000000;
PIE1=0b00000001;
for(;;)
{
PORTB=a;
}
}
void main()
{
ANSEL=0;
ANSELH=0;
TRISB=0;
PORTB=0;
TRISC.B1=1;
T1CON=0b00010111;
TMR1L=0;
for(;;)
{
PORTB=TMR1L;
}
}
Le module de
génération de signaux
MLI (PWM)
Presentation
”CCP1” et ”CCP2”
utilise le Timer 1 ou 2
•Exemple
On désire créer un signal à 400Hz.
Il faut donc créer une temporisation avec le Timer 2 de 2,5ms
( T = 1 / F = 1 / 400).
Avec la formule ci-dessous :
// prescaler 1:16
T2CKPS1_bit = 1;
T2CKPS0_bit = 1;
PWM1_Start();
}
void main()
{
trisc = 0; // C2 en sortie pour PWM
PR2 = 249; //charger Registre Periode
// prescaler 1:4
T2CKPS1_bit = 0;
T2CKPS0_bit = 1;
PWM1_Start();
}
Travaille demander comme TP
char a;
void interrupt()
{
if(intcon.INTF)
{
a=a+20;
}
intcon.INTF=0;
}
void main()
{
ANSEL=0;
ANSELH=0;
OPTION_reg.B7=0;
OPTION_reg.B6=0;
intcon=0b11010000;
a=40;
trisb.B0=1;
PWM1_Init(37000);
PWM1_Set_Duty(a);
for(;;)
{
PWM1_Start();
PWM1_Set_Duty(a);
}
}
trisb.b1 = 1;
trisc.b2 = 0;
PR2 = 124;
T2CKPS1_bit = 1;
T2CKPS0_bit = 1;
PWM1_SET_Duty(duty_cycle);
PWM1_Start();
while(1)
{
if(portb.b0 == 0)
{
duty_cycle++;
PWM1_Set_Duty(duty_cycle);
delay_ms(50);
}
if(portb.b1 == 0)
{
duty_cycle--;
PWM1_Set_Duty(duty_cycle);
delay_ms(50);
}
}
PWM1_SET_Duty(duty_cycle);
}
PWM1_Start();
03/04/2024 Hassan El Moussaoui 219
CONVERTISSEUR
ADC
16F887
Le rôle du CAN est de transformer une
tension analogique en un signal numérique
pour interfacer un système numérique (tel que
le microcontrôleur PIC) avec le monde
extérieur.
Exemples
● Capteur de température dans une machine à
laver le linge.
● Pédale de Kart : La pédale de kart est directement
fixée à un potentiomètre. Pour connaître la vitesse
désirée il suffit de connaître la tension lue sur le
potentiomètre.
03/04/2024 Hassan El Moussaoui 223
03/04/2024 Hassan El Moussaoui 224
03/04/2024 Hassan El Moussaoui 225
03/04/2024 Hassan El Moussaoui 226
Mesure de distance à l’aide de capteurs sharp
GP2
Le capteur est un module infra-rouge qui fournit une tension
analogique variant en fonction de la distance le séparant d’un
objet.
valeurs possibles.
● La plage de variation de la tension à mesurer est
donc découpée également en 8.
– Exemple : Vref- = 0V et Vref+ = 5V
Le résultat de conversion sera (000)2 si la tension à mesurer est
compris entre 0V et 5/8=0,625V
Le résultat de conversion sera (111)2 si la tension à mesurer est
compris entre (7/8)*5 =4,375V et 5V
Avec un résultat sur 10 bits, on peut obtenir 2 =1024
10
●
valeurs possibles.
● La plage de variation de la tension à mesurer est
donc découpée également en 1024.
– Exemple : Vref- = 0V et Vref+ = 5V
Le résultat de conversion sera (0000000000)2 si la
tension à mesurer est compris entre 0V et
5/1024≈0,005V
Le résultat de conversion sera (1111111111)2 si la tension à
mesurer est compris entre (1023/1024)*5 ≈ 4,995V et 5V
Schéma fonctionnel
Le CAN du PIC 16F887 (ADC module)
● Caractéristiques :
bits du signal enregistré dans les deux registres ADRESL et ADRESH de l’ADC .
Sur la base des tensions de référence Vref- et Vref +, il est alors possible de
réaliser une conversion correcte en Volts ou milliVolts selon les besoins. Pendant la
négative Vref- tandis que 1023 au positif Vref +. Ensuite, la tension mesurée
sera calculée, à partir du nombre lu dans les registres ADC, en utilisant la formule:
V an = (Vref -) + {[(Vref +) - (Vref -)] / 1023} * Nombre10Bit
exemple:
TRISA = 0x00; // Toutes les broches de PORTA sont sorties
TRISA = 0xFF; // Toutes les broches de PORTA sont entrées
TRISA = 0b00000100 // Broche 2 (RA2) du port A et entrée
TRISA = 0x04; // Broche 2 (RA2) du port A et entrée
Réglons le bit correspondant sur 1 dans les registres ANSEL et ANSELH des
broches que nous voulons configurer comme analogiques;
Les registres ANSEL et ANSELH sont utilisés pour régler les broches d'E / S en
analogique ou numérique.
La sélection du canal s'effectue en réglant le bit correspondant sur 1 dans les
registres ANSEL et ANSELH. Le modèle à suivre est la suivante:
- la ANS7 bits {} ANSEL Registre détermine si la broche PORTE.2 est analogique - CH7
Cas 2: avec VCFG1 à 0 et VCFG0 à 1 est utilisé comme tension de référence positive à une
certaine broche dédiée à recevoir le Vref + d'une source externe tandis que la référence négative
sera celle de la masse (Vss)
Cas 1: avec VCFG1 à 1 et VCFG0 à 1, les deux Vref + et Vref-pins seront utilisés. Vref + acceptera
la tension externe supérieure (mais qui doit être égale ou inférieure à Vdd ) tandis
que Vref- la tension mineure (qui peut être supérieure à Vss ). Ce choix nous permet d'obtenir un
«espace de mesure» aussi adapté que possible à nos besoins.
En résumé:
Tension de référence Vmax Vmin
Tension
1 V dd V ss
d'alimentation
T1 = T max
+ T c
+ T coff
où:
T ampères = Temps d' établissement d' amplificateur
d'acquisition T1 est invariable, sauf s'il est nécessaire d'intervenir sur les paramètres
matériels du système.
T2 dépend à la place du temps pour terminer une conversion d'un seul bit
(appelé T AD ). Le T AD correspond à la période du convertisseur ADC pour
laquelle T AD = 1 / Clock ADC . Le T AD est tiré de la fiche technique et doit être d'au
moins 1,6 μS (10 -6 secondes). Ainsi, une conversion complète de 10 bits nécessite un
temps égal ou supérieur à 10 T AD . Comme le montre la figure ci-dessous et environ
11,5 T AD car il est également nécessaire d'ajouter le temps perdu pour déconnecter /
connecter le condensateur.
Le T AD dépend de l'horloge de référence pour laquelle nous devons calibrer la
source d'horloge de l'ADC de sorte que la valeur minimale qui est d'au moins 1,6μS
soit dépassée.
Il est possible de réduire le temps de conversion au moyen d'un logiciel à condition
qu'il accepte une diminution de la précision de la valeur convertie.
Par exemple, si la fréquence d'horloge est de 4 Mhz et réglé comme étant la source
d'horloge du convertisseur Fosc / 8 , on a:
utilisée
Fréquence de l'appareil (Fosc)
Verrou
de référence C p
our ADCS1 ADCS0
le convertisseur 20 Mhz 8 Mhz 4 Mhz 1 Mhz
ADC
Frc est l'horloge générée par un oscillateur situé à l'intérieur du module ADC. Cette
source, si elle est sélectionnée, permet à l'ADC de fonctionner même lorsque la CPU est
en mode veille.
Sélectionnez l'un des canaux d'entrée ( CH0-CH13 ) via le registre ADCON0 ;
0 0 0 0 0 RA0 / AN0
0 0 0 1 1 RA1 / AN1
0 0 1 0 2 RA2 / AN2
0 0 1 1 3 RA3 / AN3
0 1 0 0 4 RA5 / AN4
0 1 0 1 5 RE0 / AN5
0 1 1 0 6 RE1 / AN6
0 1 1 1 7 RE2 / AN7
1 0 0 0 8 RB2 / AN8
1 0 0 1 9 RB3 / AN9
1 0 1 0 RB1 /
10
AN10
1 0 1 1 11 RB4 / AN11
1 1 0 0 RB0 /
12
AN12
1 1 0 1 RB5 /
13
AN13
1 1 1 0 CVref
1 1 1 1 Vref = 0.6V
exemple:
ADCON0 = 0b..0000 ..; // Activer le canal 0
ADCON0 = 0b..0010 ..; // Activer le canal 2
exemple:
ADCON1 = 0b1 .......; // Activer le canal 0
ADCON1 = 0b0 .......; // activer le canal 2 Activer le convertisseur A / D en plaçant le
bit ADON à 1 dans le registreADCON0 Le bit ADON registre
ADCON0 active ou désactive le convertisseur A / N
Pour que l'ADC atteigne son niveau de précision spécifique, il est nécessaire de prévoir un
certain délai entre la sélection du canal d'entrée analogique et sa mesure. Cette période est
appelée " temps d'acquisition " et dépend de l'impédance ( résistance au passage d'un
courant variable ) de la source. Il y a des équations qui permettent de le calculer avec
précision mais on peut utiliser comme référence le pire des cas qui est d'environ 20uS.
Commencez la conversion en plaçant le bit GO / DONE à 1 dans le
registre ADCON0 .
Attendez la fin de la conversion (le bit GO / DONE revient à 0). Une boucle d'attente sera
donc nécessaire. Il y a la possibilité d'attendre une interruption A / D mais elle doit être
activée.
L E D -R E D
D2
D8 R2
U1 L E D -R E D
1 15
RV1 R E 3 /M C L R /V P P R C 0 /T1 O S O /T1 C K I
16 D3
R C 1 /T1 O S I/C C P 2
2 17 D7 R3
R A 0 /A N 0 /U L P W U /C 12IN 0- R C 2 /P 1 A /C C P 1
3 18
R A 1 /A N 1 /C 1 2 IN 1- R C 3 /S C K /S C L
4 23 L E D -R E D
R A 2 /A N 2 /V R E F -/C V R E F /C 2IN + R C 4 /S D I/S D A
43%
5 24
6
R A 3 /A N 3 /V R E F + /C 1IN + R C 5 /S D O
25 D4
R A 4 /T0 C K I/C 1 O U T R C 6 /TX /C K
7 26 D6 R4
R A 5 /A N 4 /S S /C 2O U T R C 7 /R X /D T
1k 14
R A 6 /O S C 2 /C L K O U T RN1
13 19 D0 L E D -R E D
R A 7 /O S C 1 /C L K IN R D0
20 D1 R1 10
33
R D1
21 D2 D5 R2 9
R B 0 /A N 1 2 /IN T R D2
34 22 D3 D5 R5 R3 8
R B 1 /A N 1 0 /C 1 2 IN 3- R D3
35 27 D4 R4 7
R B 2 /A N 8 R D4
36 28 D5 L E D -R E D R5 6
R B 3 /A N 9 /P G M /C 1 2 IN 2- R D 5 /P 1B
37 29 D6 R6 5
38
R B 4 /A N 11 R D 6 /P 1C
30 D7 D6 R7 4
R B 5 /A N 1 3 /T1G R D 7 /P 1D
39 D4 R6 R8 3
R B 6 /IC S P C LK
+ 2 .15 40 8 R9 2 1
R B 7 /IC S P D AT R E 0 /A N 5
V o lts 9 L E D -R E D
R E 1 /A N 6
10 1 00
R E 2 /A N 7
P IC 1 6 F 8 87 D7
D3 R7 R 10
R1
1 00
D8 L E D -R E D
D9
D8
D2 R8
L E D -R E D
D9
D1 R9
L E D -R E D
D 10
D0 R 10
L E D -R E D
Exemple.1 Codage sur 10 Bits
unsigned int a;
void main()
{
TRISC=0X00; PORTC=0X00;
TRISD=0X00; PORTD=0X00;
a=0x00;
ADC_Init();
for(;;)
{
a = ADC_Read(0);
PORTC=a;
PORTD=a >> 8;
}
}
Exemple.1 Codage sur 8 Bits
unsigned int a;
void main()
{
TRISC=0X00; PORTC=0X00;
TRISD=0X00; PORTD=0X00;
a=0x00;
ADC_Init();
for(;;)
{
a = ADC_Read(0);
PORTC = a >> 2;
}
}
Exemple.1 Codage sur 7 Bits
unsigned int a;
void main()
{
TRISC=0X00; PORTC=0X00;
TRISD=0X00; PORTD=0X00;
a=0x00;
ADC_Init();
for(;;)
{
a = ADC_Read(0);
PORTC = a >> 3;
}
}
Exemple.2
unsigned int Valeur_ADC =0 ; // Création et initialisation de la variable de stockage
void main() {
ANSEL = 0b00000001; // Configure pin an0 en analogique
}
}
Exemple.3
unsigned int temp_res;
void main() {
ANSEL = 0x0C; // Pins AN2 and AN3 are configured as analog
TRISA = 0xFF; // All port A pins are configured as inputs
ANSELH = 0; // Rest of pins is configured as digital
TRISB = 0x3F; // Port B pins RB7 and RB6 are configured as outputs
TRISD = 0; // All port D pins are configured as outputs
ADCON1.F4 = 1 ; // Voltage reference is brought to the RA3 pin.
ADCON1.F5 = 1 ;
do {
temp_res = ADC_Read(2); // Result of A/D conversion is copied to temp_res
PORTD = temp_res; // 8 LSBs are moved to port D
PORTB = temp_res >> 2; // 2 MSBs are moved to bits RB6 and RB7
} while(1); // Endless loop
}
Vcc
RV1 U1
1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI
16
Voltage de reference 2
RC1/T1OSI/CCP2
17
100%
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18
RA1/AN1/C12IN1- RC3/SCK/SCL
4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24
RV2 1k 6
RA3/AN3/VREF+/C1IN+ RC5/SDO
25
RA4/T0CKI/C1OUT RC6/TX/CK
7 26
RA5/AN4/SS/C2OUT RC7/RX/DT
14
RA6/OSC2/CLKOUT
13 19
Voltage a mesurer RA7/OSC1/CLKIN RD0
93%
20
RD1
33 21
RB0/AN12/INT RD2
34 22
RB1/AN10/C12IN3- RD3
1k 35 27
RB2/AN8 RD4
36 28
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D
39
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9
RE1/AN6
10
RE2/AN7
PIC16F887
La liaison série RS232
Utilisation de l'EUSART
Généralités
* Full-Duplex ou Half-Duplex
-Norme RS232
(ports COM)
-Norme RS485
● Pour indiquer au récepteur le début d'une transmission, il faut lui envoyer un signal:
Exemple de transmission
● On souhaite envoyer l'octet 0x32 (qui est le code ASCII du caractère '2'), sur 8 bits,
sansparité avec 1 bit STOP. - 0x32 = (0011 0010) 2
Lignes de contrôle
● Ce sont les signaux additionnels aux lignes de données qui permettent de contrôler la
communication.
● Différents signaux peuvent être échangés.
● Ces signaux peuvent être groupés de la manière suivante :
* Des signaux de transmission de données
- TXD (transmit data) : Données dans un sens
- RXD (receive data) : Données dans l'autre sens
* Des signaux de contrôle de flux de transmission
2400 bauds
4800 bauds
9600 bauds
19200 bauds
38400 bauds
57600 bauds
115200 bauds
Contrôle de flux
● Le rôle du contrôle de flux est de permettre d'éviter de perdre des informations
pendant la transmission.
● Différents types de contrôle de flux :
+ Contrôle de flux matériel
+ Contrôle de flux logiciel
● Exemple :
de « 1 » impaire.
Bilan
● Pour que 2 équipements puissent échanger des données, il faut qu'ils soient:
● Niveaux de tension
Les 0-5V (voire moins) que l'on trouve généralement en sortie des
microcontrôleurs est insuffisant pour transmettre les informations loin.
En effet, sous l'effet de l'impédance de la ligne (inductances et capacités
parasites), le signal est atténué.
● Niveaux de tension
Afin de pouvoir envoyer les signaux plus loin, la liaison série RS232
Un niveau logique bas (0V) sera transmis à l'aide d'une tension de +10V.
Un niveau logique haut (5V) sera transmis à l'aide d'une tension de -10V.
ET-10V
● Niveaux de tension
Chronogrammes
Composant externe (MAX 232)
● Cet adaptation est très classiquement réalisée par le composant MAX
232 :
● Ce composant est capable de générer à partir d'une
alimentation Vcc de 5V, les tensions +10V et -10V.
● Avec une telle tension, il est possible de communiquer
avec une liaison série RS232 à
9600 bauds jusqu'à 10m.
● Plus la distance sera grande, moins la vitesse
de transmission sera rapide car les atténuations et les
déformations des signaux seront plus importantes.
Connecteur
● La connexion se fait aujourd'hui généralement sur
des connecteurs DB9.
● Le schéma de connexion est donné ci-dessous :
Évolution
● Depuis quelques années, les ordinateurs neufs ne sont plus pourvus par défaut de ports
COM RS232.
● Il existe maintenant des cables USB permettant de continuer à utiliser des liaisons séries
RS232.
● Ces cables intègrent un circuit intégré permettant de gérer le protocole USB d'un coté et la
liaison RS232 de l'autre (puces FTDI)
Mise en œuvre de la liaison série avec le PIC 16F887
● Le périphérique interne qui gère la liaison série asynchrone s'appelle ” EUSART” :
recevoir les données. Ils sont au nombre de deux (un pour l'émission, l'autre pour la
simultanément.
● Il faudra donc mettre la bonne valeur dans les registres de configuration de l'EUSART.
● Il nous permettra également de savoir si une transmission est en cours, si elle s'est
passée convenablement ou bien s'il y a eu une erreur. Ce sera le rôle du registre d'état.
● Enfin, nous aurons des registres pour écrire les données à envoyer ou lire les données reçues.
Setting the SPEN bit of the RCSTA register enables the EUSART and
automatically configures the TX/CK I/O pin as an output. If the TX/CK pin is
shared with an analog peripheral the analog I/O function must be disabled by
clearing the corresponding ANSEL bit.
Setting the SPEN bit of the RCSTA register enables the EUSART and
automatically configures the RX/DT I/O pin as an input. If the RX/DT pin is
shared with an analog peripheral the analog I/O function must be disabled by
clearing the corresponding ANSEL bit.
● Si l'on souhaite se connecter sur un PC, il faudra penser à utiliser un composant (par
Register »). On charge la valeur à transmettre sur 8 bits à l’aide du registre TXREG
● L'écriture de TXREG dans TSR met à '1' le drapeau TXIF. Celui-ci est capable de
générer une interruption si le bit TXIE est à '1'. Le registre à décalage ajoute tout seul le bit
de START et de STOP.
● Le fait que le drapeau TXIF passe à '1' n’indique pas que la donnée a été transmise, mais
uniquement le fait que vous avez mis une donnée dans le registre TXREG.
● Le drapeau « TRMT » indique quand le registre à décalage est vide. C'est à dire
quand le mot est complètement envoyé.
Il est ainsi bien plus utile de tester le bit TRMT que le bit TXIF.
● La figure 12-3, nous donne les chronogrammes des bits TRMT et TXIF :
● Pour envoyer les données, il faut configurer l'horloge de transmission. Ceci se fait à
l'aide du registre SPBRG (composé de 2 registres de 8 bits SPBRGH:SPBRG) qui divise la
fréquence de l'horloge interne pour obtenir la bonne vitesse de transmission.
● La validation de cette horloge se fait par TXEN. L'horloge est la même pour les
modules d'envoi et de réception.
● Les bits sérialisés sont envoyés vers la patte de sortie RC6/TX. Cette patte à la
double fonction de servir de patte d'E/S standard ou de servir comme sortie d'envoi de la
liaison série.
● La configuration entre ces deux modes de fonctionnement se fait grâce au bit SPEN.
● Lorsque le bit SPEN est égal à '1', les pattes RC6/TX et RC7/RX sont respectivement
configurés automatiquement en sortie et en entrée.
● Il est possible d'envoyer un 9ème bit avant le bit de STOP (par exemple une parité ou
un deuxième bit STOP). Il faut alors valider TX9 et inscrire la donnée du 9ème bit dans
● Il scrute en permanence le signal qui arrive sur la patte RC7/RX. Il faut donc là
aussi indiquer que cette patte sert à la liaison série grâce à SPEN.
● La réception ne sera validée que lorsque le bit CREN sera correctement configuré.
● Une fois le mot reçu correctement, le PIC stocke les 8 bits de données reçus dans le
mal passée. Il possède notamment les bits OERR (Overrun error) et FERR (Framing
error).
● Chronogrammes
Les registres associés à la transmission
Les registres associés à la réception
Les registres
● Les registres TXREG et RCREG
Vous placerez le mot à transmettre dans le registre TXREG.
Lorsqu'un mot sera reçu, vous pourrez le lire dans le registre RCREG.
● Les registres INTCON, PIR1 et PIE1
Ces registres sont utilisés pour gérer la liaison RS 232 en interruption
● Le registre PIR1
Ce registre contient les deux flags (drapeaux) permettant de :
Détecter qu’un mot a été reçu : bit RCIF
Détecter qu’un mot a été placé dans le registre de transmission : bit TXIF .
Remarque : il existe un autre « flag » pour la transmission : TRMT .
● Le registre PIE1
- BRG16 = 0 et BRGH = 0
- X forcément entier → X = 6
(calcul : (9600-8929)/9600)).
● On choisira la valeur afin de minimiser l'erreur commise sur la transmission.
● Des tableaux (pages 168 et 169 de la doc) permettent de trouver rapidement les
● Remarque : la plupart du temps, il sera suffisant de travailler avec un registre SPBRG sur 8
16 bits s'impose uniquement pour obtenir de faibles vitesses de transmission avec un quartz de
fréquence élevée.
Les registres de contrôle et d'état
asynchrone.
•Validation des lignes RC6 et RC7 comme broches d’entrée / sortie associées à
-La réception est validée en plaçant un '1' dans le bit CREN du registre RCSTA
TXSTA .
-Le bit TX9 du registre TXSTA permet de valider une transmission de 8 bits ou
de 9 bits
-En mode 9 bits, il faut placer le 9ème bit dans le bit TX9D du registre TXSTA.
-En mode 8 bits, le bit TX9D peut prendre n’importe quelle valeur.
*Réception de 8 bits ou de 9 bits.
-Le bit RX9 du registre RCSTA permet de valider une réception de 8bits ou de
9 bits
'1' : réception de 9 bits
'0' : réception de 8 bits
-En mode 9 bits, le 9ème bit sera lu dans le bit RX9D du registre RCSTA.
8 bits de données
2 bits STOP
sans parité
Registre SPBRG
erreur de 8,51%.
TX9 : '1' transmission de 9 bits (le 9ème bit sera un bit de STOP)
SENDB : '0'
for(;;) for(;;)
{ {
UART1_WRITE(PORTB); if( UART1_DATA_READY() )
delay_ms(500); {
} PORTB=UART1_READ();
} }
}
}
U1 TRANSMISSION U2 RECEPTION
1 15 1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI RE3/MCLR/VPP RC0/T1OSO/T1CKI
16 16
RC1/T1OSI/CCP2 RC1/T1OSI/CCP2
2 17 2 17
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1 RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18 3 18
RA1/AN1/C12IN1- RC3/SCK/SCL RA1/AN1/C12IN1- RC3/SCK/SCL
4 23 4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24 5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25 6 25
RA4/T0CKI/C1OUT RC6/TX/CK RA4/T0CKI/C1OUT RC6/TX/CK
7 26 7 26
RA5/AN4/SS/C2OUT RC7/RX/DT RA5/AN4/SS/C2OUT RC7/RX/DT
14 14
RA6/OSC2/CLKOUT RA6/OSC2/CLKOUT
13 19 13 19
RA7/OSC1/CLKIN RD0 RA7/OSC1/CLKIN RD0
20 20
RD1 RD1
33 21 33 21
RB0/AN12/INT RD2 RB0/AN12/INT RD2
34 22 34 22
RB1/AN10/C12IN3- RD3 RB1/AN10/C12IN3- RD3
35 27 35 27
RB2/AN8 RD4 RB2/AN8 RD4
36 28 36 28
RB3/AN9/PGM/C12IN2- RD5/P1B RB3/AN9/PGM/C12IN2- RD5/P1B
37 29 37 29
RB4/AN11 RD6/P1C RB4/AN11 RD6/P1C
38 30 38 30
RB5/AN13/T1G RD7/P1D RB5/AN13/T1G RD7/P1D
39 39
RB6/ICSPCLK RB6/ICSPCLK
40 8 40 8
RB7/ICSPDAT RE0/AN5 RB7/ICSPDAT RE0/AN5
9 9
RE1/AN6 RE1/AN6
10 10
RE2/AN7 RE2/AN7
PIC16F887 PIC16F887
U1 U2
1 15 1 15
RE3/MCLR/VPP RC0/T1OSO/T1CKI RE3/MCLR/VPP RC0/T1OSO/T1CKI
16 16
RC1/T1OSI/CCP2 RC1/T1OSI/CCP2
2 17 2 17
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1 RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1
3 18 3 18
RA1/AN1/C12IN1- RC3/SCK/SCL RA1/AN1/C12IN1- RC3/SCK/SCL
4 23 4 23
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
5 24 5 24
RA3/AN3/VREF+/C1IN+ RC5/SDO RA3/AN3/VREF+/C1IN+ RC5/SDO
6 25 6 25
RA4/T0CKI/C1OUT RC6/TX/CK RA4/T0CKI/C1OUT RC6/TX/CK
7 26 7 26
RA5/AN4/SS/C2OUT RC7/RX/DT RA5/AN4/SS/C2OUT RC7/RX/DT
14 14
RA6/OSC2/CLKOUT RA6/OSC2/CLKOUT
13 19 13 19
RA7/OSC1/CLKIN RD0 RA7/OSC1/CLKIN RD0
20 20
RD1 RD1
33 21 33 21
RB0/AN12/INT RD2 RB0/AN12/INT RD2
34 22 34 22
RB1/AN10/C12IN3- RD3 RB1/AN10/C12IN3- RD3
35 27 35 27
RB2/AN8 RD4 RB2/AN8 RD4
36 28 36 28
RB3/AN9/PGM/C12IN2- RD5/P1B RB3/AN9/PGM/C12IN2- RD5/P1B
37 29 37 29
RB4/AN11 RD6/P1C RB4/AN11 RD6/P1C
38 30 38 30
RB5/AN13/T1G RD7/P1D RB5/AN13/T1G RD7/P1D
39 39
RB6/ICSPCLK RB6/ICSPCLK
40 8 40 8
RB7/ICSPDAT RE0/AN5 RB7/ICSPDAT RE0/AN5
9 9
RE1/AN6 RE1/AN6
10 10
RE2/AN7 RE2/AN7
PIC16F887 PIC16F887