Vous êtes sur la page 1sur 22

1

Les microcontrleurs

PIC
de Microchip
Le 16F84

Sommaire
INTRODUCTION ...................................................................................................................... 3
I

Le PIC 16F84 ....................................................................................................................4


I.1
Aspect externe du 16F84 ............................................................................................4
I.2
La mmoire programme (flash) ...................................................................................5
I.3
La mmoire RAM - Rrgistres........................................................................................5
I.4
L'ALU et le registre W .................................................................................................5
I.5
L'Horloge ...................................................................................................................6
I.6
Le ports d' E/S PORTA ................................................................................................6
I.7
Le ports d' E/S PORTB ................................................................................................7
I.8
Le Timer TMR0 ..........................................................................................................7
I.9
Le Timer Watchdog WDT (Chien de garde) ..................................................................8
I.10
Le mode SLEEP ..........................................................................................................8
I.11
La mmoire EEPROM de configuration .........................................................................9
I.12
La mmoire EEPROM de donnes................................................................................9
I.12.1
Procdure de lecture dans l'EEPROM de donnes ................................................ 10
I.12.2
Procdure d'criture dans l'EEPROM de donnes ................................................. 10
I.13
Les interruptions ...................................................................................................... 10
I.13.1
Droulement d'une interruption ......................................................................... 10
I.13.2
L'interruption INT (Entre RBO DU PORTB) ........................................................ 11
I.13.3
L'interruption RBI (RB4 A RB7 DU PORTB).......................................................... 11
I.13.4
L'interruption T0I : Dbordement du Timer TMR0 ............................................... 11
I.13.5
L'interruption EEI : Fin d'criture dans l'EEPROM................................................. 11
I.14
L'adressage indirect.................................................................................................. 11
I.15
Le conteur programme ............................................................................................. 11
I.15.1
GOTO calcul.................................................................................................... 12
I.16
Les indicateurs ......................................................................................................... 12
I.17
Les instructions du 16F84 ......................................................................................... 12
I.17.1
Les instructions orientes octet (adressage direct) ........................................ 12
I.17.2
Les instructions orientes bits ...................................................................... 13
I.17.3
Les instructions oprant sur une donne (adressage immdiat) ........................... 13
I.17.4
Les instructions de saut et appel de procdures .................................................. 13
I.17.5
Le jeu d'instructions .......................................................................................... 14
I.17.6
Etat de quelque registre l'initialisation.............................................................. 14

II

Les outils de dveloppement ............................................................................................ 15


II.1
Deux mot sur MPLAB ................................................................................................ 15
II.2
Les directives de MPASM .......................................................................................... 16
II.2.1
Les directives les plus utilises ........................................................................... 16
II.3
Format des nombres ................................................................................................ 17
II.4
Structure d'un programme crit en assembleur .......................................................... 17
II.5
Exemples de programme .......................................................................................... 19
II.6
Rfrences............................................................................................................... 22

INTRODUCTION
Un PIC est un microcontrleur, cest une unit de traitement de linformation de type
microprocesseur laquelle on a ajout des priphriques internes permettant de faciliter
l'interfaage avec le monde extrieur sans ncessiter lajout de composants externes.
Les PICs sont des composants RISC (Reduce Instructions Construction Set), ou encore
composant jeu dinstructions rduit. L'avantage est que plus on rduit le nombre dinstructions,
plus facile et plus rapide en est le dcodage, et plus vite le composant fonctionne.
La famille des PICs est subdivise en 3 grandes familles : La famille Base-Line, qui utilise des
mots dinstructions de 12 bits, la famille Mid-Range, qui utilise des mots de 14 bits (et dont font
partie la 16F84 et 16F876), et la famille High-End, qui utilise des mots de 16 bits.
Nous nous limiterons dans ce document la famille Mid-Range et particulirement au PIC
16F84, sachant que si on a tout assimil, on pourra facilement passer une autre famille, et
mme un autre microcontrleur.

Pour identifier un PIC, on utilise simplement son numro :


Les 2 premiers chiffres indiquent la catgorie du PIC, 16 indique un PIC Mid-Range.
Vient ensuite parfois une lettre L, celle-ci indique que le PIC peut fonctionner avec une plage
de tension beaucoup plus tolrante.
Vient en suite une ou deux lettres pour indiquer le type de mmoire programme :
- C indique que la mmoire programme est une EPROM ou plus rarement une EEPROM
- CR pour indiquer une mmoire de type ROM
- F pour indiquer une mmoire de type FLASH.
On trouve ensuite un nombre qui constitue la rfrence du PIC.
On trouve ensuite un tiret suivi de deux chiffres indiquant la frquence dhorloge maximale que
le PIC peut recevoir.

Donc, un 16F84-04 est un PIC Mid-Range donc la mmoire programme est de type FLASH de
rfrence 84 et capable daccepter une frquence dhorloge de 4MHz.
Notez que les PICs sont des composants STATIQUES, cest dire que la frquence dhorloge
peut tre abaisse jusque larrt complet sans perte de donnes et sans dysfonctionnement. Une
version 10 peut donc toujours tre employe sans problme en lieu et place dune 04. Pas
linverse, naturellement.

Pourquoi choisir un PIC ?

Les performances sont identiques voir suprieurs ses concurrents


Les prix sont les plus bas du march
Trs utilis donc trs disponible
Les outils de dveloppement sont gratuits et tlchargeables sur le WEB
Le jeu d'instruction rduit est souple, puissant et facile matriser
Les versions avec mmoire flash prsentent une souplesse d'utilisation et des avantages
pratiques indniables
La communaut des utilisateurs des PICs est trs prsente sur le WEB. On trouve sur le net
quasiment tout ce dont on a besoin, tutoriaux pour dmarrer, documents plus approfondis,
schmas de programmeurs avec les logiciels qui vont avec, librairies de routines, forums de
discussion . . .

LE PIC 16F84
Les caractristiques principales du 16F84 sont :
Une mmoire programme de type flash de 1K (1024) mots de 14 bits
Une mmoire RAM constitue :
o Des registres de control SFR (Special Function Registers)
o 68 octets de RAM utilisateur appels aussi GPR (General Propose Resisters)
Une mmoire EEPROM de donne de 64 octets
Deux ports d'entre sortie, un de 8 bits et un de 5 bits
Un timer/Compteur cadenc par une horloge interne ou externe
Un chien de garde / compteur qui est un timer particulier
Un prdiviseur de frquence programmable permettant d'tendre les possibilits du Timer
TMR0 et du chien de garde WDT
4 sources d'interruption
L'horloge peut tre gnre par 4 types d'oscillateurs slectionnables
Protection de code
Fonctionnement en mode sleep pour rduction de la consommation
Programmation par mode ICSP (In Circuit Serial Programming)

PORTA

PORTB
timer
TMR0

Horloge
systme
Prdiviseur
Horloge
WDT

WDT
timer

14 bits : config

ALU
16 registres
systme
RAM
utilisateur
64 octets
EEPROM
64 octets

I.1

Mmoire
programme
de type Flash
1024
mots de 14 bits

Aspect externe du 16F84

Le 16F84 est commercialis dans un botier 18 broches classique

RA2
RA3
RA4/T0CKI
MCLR
VSS
RB0/INT
RB1
RB2
RB3

1
18
2
17
3
16
4 PIC 15
5 16F8X 14
6
13
7
12
8
11
9
10

Fig. I-1 : brochage du 16 F84

RA1
RA0
OSC1
OSC2
Vdd
RB7
RB6
RB5
RB4

I.2

La mmoire programme (flash)

Cette mmoire de 1024 mots stocke le programme. Elle est non volatile et reprogrammable
souhait. Chaque position de 14 bits contient une instruction. L'emplacement du programme peut
se situer n'importe quel endroit de la mmoire. Cependant il faut savoir que suite un RESET ou
lors de la mise sous tension, le PIC commence l'excution l'adresse 0000H. De plus, lorsqu'il y a
une interruption, le PIC va l'adresse 0004H. Il est donc conseill de placer le dbut du
programme aprs l'adresse 0004H et de mettre un branchement au dbut du programme
l'adresse 0000H et un branchement au dbut de la routine d'interruption s'il y en a une l'adresse
0004H. Le programme est implant dans la flash l'aide d'un programmateur (hard+soft) sur
lequel nous reviendrons dans la suite de ce document.

I.3

La mmoire RAM - Rrgistres

La mmoire RAM est constitue de deux parties :


Les registres SFR (Special Function
Register), ce sont les registres de
fonctionnement du PIC. L'ensemble de ces
registres est souvent appel fichier des
registres. Nous reviendrons sur ces
registres tout le long de ce document.

Les registres GPR (General Propose


Register) sont des positions mmoire que
l'utilisateur peut utiliser pour stocker ses
variables et ces donnes. On remarquera
donc que, indpendamment de leur
nature, les position de la RAM sont
toujours appel registres

La mmoire RAM est organise en


deux banks, pour accder un registre, il
faut d'abord se placer dans le bank o il
se trouve. Ceci est ralis en positionnant
le bit RP0 du registre STATUS. (RP0 = 0
Bank 0, RP0 = 1 Bank 1)
Registre STATUS

IRP

RP1

00
01
02
03
04
05
06
07
08
09
0A
0B
0C
.
.
.
.
.
4F
RP0

TO

bank 0
INDF
TMR0
PCL
STATUS
FSR
PORTA
PORTB

bank 1
INDF
OPTION
PCL
STATUS
FSR
TRISA
TRISB

EEDATA
EEADR
PCLATH
INTCON

EECON1
EECON2
PCLATH
INTCON

Mmoire
utilisateur

Maped in bank0

PD

DC

80
81
82
83
84
85
86
87
88
89
8A
8B
8C
.
.
.
.
.
CF

Pour la mmoire utilisateur, l'utilisation des pages (Bank ) n'est pas ncessaire puisque le Bank
1 est "mapped" avec le Bank0. Cela signifie qu'crire une donne l'adresse 0CH ou l'adresse
8CH revient au mme.

I.4

L'ALU et le registre W

C'est une ALU 8 Bits qui ralise les oprations arithmtique et logique entre l'accumulateur W
et n'importe quel autre registre 'F' ou constante K. L'accumulateur W est un registre de travail 8
bits, il n'a pas d'adresse comme les autres SFR. Pour les instructions deux oprandes, c'est
toujours lui qui contient un des deux oprandes. Pour les instructions un oprande, celui-ci peut
tre soit W soit n'importe quel registre F. Le rsultat de l'opration peut tre plac soit dans le
registre de travail W soit dans le registre F.

I.5

L'Horloge

L'horloge peut tre soit interne soit externe.


L'horloge interne est constitue d'un oscillateur
quartz ou d'un oscillateur RC.
Avec l'oscillateur Quartz, on peut avoir des
frquences allant jusqu' 4, 10 ou 20 MHz selon le
type de C. Le filtre passe bas RS, C2 limite les
harmoniques dus lcrtage et Rduit lamplitude
de loscillation. (il n'est pas obligatoire)
Avec un oscillateur RC, la frquence de
l'oscillation est fixe par Vdd, Rext et Cext. Elle peut
varier lgrement d'un circuit l'autre.
Dans certains cas, une horloge externe au
microcontrleur peut tre utilise pour synchroniser
le PIC sur un processus particulier.
Quelque soit l'oscillateur utilis, l'horloge systme
dite aussi horloge instruction est obtenue en divisant
la frquence par 4. Dans la suite de ce document on
utilisera le terme Fosc/4 pour dsigner l'horloge
systme.
Avec un quartz de 4 MHz, on obtient une horloge instruction de 1 MHz, soit le temps pour
excuter une instruction de 1s.

I.6

Le port d' E/S PORTA

Le port A dsign par PORTA est un port de 5 bits (RA0 RA4). Chaque E/S est compatible
TTL. La configuration de direction pour chaque bit du port est dtermine avec le registre TRISA.
Bit i de TRISA = 0 bit i de PORTA configur en sortie
Bit i de TRISA = 1 bit i de PORTA configur en entre
La broche RA4 est multiplexe avec l'entre horloge du timer TMR0, elle peut donc tre utilise
soit comme E/S normale du port A, soit comme entre horloge pour le Timer TMR0, le choix se fait
l'aide du bit T0CS du registre OPTION_REG.
T0CS = 0 RA4 est une E/S normale
T0CS = 1 RA4 = horloge externe pour le timerTMR0
Vdd
RA4 est une E/S drain ouvert, si on veut l'utiliser comme sortie (pour
allumer une LED par exemple), il ne faut pas oublier de mettre une
RA4
rsistance externe vers Vdd. Le schma ci contre illustre (pour les non
lectronicien) le principe d'une sortie drain ouvert (ou collecteur ouvert) : si
RA4 est positionne 0, l'interrupteur est ferm, la sortie est relie la
masse. Si RA4 est place 1, l'interrupteur est ouvert, la sortie est
dconnecte d'o la ncessite de la rsistance externe pour amener le
courant de l'alimentation vers la LED. (la valeur de 1k est donne titre
indicatif, vous d'ajuster selon votre application)
Registre OPTION_REG

RBPU INTEDG TOCS TOSE

PSA

PS2

PS1

1k

LED

PS0

I.7

Le port d' E/S PORTB

Le port port B dsign par PORTB est un port bidirectionnel de 8 bits (RB0 RB7). Toutes les
broches sont compatibles TTL. La configuration de direction se fait l'aide du registre TRISB. (Voir
PORTA / TRISA)
En entre, la ligne RB0 appele aussi INT peut dclencher linterruption externe INT.
En entre, une quelconque des lignes RB4 RB7 peut dclencher l'interruption RBI.
Nous reviendrons l-dessus dans le paragraphe rserv aux interruptions.

I.8

Le Timer TMR0

Cest un compteur 8 bits ayant les caractristiques suivantes :

Il est incrment en permanence soit par lhorloge interne Fosc/4 (mode timer) soit par une
horloge externe applique la broche RA4 du port A (mode compteur). Le chois de l'horloge
se fait l'aide du bit T0CS du registre OPTION_REG
o TOCS = 0 horloge interne
o TOCS = 1 horloge externe applique RA4

Dans le cas de l'horloge externe, on peut choisir le front sur lequel le TIMER s'incrmente.
o TOSE = 0 incrmentation sur fronts montants
o TOSE = 1 incrmentation sur fronts descendants
PS2 PS1 PS0 Div
0
0
0
2
Quelque soit l'horloge choisie, on peut la passer dans un diviseur de
0
0
1
4
frquence programmable (prescaler) dont le rapport est fixs par les
0
1
0
8
bits PS0, PS1 et PS2 du registre OPTION_REG (tableau ci-contre).
0
1
1
16
L'affectation ou non du prdiviseur se fait l'aide du bit PSA du
1
0
0
32
registre OPTION_REG
1
0
1
64
o PSA = 0 on utilise le prdiviseur
1
1
0
128
o PSA = 1 pas de prdiviseur (affect au chien de garde)
1
1
1
256
Le contenu du timer TMR0 est accessible par le registre qui porte le
mme nom. Il peut tre lu ou crit n'importe quel moment. Aprs une criture,
l'incrmentation est inhibe pendant deux cycles instruction

Au dbordement de TMR0 (FF 00), le drapeau T0IF est plac 1. Ceci peut dclencher
l'interruption T0I si celle-ci est valide

Registre OPTION_REG

RBPU INTEDG TOCS TOSE

T0CS

T0SE
RA4

Horloge
Systme
Fosc

Fosc/4

PS2

PS1

PS0

PSA

1
0

PSA

TMR0
Prdiviseur
programmable
PS2

PS1 PS0

T0IF

I.9

Le Watchdog Timer WDT (Chien de garde)

Cest un compteur 8 bits incrment en permanence (mme si le C est en mode sleep) par
une horloge RC intgre indpendante de l'horloge systme. Lorsquil dborde, (WDT TimeOut),
deux situations sont possibles :

Si le C est en fonctionnement normal, le WDT time-out provoque un RESET. Ceci permet


dviter de rester plant en cas de blocage du microcontrleur par un processus indsirable
non contrl
Si le C est en mode SLEEP, le WDT time-out provoque un WAKE-UP, l'excution du
programme continue normalement l o elle s'est arrte avant de rentrer en mode SLEEP.
Cette situation est souvent exploite pour raliser des temporisations

L'horloge du WDT est ajuste pour que Le Time-Out arrive toutes les 18 ms. Il est cependant
possible d'augmenter cette dure en faisant passer le signal Time-Out dans un prdiviseur
programmable (partag avec le timer TMR0). l'affectation se fait l'aide du bit
PS2 PS1 PS0 Div
PSA du registre OPTION_REG
0
0
0
1
o PSA = 1 on utilise le prdiviseur
0
0
1
2
o PSA = 0 pas de prdiviseur (affect TMR0)
0
1
0
4
1
1
8
Le rapport du prdiviseur est fix par les bits PS0, PS1 et PS2 du registre 0
OPTION_REG (voir tableau ci-contre)
1
0
0 16
1
0
1 32
L'utilisation du WDT doit se faire avec prcaution pour viter la 1
1
0 64
rinitialisation (inattendue) rpte du programme. Pour viter un WDT 1
1
1 128
timeOut lors de l'excution d'un programme, on a deux possibilits :
Inhiber le WDT d'une faon permanente en mettant 0 le bit WDTE dans l'EEPROM de
configuration
Remettre le WDT 0 priodiquement dans le programme l'aide de l'instruction CLRWDT pour
viter qu'il ne dborde
PSA
Horloge
WDT

WDT

WDT timeout
1

Prdiviseur
programmable
PS2

PS1 PS0

I.10 Le mode SLEEP


Le PIC peut tre plac en mode faible consommation l'aide de l'instruction SLEEP. Dans ce
mode, l'horloge systme est arrte ce qui arrte l'excution du programme.
Pour sortir du mode SLEEP, il faut provoquer un WAKE-UP, pour cela il y a 3 possibilits :
RESET externe d l'initialisation du PIC en mettant l'entre MCLR 0. Le PIC reprend
l'excution du programme partir du dbut.
Timeout du chien de garde WDT si celui-ci est valid. Le PIC reprend le programme partir de
l'instruction qui suit l'instruction SLEEP
Interruption INT (sur RB0) ou RBI (sur RB4-RB7) ou EEI (fin d'criture en EEPROM de
donnes). Le bit de validation de l'interruption en question doit tre valid, par contre, le
WAKE-UP a lieu quelque soit la position de bit de validation globale GIE. On a alors deux
situations :

o
o

GIE = 0, Le PIC reprend l'excution du programme partir de l'instruction qui suit


l'instruction SLEEP, l'interruption n'est pas prise en compte
GIE = 1, Le PIC excute l'instruction qui se trouve juste aprs l'instruction SLEEP puis se
branche l'adresse 0004 pour excuter la procdure d'interruption. Dans le cas o
l'instruction suivant SLEEP n'est pas dsire, il faut utiliser l'instruction NOP.

L'utilisation des interruptions pour raliser un WAKE-UP doit tre utilise avec prcaution. Voir
le data sheet [1][2] du 16F84 pour plus de prcisions.

I.11 La mmoire EEPROM de configuration


Pendant la phase d'implantation d'un programme dans la mmoire programme du PIC, on
programme aussi une EEPROM de configuration constitue de 5 mots de 14 bits :

4 mots didentification ( ID) partir de ladresse 0x2000 pouvant contenir un reprage


quelconque que nous n'utiliserons pas,

1 mot de configuration (adresse 0x2007) qui permet :


o de choisir le type de l'oscillateur pour l'horloge
o de valider ou non le WDT timer
o dinterdire la lecture des mmoires EEPROM de programme et de donnes.
13 12 11 10 9 8 7 6 5 4
3
2
1
0
CP CP CP CP CP CP CP CP CP CP PWRTE WDTE FOSC1 FOSC0

bits 1:0

FOSC1:FOSC0
11 : Oscillateur
10 : Oscillateur
01 : Oscillateur
00 : Oscillateur

bit

WDTE
validation du timer WDT (chien de garde)
1 : WDT valid
0 : WDT inhib

Bit 3

PWRTE
validation d'une temporisation la mise sous tension
1 : temporisation inhibe
0 : temporisation valide

Bit 13:4

CP
Protection en lecture du code programme
1 : pas de protection
0 : protection active

Slection du type d'oscillateur pour l'horloge


RC
HS (High speed) : quartz haute frquence (jusqu' 10 MHz)
XT, c'est le mode le plus utilis, quartz jusqu' 4 MHz
LP (Low power), consommation rduite, jusqu' 200 kHz

I.12 La mmoire EEPROM de donnes


La mmoire EEPROM de donnes est constitue de 64 octets commenant l'adresse 0x2100
que l'on peut lire et crire depuis un programme. Ces octets sont conservs aprs une coupure de
courant et sont trs utiles pour conserver des paramtres semi permanents.
On y accde l'aide des registres EEADR et EEDATA : toute lecture criture dans le registre
EEDATA se fait dans la position mmoire pointe par EEADR. En fait EEADR contient l'adresse
relative par rapport la page qui commence en 0x2100, autrement dit, l'adresse va de 0 63.
Deux registres de contrle (EECON1 et EECON2) sont associs la mmoire EEMROM.

10

La dure dcriture dun octet est de lordre de 10 ms, la fin de chaque criture russie est
annonc par le drapeau EEIF et la remise zro du bit RW du registre EECON1. Le drapeau EEIF
peut dclencher l'interruption EEI si elle a t valide.
I.12.1 Procdure de lecture dans l'EEPROM de donnes

Placer ladresse relative dans EEADR


Mettre le bit RD de EECON1 1
Lire le contenu du registre EEDATA

I.12.2 Procdure d'criture dans l'EEPROM de donnes


1.
2.
3.
4.
5.
6.
7.
8.

L'criture dans L'EEPROM doit tre autorise : bit WREN = 1


Placer ladresse relative dans EEADR
Placer la donne crire dans EEDATA
Placer 0x55 dans EECON2
Placer 0xAA dans EECON2
Dmarrer l'criture en positionnant le bit WR
Attendre la fin de l'criture, (10 ms) (EEIF=1 ou WR=0)
recommencer au point 2 si on a d'autres donnes crire

Le drapeau WRERR est positionn si une erreur d'criture intervient


EECON1

EEIF

WRERR WREN

WR

RD

EECON2 nen est pas vritablement un Registre. Microchip lutilise en tant que registre de
commande. Lcriture de valeurs spcifiques dans EECON2 provoque lexcution dune commande
spcifique dans llectronique interne du PIC.

I.13 Les interruptions


Une interruption provoque larrt du programme principal pour aller excuter une procdure
d'interruption. A la fin de cette procdure, le microcontrleur reprend le programme lendroit o
il stait arrt. Le PIC16F84 possde 4 sources d'interruption. A chaque interruption sont associs
deux bits: un bit de validation et un drapeau. Le premier permet d'autoriser ou non l'interruption,
le second permet au programmeur de savoir de quelle interruption il s'agit. Tous ces bits sont dans
le registre INTCON part le drapeau EEIF de l'interruption EEI qui se trouve dans le registre
EECON1.
I.13.1 Droulement d'une interruption
Lorsque l'vnement dclencheur d'une interruption intervient, alors son drapeau est
positionn un (lev). Si l'interruption correspondante a t valide, elle est alors dclenche : le
programme arrte ce qu'il est en train de faire et va excuter la procdure d'interruption qui se
trouve l'adresse 4 en excutant les tapes suivantes :
l'adresse contenue dans le PC (Program Counter) est sauvegarde dans la pile, puis remplace
par la valeur 0004 (adresse de la routine d'interruption).
Le bit GIE est plac "0" pour inhiber toutes les interruptions (afin qu'on ne soit pas drangs
pendant l'excution de la procdure d'interruption).
A la fin de la procdure d'interruption (instruction RETFIE) :
o le bit GIE est replac l'tat haut (autorisant ainsi un autre vnement)
o le contenu du PC est recharg partir de la pile ce qui permet au programme de reprendre
l o il s'est arrt
Deux remarques importantes sont faire :

11

Le drapeau reste ltat haut mme aprs le traitement de linterruption. Par consquent, il
faut toujours le remettre "0" la fin de la routine d'interruption sinon l'interruption sera
dclenche de nouveau juste aprs l'instruction RETFI
Seul le PC est empil automatiquement. Si cela est ncessaire, les registres W et STATUS
doivent tre sauvegards en RAM puis restaurs la fin de la routine pour que le
microcontrleur puisse reprendre le programme dans les mmes conditions o il l'a laiss.

I.13.2 L'interruption INT (Entre RB0 du port B)


Cette interruption est provoque par un changement d'tat sur l'entre RB0 du port B quand
elle est programme en entre. Elle est gre par les bits :
- INTE : bit de validation (1=oui, 0=non)
- INTF : drapeau
- INTEDG : front de dclenchement, 1=montant, 0=descendant (registre OPTION_REG)
I.13.3 L'interruption RBI (RB4 A RB7 du port B)
Cette interruption est provoque par un changement d'tat sur l'une des entres RB4 RB7 du
port B, Le front n'a pas d'importance. Les bits associs sont RBIE (validation) et RBIF (drapeau)
I.13.4 L'interruption T0I : Dbordement du Timer TMR0
Cette interruption est provoque par le dbordement du timer TMR0. Les bits associs sont
T0IE (validation) et T0IF (drapeau)
I.13.5 L'interruption EEI : Fin d'criture dans l'EEPROM
Cette interruption est dclenche la fin d'une criture russie dans l'EEPROM.
Les bits associs sont EEIE (validation) et EEIF (drapeau).
INTCON
GIE
EEIE
T0IF
EECON1
OPTION_REG RBPU INTEDG TOCS

INTE
RBIE
T0IF INTF RBIF
EEIF WRERR WREN WR
RD
TOSE
PSA
PS2
PS1 PS0

GIE : ce bit permet de valider ou d'interdire (globalement) toutes les interruptions

I.14 L'adressage indirect


L'adressage indirect se fait par l'intermdiaire des registres FSR et INDF. Le registre INDF n'est
pas un vrai registre mais reprsente la case mmoire pointe par le registre d'index FSR. Pour lire
ou crire dans une case mmoire en utilisant l'adressage indirect, on commence par placer
l'adresse dans le registre FSR, ensuite on lit/crit dans le registre INDF

I.15 Le conteur programme


Le Program Counter est un registre de 13 bits qui s'incrmente automatiquement lors de
l'excution du programme. On peut toutefois le modifier par programme pour raliser ce qu'on
appelle un goto calcul. On y accde par les registres PCL et PCLATH

12

PCH

PCL

PCL (8 bits) est la partie basse de PC, il est accessible en lecture criture
PCH (5 bits) est la partie haute de PC, il n'est pas accessible directement. On peut toutefois le
modifier indirectement l'aide du registre PCLATH qui est une registre SFR accessible en
lecture criture et o seuls 5 bits sont utiliss.

I.15.1 GOTO calcul


Si on veut modifier le Program Counter pour raliser un saut, il faut d'abord placer la partie
haute dans le registre PCLATH, ensuite on crit la partie basse dans PCL. Au moment de l'criture
dans PCL, le contenu de PCLATH est recopi automatiquement dans PCH
PCH

PCL

PCLATH

Ecriture dans PCL

Dans les instructions de branchement, l'adresse de destination est code sur 11 bits. Lors de
l'excution de telles instruction, les 11 bits sont copis dans PC les deux bits manquants sont pris
dans PCLATH. Pour le 16F84, On n'aura pas besoin de ces bits car pour adresser 1024 lignes de
programme, seuls 10 bits du Programme Counter sont utiliss.
PC

PCLATH

11 bits venant de l'instruction

I.16 Les indicateurs


Les indicateurs C, DC, et Z sont des bits qui nous informent sur le rsultat d'une instruction. Ils
sont situs dans le registre STATUS
:
RP0
Z
DC
C

C (Carry) : ce bit Il passe "1" lorsque le rsultat d'une opration dpasse la valeur FF ou si
le rsultat est ngatif.
DC (Digital Carry) : ce bit passe "1" lorsque une retenue s'est produite entre les bit 3 et 4.
Z (Zero) : Ce bit passe "1", pour indiquer que le rsultat de l'opration est nul.

I.17 Les instructions du 16F84


Tous les PICs Mid-Range ont un jeu de 35 instructions. Chaque instruction est code sur un
mot de 14 bits qui contient le code opration (OC) ainsi que l'oprande. A part les instructions de
saut, toutes les instructions sont excutes en un cycle d'horloge. Sachant que lhorloge fournie au
PIC est prdivise par 4, si on utilise par exemple un quartz de 4MHz, on obtient donc 1000000
cycles/seconde, cela nous donne une puissance de lordre de 1MIPS (1 Million d Instructions Par
Seconde). Avec une horloge de 20MHz, on obtient une vitesse de traitement plus quhonorable.
I.17.1 Les instructions orientes octet (adressage direct)
Ce sont des instructions qui manipulent les donnes sous forme doctets. Elles sont codes de
la manire suivante :

13

6 bits pour linstruction : logique, car comme il y a 35 instructions, il faut 6 bits pour pouvoir
les coder toutes

1 bit (d) pour indiquer si le rsultat obtenu doit tre conserv dans le registre de travail
(accumulateur) W de lunit de calcul (W pour Work) ou sauv dans un registre F (F pour File).

Reste 7 bits pour encoder l'adresse de loprande (128 positions au total)

Problme ! 7 bits ne donnent pas accs la mmoire RAM totale, donc voici lexplication de la
division de la RAM en deux banks. Pour remplacer le bit manquant, on utilise le bit RP0 du registre
STATUS.
Bien qu'on ne l'utilise pas sur le 16F84, le bit RP1 est aussi rserv pour le changement de
bank, le 16F876 par exemple possde 4 banks.
I.17.2 Les instructions orientes bits
Ce sont des instructions destines manipuler directement les bits dun registre d'une case
mmoire. Elles sont codes de la manire suivante :
-

4 bits pour linstruction


3 bits pour indiquer le numro du bit manipuler (de 0 7)
7 bits pour indiquer loprande.

I.17.3 Les instructions oprant sur une donne (adressage immdiat)


Ce sont les instructions qui manipulent des donnes qui sont codes dans linstruction
directement. Elles sont codes de la manire suivante :
-

Linstruction est code sur 6 bits


Elle est suivie dune valeur IMMEDIATE code sur 8 bits (donc de 0 255).

I.17.4 Les instructions de saut et appel de procdures


Ce sont les instructions qui provoquent une rupture dans la squence de droulement du
programme. Elles sont codes de la manire suivante :
- Les instructions sont codes sur 3 bits
- La destination est code sur 11 bits
Nous pouvons dj en dduire que les sauts ne donnent accs qu 2K de mmoire
programme (211). Pas de problme pour le 16F84 qui ne possde que 1k de mmoire programme.
I.17.5 Exemples d'instruction
MOVWF F
; recopie W dans le registre d'adresse F : .W

.F.
F (File) dsigne l'adresse de n'importe quel registre SFR ou GPR. Pour les registres SFR, on peut
utiliser leurs noms condition d'inclure le fichier p16F84.inc dans le programme
MOVWF
0x2C
; recopie W dans la case mmoire d'adresse 2Ch
MOVWF
EEDATA
; recopie W dans le registre EEDATA
MOVF
0x08
; recopie W dans le registre EEDATA
MOVF F,d ; recopie le registre F soit dans W soit dans lui-mme
Recopier un registre sur lui-mme peut paratre sans intrt, mais comme
l'instruction positionne les indicateurs, cela peut s'avrer intressant

d=1
F

d=0

14

I.17.6 Le jeu d'instructions


INSTRUCTIONS OPERANT SUR REGISTRE (direct)
ADDWF
F,d W+F {W,F ? d}
ANDWF
F,d W and F {W,F ? d}
CLRF
F
Clear F
CLRW
Clear W
CLRWDT
Clear Watchdoc timer
COMF
F,d Complmente F {W,F ? d}
DECF
F,d dcrmente F {W,F ? d}
DECFSZ
F,d dcrmente F {W,F ? d} skip if 0
INCF
F,d incrmente F {W,F ? d}
INCFSZ
F,d incrmente F {W,F ? d} skip if 0
IORWF
F,d W or F {W,F ? d}
MOVF
F,d F {W,F ? d}
MOVWF F
WF
RLF
F,d rotation gauche de F a travers C {W,F ? d}
RRF
F,d rotation droite de F a travers C {W,F ? d}
SUBWF
F,d F W {W,F ? d}
SWAPF
F,d permute les 2 quartets de F {W,F ? d}
XORWF
F,d W xor F {W,F ? d}

indicateurs Cycles
C,DC,Z
1
Z
1
Z
1
Z
1
TO', PD'
1
Z
1
Z
1
1(2)
Z
1
1(2)
Z
1
Z
1
1
C
1
1
C,DC,Z
1
1
Z
1

INSTRUCTIONS OPERANT SUR BIT


BCF
F,b RAZ du bit b du registre F
BSF
F,b RAU du bit b du registre F
BTFSC
F,b teste le bit b de F, si 0 saute une instruction
BTFSS
F,b teste le bit b de F, si 1 saute une instruction
INSTRUCTIONS OPERANT SUR DONNEE (Immediat)
ADDLW
K
W+KW
ANDLW
K
W and K W
IORLW
K
W or K W
MOVLW K
KW
SUBLW
K
KWW
XORLW
K
W xor K W
INSTRUCTIONS GENERALES
CALL
L
Branchement un sous programme de label L
GOTO
L
branchement la ligne de label L
NOP
No operation
RETURN
retourne d'un sous programme
RETFIE
Retour d'interruption
RETLW
K
retourne d'un sous programme avec K dans W
SLEEP
se met en mode standby

1
1
1(2)
1(2)

C,DC,Z
Z
Z
C,DC,Z
Z

1
1
1
1
1
1

TO', PD'

2
2
1
2
2
2
1

{W,F ? d} signifie que le rsultat va soit dans W si d=0 ou w, soit dans F si d= 1 ou f


I.17.7 Etat de quelque registre l'initialisation
STATUS
OPTION_REG
INTCON
EECON1

IRP
RP1
RP0 TO
PD
Z
DC
C
000x xxxx
RBPU INTEDG TOCS TOSE PSA
PS2
PS1 PS0 1111 1111
GIE
EEIE
T0IF INTE RBIE
T0IF INTF RBIF 0000 000x
EEIF WRERR WREN WR
RD - - -0 x000

TRISA
TRISB
PORTA
PORTB

- - -1 1111
1111 1111
- - -x xxxx
xxxx xxxx

15

II

LES OUTILS DE DEVELOPPEMENT


Les tapes ncessaires permettant de voir un programme s'excuter sur un PIC sont :

Ecrire un programme en langage assembleur dans un fichier texte et le sauvegarder avec


l'extension .asm
Compiler ce programme avec l'assembleur MPASM fourni par Microchip. Le rsultat est un
fichier avec l'extension .hex contenant une suite d'instruction comprhensible par le pic.
Transplanter le fichier .hex dans la mmoire programme du PIC (mmoire flash) l'aide d'un
programmateur adquat. On peut utiliser les programmateurs de Microchip ou tout autre
programmateur achet ou ralis par soit mme.
Mettre le PIC dans son montage final, mettre sous tension et admirer le travail.

Microchip propose gratuitement l'outil de dveloppement MPLAB qui regroupe l'diteur de


texte, le compilateur MPASM, un outil de simulation et le logiciel de programmation. Le
programmateur lui-mme, n'est malheureusement pas gratuit.
Pour ce qui nous concerne, nous utiliseront MPLAB pour crire, compiler et ventuellement
simuler nos programmes, ensuite nous utiliserons un programmateur fait maison pour implanter
les programmes dans la mmoire flash du PIC. Moi j'utilise le programmateur JDM avec le logiciel
ICPROG, les deux sont disponibles gratuitement sur le Web.

II.1

Deux mot sur MPLAB

MPLAB peut tre trouv sur les CD distribus par Microchip ou tlcharg directement du site
Web http://www.microchip.com
Nous allons raliser un tout petit programme sans grand intrt pour voir la procdure de
fonctionnement (avec MPLAB 6.30)

Debugger Select tool MPLAB SIM ( faire une fois aprs installation de MPLAB)
Configure Select Device PIC16F64A
Ouvrir une nouvelle fentre (de l'diteur) pour commencer crire un programme : file
new ou cliquez sur l'icne feuille blanche

Taper le petit programme ci-dessous dans la fentre qui vient de s'ouvrir. Ce programme
incrmente sans fin la position mmoire (RAM) 0CH

loop

incf 0x0C,1
goto looop
end

Sauvegarder (file save ) ce programme dans la directory de votre chois sous le nom

Lancer la compilation du programme l'aide de la commande project Quikbuild


Apparemment il y a un problme, le compilateur nous dit qu'il y une erreur la ligne 2 :

bidon.asm

Error[113] C:\...\BIDON.ASM 2 : Symbol not previously defined (looop)


Evidemment, le label loop dfinit dans la ligne prcdente prend seulement deux o. Corrigez et

recommencez. Cette fois a a l'air d'aller. On peut vrifier que le compilateur cre le fichier
bidon.hex dans la mme directory o se trouve bidon.asm. Les fichiers bidon.cod, bidon.err et
bidon.lst ne nous servent rien pour l'instant on peut les dtruire.

Nous pouvons maintenant excuter notre programme en simulation pour voir s'il ralise bien la
tache demande :

16

- Ouvrez la fentre qui visualise la mmoire RAM : view FileRegisters. La case mmoire
0x0C se trouve sur la premire ligne (ligne:0000, colonne:0C)
- Excuter maintenant le programme PAS PAS en cliquant chaque fois sur le bouton Step
Into {"} en observant la case mmoire 0C . (on dirait que a marche).

On peut aussi excuter en continu en cliquant sur le bouton animate  , pour arrter, il faut
cliquer sur le bouton halt 

Pour plus de dtail, consulter le manuel d'utilisation de MPLAB

II.2

Les directives de MPASM

Les directives de l'assembleur sont des instructions qu'on ajoute dans le programme et qui
seront interprtes par l'assembleur MPASM. Ce ne sont pas des instructions destines au PIC.
II.2.1 Les directives les plus utilises

LIST : permet de dfinir un certain nombre de paramtres comme le processeur utilis (p), la
base par dfaut pour les nombres (r), le format du fichier hex produire (f) ainsi que d'autres
paramtres. Exemple :
LIST
p=16F84A, r=dec, f=inhx8m

INCLUDE : permet d'insrer un fichier source. Par exemple le fichier p16f84A.inc contient la
dfinition d'un certain nombre de constante comme les noms des registres ainsi que les noms
de certain bits;
INCLUDE
"p16f84A.inc"

__CONFIG : permet de dfinir les 14 fusibles de configuration qui seront copi dans l'EEPROM
de configuration lors de l'implantation du programme dans le PIC (protection de code, type
d'oscillateur, chien de garde et temporisation du dpart)
__CONFIG B'11111111111001'
__CONFIG H'3FF9'
si le fichier p16f84.inc a t insr, on peut utiliser les constantes prdfinies :
__CONFIG _CP_OFF & _XT_OSC & _PWRTE_OFF & _WDT_OFF

EQU : permet de dfinir une constante ou une variable :


XX
EQU
0x20
Chaque fois que le compilateur rencontrera XX, il la remplacera soit par la constante 0x20. a
peut tre une constante s'il s'agit d'une instruction avec adressage immdiat, ou d'une adresse
s'il s'agit d'une instruction avec adressage direct.

#DEFINE : dfinit un texte de substitution


#DEFINE pos(x,y,z)
(y-2z+x)
Chaque fois que le compilateur rencontrera le texte pos(x,y,z), il le remplacera par (y-2z+x)

ORG : dfinit la position dans la mmoire programme partir de laquelle seront inscrites les
instructions suivantes.

CBLOCK/ENDC : dfinit un bloc de constantes


CBLOCK
0X0C
var1,var2
k
ENDC

; var1=0x0C, var2=0x0D, k=0x0D

17

DE : pour dclarer des donns qui seront stocke dans l'EEPROM de donne au moment de
l'implantation du programme sur le PIC
ORG
DE

0x2100
"Programmer un PIC, rien de plus simple", 70, 'Z'

DT : pour dclarer un tableau RETLW


proc

addwf
PCL,f
; saut la position : (position suivante + W)
DT "Programmer un PIC",23,0x47 ; L'assembleur remplacera cette ligne par la suite
d'instructions :
RTLW 'P'
RTLW 'r'
RTLW 'o'
. . .
RTLW 'C'
RTLW 23
RTLW 0x47

END : indique la fin du programme


Pour plus de dtail sur les directives de MPASM, voir "MPASM USER'S GUIDE"

II.3

Format des nombres

L'assembleur reconnat les nombres en dcimal, hexadcimal, binaire ou octal. Pour prciser la
base il faut utiliser les prfixes prciss dans le tableau ci-dessous :
On peut l'aide de la directive LIST ou RADIX dfinir
un format par dfaut. Si par exemple on place une des
instructions suivantes au dbut du programme, tous les
nombres sans prfix seront interprts en dcimal :

LIST r = dec
RADIX dec
(les radix valables sont dec, hex ou oct)

II.4

Base
Dcimal

Prfixe
D'nnn'
.nnn
Hexadcimal H'nn'
0xnn
nnh
Binaire
B'.'
Octal
O'nnn'

Exemple (36)
D'36'
.36
H'24'
0x24
24h
B'00100100'
O'44'

Structure d'un programme crit en assembleur

Un programme crit en assembleur doit respecter une certaine syntaxe et un certain nombre
de rgles afin qu'il soit facile lire et dbuguer :

Tout ce qui commence la premire colonne est considr comme une tiquette (label)
permettant de faire des renvois et aussi des assignations de constantes et de variables.

tout ce qui suit un point virgule est considr comme un commentaire non interprt par le
compilateur

Un programme apparat donc comme un texte crit sur 3 colonnes :


- la colonne de gauche contient les tiquettes
- la colonne du milieu contient les linstructions
- la colonne de droite contient des commentaires

Il existe diffrentes coles indiquant comment doit tre organis un programme. Voici un
exemple d'organisation :

1) Quelques lignes de commentaire prcisant la fonction du programme,

18

2) Configuration, exemple :
LIST
INCLUDE
__CONFIG

p=16f84, f=inhx8m, r = dec


"p16f84.inc"
H'3FF9'

3) Dfinition des constantes et des variables, exemple :


led
x
cblock
y,z
u,v,w
endc

equ
equ
0x0D

0
0x0C

4) Si le programme utilise des interruptions, mettre l'adresse 0000 (adresse du RESET) une
instruction de branchement au dbut du programme principal :
org 0
goto debut

5) Ecrire la routine d'interruption l'adresse 4


ORG 4
crire la routine d'interruption ici
RETFIE
Si le programme est configur pour interdire les interruptions, on peut se passer des
tapes 4) et 5),

6) Ecrire les sous programmes (s'il y en a). Chaque procdure commence par une tiquette
qui reprsente son nom, et se termine par l'instruction RETURN

7) Ecrire le programme principal (commenant par l'tiquette dbut: si les tapes 4 et 5 sont
prsentes)

8) terminer avec la directive END

19

II.5

Exemples de programme

;*******************************************************************************************************
; programme led_int.asm
; on connecte un interrupteur sur RB0 (entre) et une LED sur RB1 (sortie)
; Si on place l'interrupteur 1, la LED doit s'allumer, si on le met zro, elle doit s'teindre
;********************************************************************************************************
LIST
p=16f84A, f=inhx8m, r = dec
INCLUDE "p16f84A.inc"
__CONFIG _CP_OFF & _XT_OSC & _PWRTE_OFF & _WDT_OFF

tst

off

bsf
movlw
movwf
bcf

STATUS,RP0
B'00000001'
TRISB
STATUS,RP0

btfss
goto
bsf
goto
bcf
goto

PORTB,0
off
PORTB,1
tst
PORTB,1
tst

; bank 1
; pour configurer RB0 en entre
; bank 0

end
;***********************************************************************************************************************************
; programme led-tmr0-1.asm
; faire clignoter une LED connecte sur une sortie du port B, la temporisation permettant d'ajuster la frquence
; est obtenue par scrutation des dbordement du timer TMR0
;***********************************************************************************************************************************
LIST
p=16f84A, f = inhx8m, r = dec
__CONFIG_CP_OFF & _XT_OSC & _PWRTE_OFF & _WDT_OFF
INCLUDE "p16f84A.inc"
CTR

equ

0x0C

bsf
clrf
movlw
movwf

STATUS,RP0
TRISB
B'00000111'
OPTION_REG

bcf

STATUS,RP0

; PSA=0, prdiviseur affect TMR0, PS1 PS2 PS3 = 111, div = 256
; T0CS=0, horloge TMR0 = fosc/4/div
; retour bank 0

encore:

comf
call
goto

PORTB,f
delay
encore

; complmenter PORTB
; attendre un peu
; recommencer

delay:

movlw
movwf
btfss
goto
bcf
decfsz
goto
return

5
CTR
INTCON,T0IF
$-1
INTCON,T0IF
CTR,f
tst

; pour attendre que TMR0 dborde 5 fois


; ce qui donne 5 x 256 x 256 s
; attendre que TMR0 dborde

tst:

end

; bank 1 (pour TRISB et OPTION_REG)


; PORTB en sortie

; baisser le drapeau
; pour recommencer CTR fois

20

;************************************************************************************************************************
; programme led-tmr0-2.asm
; faire clignoter une LED connecte sur une sortie du port B. La temporisation permettant d'ajuster la
; frquence est obtenue en comptant les dbordements du timer TMR0 l'interieur de l'interruption T0I
; TMR0 est utilis en timer avec un prdiviseur de 256. En comptant 5 dbordement on obtient une
; temporisation de 4 x 256 x 256 s
;**********************************************************************************************************************
list p=16f84,f=inhx8m,r=dec
__config _PWRTE_OFF & _CP_OFF & _WDT_OFF & _XT_OSC
#include "p16f84.inc"
CTR

equ

0x0C

; varible de comptage

; ================= dmarrage sur RESET


org 0
goto start
;================= procedure d'interruption
org
4
bcf
INTCON,T0IF ; baisser le drapeau lev par l'interruption
decfsz
CTR,f
retfie
comf
PORTB,f
; changer l'tat de la LED
movlw 5
; initializer compteur
movwf CTR
retfie
;================= Programme principal
start
bsf
STATUS,RP0 ; select bank1
clrf
TRISB
; programme tous les bits du bort B en sortie
movlw
B'00000111'
; mode timer, prdiviseur pour TMR0, div=256
movwf
OPTION_REG
bcf
STATUS,RP0 ; select bank0
movlw
B'10100000'
; autorisation Interruption T0I
movwf
INTCON
movlw 5
; initialise CTR pour le premier passage
movwf CTR
Loop
goto Loop
; le PIC reste plant ici et n'en sort que pour aller
; executer une interuption due au dbordement de TMR0
end

21

;********************************************************************************************************************
; Clignotement d'une LED relie la sortie 0 du port B. Les autres bits du port B ne sont pas affects
; La temporisation est ralise l'aide du Watchdog timer
;*********************************************************************************************************************
list p=16f84, f=inhx8m, r = dec
__config _PWRTE_OFF & _CP_OFF & _WDT_ON & _XT_OSC
#include "p16f84A.inc"
bsf
STATUS,RP0
bcf
TRISB,0
movlw B'00001101'
movwf
OPTION_REG
bcf
STATUS,RP0
movlw
1
Loop:

sleep
xorwf
PORTB,f
goto Loop

; select bank1
; RB0 en sortie
; prescaler affect au WDT, prescaler = 101 = 32
; dbordement du WDT tous les 32 x 18ms = 0.576 s
; select bank0
; bit 0 de W 1, le autres 0,
; passe en mode sleep, rveil dans 0.576 s
; complmente le bit 0 de PORTB
; recommence la loupe indfinitivement

end
;***************************************************************************
; Clignotement d'une LED relie n'importe quelle sortie du port B. La temporisation est ralise l'aide d'une boucle de
; retard base de 3 boucles imbriques N1 (256), N2 (256), N3 ( prciser)
; T1 : (N1-1) x (1+2) + 2 => N1=0=256 => T1 = 767 s
; T2 : T1 + (N2-1) x (1+2+T1) + 2, N2=0 => T2 = 196352 s
; T3 : T2+(N3-1) x (1+2+T2) + 2 + 2 = N3 x 196355 + 1 s (je croix)
;***************************************************************************
list p=16f84, f=inhx8m, r=dec
#include "p16f84A.inc"
__config _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_OFF
N1
equ
0x0D
; N1,N2,N3 = compteurs temporisateur
N2
equ
0x0E
N3
equ
0x0F
;=================================Programme principal
bsf
STATUS,RP0 ; select bank1
clrf
TRISB
; programme tous les bits du bort B en sortie
bcf
STATUS,RP0 ; select bank0
loop:

comf
movlw
call
goto

PORTB,f
3
tempo
loop

; complmente PORTB
; 3 donne une tempo voisine de 0.6 s
; recommence la loupe indfinitivement

;=================================Procdure de temporisation
tempo:
movwf
N3
; copier W dans N3
tmp
decfsz
N1,f
; boucle intrieure
goto
tmp
decfsz
N2,f
; boucle mdiane
goto
tmp
decfsz
N3,f
; boucle extrieure
goto
tmp
return
end

22

II.6
[1]
[2]
[3]

Rfrences
PIC16F8X, document DS30430C, www.microchip.com
PIC16F84a, document DS35007A, www.microchip.com
Programmation des PIC, Premire partie-PIC16F84-Rvision 5, par BIGONOFF,
http://www.abcelectronique.com/bigonoff/organisation.php?2654c

Vous aimerez peut-être aussi