Poly
Poly
ENSAM de Rabat
Mohammed ABDOUN
Table des matières
1.3.1 Représentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.5 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2 Introduction du PIC18FXX2 14
2.1 Structure d'un système automatisé . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1
TABLE DES MATIÈRES
2.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.2 Brochage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.4 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.3.1 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.5 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4 Les interruptions 37
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.3.4 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.4 Exercice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
M.ABDOUN 2
TABLE DES MATIÈRES
5 Les Timers 52
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.5.1 Timer0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.5.4 Timer1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
M.ABDOUN 3
Chapitre 1
1.1 Introduction
L'informatique industrielle couvre l'ensemble des techniques de conception d'analyse et de pro-
grammation de systèmes à base d'interfaçage de l'informatique avec de l'électronique, électrotech-
nique, mécanique, robotique, etc. à vocation industrielle. Elle concerne l'utilisation de l'outil in-
formatique pour la fabrication de produits industriels, du bureau d'études (conception assistée par
ordinateur) à leur production (fabrication assistée par ordinateur, automatique, robotique) en passant
par la logistique, la gestion des stocks, etc.
Automates, robotique,
Mesures de grandeurs physiques,
Systèmes temps-réel,
Systèmes embarqués
La raison d'être d'un système informatique (industriel ou non) est d'acquérir les données (in-
formations) de l'extérieur, faire des calculs et transformations, avant de restituer un résultat aux
périphériques de sortie. Cette information a la forme qui va d'un seul bit (état d'un capteur par
exemple) à la forme d'un ux audio ou vidéo. Dans les sections suivantes on traitera la représenta-
tion et manipulation des données numériques et logiques.
Le système de numération utilisé dans la vie quotidienne est la base 10 ou le système de nombres
décimaux. Dans les applications à base de microprocesseur et de microcontrôleur, on utilise le plus
couramment la base 16, ou hexadécimal. Les systèmes de nombres en base 2 (binaire) ou en base 8
(ou octal) sont également utilisés.
4
CHAPITRE 1. CODAGE DES NOMBRES
M.ABDOUN 5
CHAPITRE 1. CODAGE DES NOMBRES
N = ap · bp + ... + aj · bj + ... + a1 · b1 + a0 · b0
Pour les nombres entiers naturels dans la base décimale : b = 10 on utilise les symboles :
{0, 1, 2, 3, 4, 5, 6, 7, 8 et 9}.
Dans ce cas b = 2, les chires sont {0, 1}. Pour indiquer la base dans laquelle on écrit une valeur
binaire, on utilise l'indice 2 ou b. On peut donc deviner la quantité représentée par :
1100111b = 11001112 = 1 · 26 + 1 · 25 + 0 · 24 + 0 · 23 + 1 · 22 + 1 · 21 + 1 · 20
= 64 + 32 + 0 + 0 + 4 + 2 + 1
= 10310 ou 103d ou 103 tout court, sans indice
L'indice d veut dire : exprimé dans la base décimale, c'est à dire celle qu'on utilise depuis que
l'on sait compter !
Les limites des nombres non signés représentés par n = 8 bits est 0 ≤ n ≤ 255d
Pour la représentation octale, la base est b = 8 les symboles sont {0, 1, 2, 3, 4, 5, 6 et 7}. Quelle
est la quantité représentée par 2738 ?
Dans la représentation hexadécimale on utilise la base b = 16, les chires hexadécimaux sont
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E et F }. Garder en tête A → 1010 , B → 1110 , etc.... La gure 1.3
représente le tableau de correspondance décimal-binaire-hexadécimal.
M.ABDOUN 6
CHAPITRE 1. CODAGE DES NOMBRES
Décimal → Binaire : on utilise la division par 2 successive jusqu'à avoir un quotient < 2. Voir
l'exemple de la gure 1.4a, pour calculer (29)10 = (???)2 .
Décimal → Hexadécimal : on utilise la division par 16 successive jusqu'à avoir un quotient < 16.
Voir l'exemple de la gure 1.4b
Binaire → Hexadécimal : on regroupe par 4 les bits donnés, EN COMMENÇANT PAR LA
DROITE, puis à chaque quartet de bits, on associe le symbole hexadécimal correspondant.
Penser à remplacer les nombres supérieurs à 10 par leurs symboles (exemple 11 → B ). Voir
l'exemple de la gure 1.5
Binaire → Octal : on procédera de la même manière que précédemment en regroupant par 3 les
bits donnés, EN COMMENÇANT PAR LA DROITE, puis à chaque triplet de bits, on
associe le symbole de 0 à 7 correspondant.
M.ABDOUN 7
CHAPITRE 1. CODAGE DES NOMBRES
1.3.1 Représentation
Les nombres entiers relatifs, ou signés, N ∈ Z, sont codés souvent par la méthode : "Complé-
ment à Deux", en utilisant le bit le plus à gauche, comme un bit de signe ; 1 c'est négatif, 0 c'est
positif. Ce bit est appelé le bit de poids le plus fort (en anglais, MSB : Most Signicant Bit). La
gure 1.6 donne l'exemple d'un nombre en complément à deux sur 8 bits.
(10010100)Ca2 = −1 · 27 + 0 · 26 + 0 · 25 + 1 · 24 + 0 · 23 + 1 · 22 + 0 · 21 + 0 · 20
= −108
Remarques :
M.ABDOUN 8
CHAPITRE 1. CODAGE DES NOMBRES
Quand on donne la représentation d'un nombre signé, il faut absolument indiquer sa largeur
en bits.
On peut déduire son signe en consultant son bit MSB
Dans le langage de programmation "C", on indique un entier signé par :
int n; // n: entier relatif
Les limites des nombres non signés représentés par n = 8 bits est −128d ≤ n ≤ 127d
Pour convertir un entier relatif donné (dans la base 10), il faut suivre la démarche (algorithme) :
si le nombre est positif
alors sa conversion se fait de la même façon qu'un entier naturel
sinon
calculer dans la base 2, sa valeur absolue
puis réaliser l'opération complément à deux, au résultat c-à-d :
compléter le résultat par des 0 à gauche, an d'avoir la largeur voulue (8, 16 ou 32
bits)
complémenter chaque bit (0 devient 1 et 1 devient 0)
ajouter un 1 au résultat obtenu.
Exemple : Donner la représentation sur 8 bits, du complément à deux, des nombres 35d et −19d .
1. 35d est un entier positif, donc la division succéssive par deux donne 00100011b
2. −19d est négatif, donc :
je part de sa valeur absolue → 19
je la convertis en binaire naturel → 10011
je complète pour avoir 8 bits → 00010011
je complémente bit par bit → 11101100
puis j'ajoute 1 au résultat → 11101101
M.ABDOUN 9
CHAPITRE 1. CODAGE DES NOMBRES
Toutes les opération "décimales" qu'on a apprises à l'enseignement primaire, peuvent être trans-
posées aux opérations eectuées sur les nombres binaires. Mentalement, on utilise les opérations
chire par chire : par exemple pour l'addition (0 + 0 = 0, 0 + 1 = 1 et 1 + 1 = 10 dans cette dernière
addition et dans notre tête, on dit "J'obtient 0 et je retient 1")
Quelques exemples :
1. Addition : 0110 + 0101 = 1011 (g 1.7). on vérie 6d + 5d = 11d
M.ABDOUN 10
CHAPITRE 1. CODAGE DES NOMBRES
Dans un calculateur, la partie qui réalise les opérations arithmétiques et logiques, est appelé :
Unité Arithmétique et Logique (UAL). Cette UAL contient un jeu de bascules appelés : Drapeaux
ou (Flags en ang.), qui par leurs états 1 ou 0, indiquent les conditions sous lesquelles s'est passé la
dernière opération (y a-t-il eu un report ? un débordement ? ...). On ne s'intéresse qu'à quelques uns
de ces drapeaux :
C (Carry) : par son état à 1, indique que l'opération a produit un report dans l'addition ou
soustraction des bits les plus forts (MSB : Most Signicant Bit). Dans la gure 1.10, c'est
C8 ,
DC (Digit Carry) : par son état à 1, même chose que précédemment mais après l'opération
sur les bits b3 => C4
Z (Zero) : par son état à 1, indique le résultat est nul (tous les bits du résultat son à 0),
OV (OVerow) : son état est = C7 ˆC8 où ˆ est le 'ou exclusif',
N (Negate) : a la même valeur que le MSB du résultat (ici le bit b7 ).
Remarque
Si on prend comme exemple des entiers sur 8bits. Pour verier que le résultat d'une addition
ou d'une soustraction sur des entiers, ne déborde pas (au delà de 8 bits), il faut consulter, après
l'opération :
Le carry C , si ce sont des entiers naturels (non signés), C = 1 =⇒ le résultat est > 255
Le dépassement OV , si ce sont des entiers relatif (signés), OV = 1 =⇒ soit l'addition de
deux entiers positifs a donné un résultat négatif, soit l'addition de deux entiers négatifs a
donné un résultat positif !
M.ABDOUN 11
CHAPITRE 1. CODAGE DES NOMBRES
On peut appliquer ce qu'on connaît sur les fonctions booléennes (le "et", "ou" et "ou-exclusif"
logiques) aux opérations bit à bit (bitwise en anglais) sur des nombres binaires. Pour diérencier les
opérations arithmétiques et logiques on utilise les symboles logiques suivants :
”non” → ˜
”et” → &
”ou” → |
”ou − exclusif ” → ˆ
M.ABDOUN 12
CHAPITRE 1. CODAGE DES NOMBRES
1.5 Exercices
Conversion bin-hex, dec-bin, complément à 2
1. Soit l'expression binaire 10011110, Quelle est sa valeur en décimal :
si ça représente une quantité entière naturelle ?
si ça représente un nombre signé sur 8 bits ?
Donner son écriture en hexadécimal.
2. Convertir (113)d en binaire sur 8 bits et en déduire sa représentation hexadécimale et octale.
3. Même question que la précédente avec (−113)d
4. Pour chacune des opérations arithmétiques suivantes, écrire les opérandes en binaire, donner
leurs valeurs décimales : 1) s'ils représentent des nombres non-signés ou 2) s'ils représentent
des nombres signés en complément à deux. Puis eectuer les opérations binaires en indiquant
aussi l'état des drapeaux (ags) :
(a) 00100100b + 01011000b
(b) 11100101b + 00101100b
(c) 00100100b − 10101000b
(d) 11100011b − 01100111b
5. Eectuer les opérations logiques sur des nombres binaires, en donnant l'état du drapeau Z :
(a) 0 0 0 0 0 1 0 0 & b7 b6 b5 b4 b3 b2 b1 b0 = ? avec & est le "et logique". Le nombre
0 0 0 0 0 1 0 0b est appelé : le masque. Conclure si le résultat est nul (c-à-d Z=1) de la
valeur du bit b2 ,
(b) 0 0 0 1 0 1 1 0 & b7 b6 b5 b4 b3 b2 b1 b0 . Avec cette opération et en consultant le drapeau
Z s'il est à 1, on a réalisé quelle fonction logique des variables f (b7 , b6 , b5 , b4 , b3 , b2 , b1 , b0 ) ?
6. Donner le résultat binaires des opérations suivantes, sachant que A représente un octet dont la
valeur initiale est b7 b6 b5 b4 b3 b2 b1 b0 :
(a) A ← (A) | 0 0 0 0 0 1 0 0, qu'on peut lire : A reçoit le contenu de A "ou bit à bit" avec
00000100
(b) A ← (A) & 1 1 1 1 1 0 1 1, qu'on peut lire : A reçoit le contenu de A "et bit à bit" avec
11111011
(c) A ← (A) ˆ 0 0 0 0 0 1 0 0, qu'on peut lire : A reçoit le contenu de A "ou exclusif bit à
bit" avec 0 0 0 0 0 1 0 0
M.ABDOUN 13
Chapitre 2
Introduction du PIC18FXX2
14
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
de traitement et une interaction agile et réactive avec des composants numériques ou analogiques.
Le marché des microcontrôleurs est formé par plusieurs fabricants (Microchip Technology Inc.,
STMicroelectronics, Atmel, ... ) et chacun propose plusieurs types de microcontrôleur. Ici on s'inté-
ressera aux microcontrôleurs PICs du fabricant Microchip. Ceux-ci sont référencés sous la forme :
PIC suivi de deux chires exemple : PIC (10, 12, 16, 18, 24 ,32) ou dsPIC (30, 33). Les PICs se
répartissent en plusieurs familles, par ordre de puissance croissante : PIC10 et PIC12, les PIC16,
M.ABDOUN 15
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
Figure 2.3
les PIC18, les PIC24F/PIC24H/PIC24E etc.... Pour plus d'information, consulter : Familles de
PIC-wikipedia
Dans notre cours, on s'intéressera à la famille PIC18, car cette famille a un jeu d'instruction plus
complet puisqu'il comprend quelque 75 instructions machines et donc lui permet de faire executer
du code en langage C compilé de manière plus ecace. On a choisi d'exploiter les pics PIC18fXX2
(chaque X représente un chire, ex PIC18F452). Mais tout ce qu'on peut apprendre sur cette fa-
mille est exploitable pour étudier d'autres microcontrôleurs. Les PICs sont basés sur l'Architecture
Harvard, voir gure 2.4, où le bus qui véhicule le code à executer depuis la mémoire programme
(Flash : Program memory) vers le CPU, est diérent de celui qui véhicule la donnée à utiliser depuis
la mémoire de données (RAM : Data memory). Cette architecture permet de paralléliser la recherche
du code de la prochaine instruction et l'execution de l'instruction actuelle, et donc plus rapide que
celle de Von-Neumann.
Figure 2.4
M.ABDOUN 16
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
2.3.1 Introduction
Les microcontrôleurs PIC18F fournissent une mémoire de programme ash (d'où le 'F' dans
la désignation) dans des tailles, de mémoire programme, de 8 à 128 Ko (Ko = KiloOctets, avec
1Ko = 210 = 1024 octets) et mémoire de données (RAM) de 256 à 4 Ko, fonctionnant dans une
limite d'alimentation entre 2,0 et 5,0 volts, à des vitesses allant jusqu'à 40 MHz.
Le tableau (g. 2.5) présente les éléments de la famille PIC18FXX2 et ses caractéristiques :
Figure 2.5
2.3.2 Brochage
Le brochage du PIC18F452, par exemple, est donné dans la gure 2.6. Chaque broche est indiquée
par sa position (1 à 40), par le sens des signaux (entrée, sortie ou bidirectionnelles) et par ses
M.ABDOUN 17
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
possibles fonctions, par exemple la broche 3 : RA1/AN 1 indique que c'est une broche qui pourrait
être congurée comme entrée/sortie tout-ou-rien 'RA1' ou comme entrée analogique 'AN 1'. On
remarque qu'il y a beaucoup de fonctions (T 0CKI , CCP 2, ...) dont le traitement de quelques unes
se fera le long des chapitres suivants.
la RAM, qui est la mémoire des données. C'est là où on loge les variables du programme. Le
contenu de cette mémoire est eacé qu'on coupe l'alimentation le VDD .
M.ABDOUN 18
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
La ROM, de type mémoire Flash, donc programmable et eaçable électriquement. C'est elle
qui contient le programme sous forme d'un code sur 16 bits. Le programme qui y est écrit
persiste après coupure de l'alimentation.
l'Unité Arithmétique et Logique l'UAL (ALU en anglais), c'est le c÷ur des des calculs Arith-
M.ABDOUN 19
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
Le schéma bloc est assez compliqué à étudier en une seule séance. Il est utile à com-
á prendre, mais il l'est encore plus pour celui qui utilisera l'assembleur comme langage
de programmation. Nous, on va plutôt utiliser le langage 'C'. Mais on reviendra à ce
schéma quand c'est nécessaire.
Les microcontrôleurs PIC18F452 ont un ensemble de registres de conguration (g. 2.8). Ils sont
écrits lors de la programmation de la mémoire ash du MCU par le programmateur. On ne traitera
pas tous ces registres, par manque de temps, mais il faut savoir que ceux là, ont des valeurs par
défaut (non programmées) qui satisfont la plupart des projets et on ne programmera que quelques
congurations particulières. Certains des registres de conguration les plus importants sont décrits
en détail dans cette section.
Comme exemple, pour le registre de conguration CON F IG1H (voir g. 2.9)
OSCSEN (Clock source switching enable) : Les PIC18FXX2 incluent une fonction qui per-
met de passer de l'oscillateur principal haute fréquence vers une autre source d'horloge basse
fréquence, an d'économiser la consommation électrique du MCU (car sa consommation est
croissante en fonction de la fréquence de l'horloge). Pour les PIC18FXX2, cette autre source
d'horloge est l'oscillateur du Timer1 (entre les broches T 1OSO et T 1OSI ). Si ce bit, qui
est le bit b5 du registre CON F IG1H , est dans l'état actif c-à-d à 0, cette commutation est
possible. Sinon, (si OSCSEN = 1) on n'utilise que l'horloge principale. D'après le tableau
(g. 2.8), par défaut (si on ne le programme pas) ce bit est inactif.
F OSC2 : F OSC0 : Ces trois bits permettent la selection l'un des modes d'horloge (g.
2.10) :
111 : On utilise un circuit RC externe et en plus la broche RA6 peut être utilisée comme
entrée-sortie logique. Le choix R = 3.9kΩ et C = 30pF , par exemple, donne une fréquence
de 2M Hz .
011 : Oscillateur RC avec sortie FOSC /4 sur la broche OSC2
M.ABDOUN 20
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
Un autre exemple est le registre de conguration CON F IG2H , utilisé pour contrôler le timer
du chien de garde (Watch Dog Timer ou WDT).
M.ABDOUN 21
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
La plupart des microcontrôleurs ont au moins une fonction de surveillance. Le chien de garde
est essentiellement une minuterie qui est actualisée par le programme utilisateur. Si le programme ne
parvient pas à actualiser le chien de garde au bout d'un certain temps, un RESET (réinitialisation)
est déclenché. Le minuteur de surveillance est utilisé pour détecter un problème système, tel que
le programme se trouvant dans une boucle sans n. Cette fonction de sécurité empêche le micro-
contrôleur d'exécuter du code erroné et indésirable. Les dispositifs de surveillance sont couramment
utilisés dans les systèmes en temps réel où la n réussie d'une ou plusieurs activités doit être vériée
régulièrement.
Dans les membres de la famille des microcontrôleurs de la série PIC18F, la minuterie de sur-
veillance (WDT) est pilotée par un oscillateur RC interne au MCU à fonctionnement indépendant
et ne nécessite aucun composant externe. Il a une période de ∼ 18ms. Le fonctionnement du WDT
est donné sur la gure 2.11.
M.ABDOUN 22
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
Sur le microcontrôleur PIC18F452, un post-diviseur 8 bits est utilisé pour multiplier la période
de temporisation de base de 1 à 128 en puissances de 2. Ce post-diviseur est contrôlé à partir du
registre de conguration CON F IG2H (g. 2.12). Par défault, le bit W DT EN est à 1 (voir g. 2.8),
donc le WDT est actif. Si on veut l'inhiber, il faut programmer W DT EN à 0.
Le délai d'expiration WDT de base typique est de 18 ms pour une valeur de post-diviseur de
(1 :1), de 36ms si post-diviseur de (1 :2), ....
M.ABDOUN 23
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
2.4 Exercices
Exercice 1
On veut choisir un PIC de la famille PIC18FXX2 à utiliser dans une application qui nécessite :
Mémoire programme (Flash) : 20134 octets,
Mémoire de données (RAM) : 1024 octets,
Nombre d'entrées analogiques (fonction AN) : 2 entrées,
Nombre d'entrées logiques (tout ou rien) : 11 entrées et
Nombre de Sorties logiques : 8 sorties.
1. Choisir un PIC parmi 18F242, 18F252, 18F442 et 18F452, ayant le plus petit nombre de broches,
et qui convient pour cette application. Consulter le datasheet des PIC18F452, section "1.0
Device overview".
1. Calculer la résistance R à utiliser, sachant que la période d'oscillation de l'horloge TOSC est
proportionnelle au produit R × C .
2. Donner le mot à programmer dans le registre de conguration CON F IG1H , puis la pragma
en langage C associée.
Un des moyens utilisés pour detecter le mal fonctionnement d'un système à base de microcon-
trôleurs, est d'utiliser le chien de garde (Watchdog). Soit un système à base de PIC18F452.
M.ABDOUN 24
CHAPITRE 2. INTRODUCTION DU PIC18FXX2
M.ABDOUN 25
Chapitre 3
3.1 Introduction
Un microcontrôleur possède des bus internes de données et d'adresses. D'une certaine manière,
ce sont comme des autoroutes, transportant de grandes quantités de trac dans les deux sens vers une
variété de destinations diérentes (RAM, FLASH, TIMERS, ...). Le microcontrôleur doit être doté
d'un moyen de permettre à ce ux de données de se connecter au monde extérieur, de sorte qu'il puisse
lire des valeurs numériques externes ou produire d'autres valeurs aprés calcul, vers l'extérieur. Ces
jonctions sont des broches physiques, et sont appelés des Ports d'Entrées-sorties. Ils peuvent être
parallèles ou séries. Dans ce chapitre, on traitera les entrées-sorties parallèles logiques (tout-ou-rien).
On interface, par exemple, au microcontrôleur des capteurs n de course, des claviers, des diodes
électroluminescentes (DEL), des acheurs....
Ces PORTS se connectent en interne à des registres à l'intérieur du PIC. Ces registres sont
simplement une collection de cellules (bascules D) individuelles que nous appelons des bits. Dans le
18fxx2, on peut grouper ensemble 8 cellules ou bits pour former un registre. En eet, le 18fxx2 est
un micro 8 bits, ses bits sont numérotés de droite à gauche sous forme de bit 7, bit 6, bit 5, bit 4,
bit 3, bit 2, bit 1 et bit 0 (voir gure 3.1). Une sortie tout ou rien indique que le micro-contrôleur
impose le potentiel de la broche à 0V pour un 0 logique et à 5V pour un 1 logique.
26
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
Avec :
PORTA → 7 bits : RA0 à RA6,
PORTB, PORTC et PORTD → 8 bits : RB0 à RB7, RC0 à RC7 et RD0 à RD7,
PORTE → 3 bits : RE0 à RE2.
Pour congurer les fonctionnalités de ses périphériques, un microcontrôleur contient un en-
sembles de registres appelés 'Special function Registers' (SFR). Chaque registre ayant une adresse
donnée. Parmi ces registres, il y en a ceux qui permettent de congurer individuellement en entrée
ou bien en sortie, chacune des broches des ports du PIC : TRISA pour le port A, TRISB pour le
port B, ... C'est vous comme programmeur, qui allez indiquer au PIC, au moyen d'instructions dans
votre programme, quelle est la direction que vous voulez pour chaque bit d'un port.
Un 1 écrit dans un bit TRISx (x prend la lettre correspondant au port en question), indique que
la broche correspondante est en Entrée, un 0 indique que la broche est en Sortie.
Quand on dit : en entrée ou en sortie, c'est par rapport au microcontrôleur. Par défaut,
á à l'alimentation du PIC, tous les bits des TRISx sont à 1, donc toutes les broches sont
par défaut vues comme des entrées par le microcontrôleur.
Pour indiquer, par exemple, que la broche RB2 (la broche b2 du PORTB) est programmée en
sortie, il faut écrire la valeur 0 dans le bit 2 du TRISB.
Bien faire la diérence entre le registre PORTB (lui aussi appartenant au SFR) et le
* registre de conguration de direction TRISB. Le premier est utilisé pour pour lire l'état
d'une ou des broches associées au port B (0 → 0volt ou 1 → 5volts), le deuxième c'est
pour congurer telle ou telle broche du port B en entrée ou bien en sortie.
M.ABDOUN 27
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
3.3.1 Exemple
Sur une carte à base de PIC18F452, on connecte : trois boutons poussoirs et une LED (diode
electro-luminescente). Le bouton poussoir BP0 est connecté sur la broche 3 du port B, BP1 sur la
broche 4 du port B et BP2 sur la broche 5 du port B. La LED est connectée sur la broche 6 du port
A. On veut que la LED s'allume, lorsque les trois boutons sont actifs (un "et logique"). Elle restera
éteinte sinon.
Initialisation
Les boutons poussoirs sont connectés à des entrées du micro-contrôleur. Il faut donc forcer à 1
les bits 3, 4 et 5 du registre TRISB. Deux solutions :
Congurer bit par bit : Un bit individuel de TRISB (par exemple) est accessible en spéciant
"TRISB", suivi du mot "bits", puis d'un symbole de point et du nom du bit correspondant.
Dans notre exemple :
TRISB3 = 1; // ou bien pour accéder à un bit dans un registre, on peut aussi
// utiliser TRISBbits.TRISB3 = 1, on préfère la première écriture
TRISB4 = 1;
M.ABDOUN 28
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
TRISB5 = 1;
ou bien par forçage à 1 des bits du registre TRISB :
TRISB |= 0x38; // | est le 'ou logique', 0x38 = 0b00111000
// |= veut dire TRISB <- TRISB | 0X38
Figure 3.2
La LED est connectée à une sortie du microcontrôleur. Il faut donc forcer le bit 6 de TRISA à
0:
TRISA6 = 0;
// ou bien
TRISA &= 0xBF; // & est le 'et logique', 0xBF = 0b10111111
Pour éditer et compiler nos programmes, j'utilierai l'éditeur integré 'MPLAB X', que
á vous pouvez télécharger et installer gratuitement, et le compilateur "XC8" aussi gratuit.
Pour utiliser les étiquettes TRISA, TRISB, PORTA, ..., il faut inclure dans le chier
"C" une entête : '# include <xc.h>'.
Pour écrire un état initial 0 dans la sortie LED (qui est sur PORTA6), on doit écrire 0 dans le
bit associé : LA6, dans un registre : LATA. Ce registre est utilisé pour inscrire un 0 → 0volts ou un
1 → 5volts sur une broche du port A congurée en sortie. Dans notre exemple on écrit :
On va lire l'état des boutons et le mettre dans une variable "btns" de type 'unsigned int' :
M.ABDOUN 29
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
En résumé à chaque port du PIC, on associe trois registres. On prendra comme exemple
ÿ le port B ou le bit 3 du port B :
1. TRISB ou TRISB3 : pour congurer la direction du port ou du bit 3 du port B,
2. LATB ou LB3 : pour écrire dans le port B ou dans la broche RB3 déjà conguré
en sortie,
3. PORTB ou RB3 : pour lire l'état physique des broches du port B ou l'état de la
broche RB3 conguré en entrée.
Organigramme :
L'organigramme (voir gure 3.3) permet d'élaborer le programme relatif à l'exemple. La LED
s'allumera si les trois boutons sont à 5volts.
Le code :
/*
* File: exemple1.c
* Author: abdoun
*
* Created on May 15, 2021, 3:43 PM
*/
#include <xc.h>
M.ABDOUN 30
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
void init_ports(void) {
TRISB |= 0b00111000; // configurer les bits 3, 4 et 5 du port B en entrée
TRISA6 = 0; // configurer le bit 6 du port A en sortie
void main(void) {
unsigned int btns; // variable locale
init_ports();
return;
}
Il y a plusieurs méthodes pour implanter ces fonctions. Ici on expliquera une méthode dite
orientée "données" utilisant des mots de masques et des mots de valeurs.
On sait qu'on peut toujours ramener n'importe quelle fonction logique à la forme d'une somme
M.ABDOUN 31
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
Figure 3.4
de produits. Supposons par exemple (voir g. 3.4), que f1 (a, b, c, d) s'exprime par :
Le calcul de la valeur de cette fonction se ramène au calcul du produit P1 . S'il est vrai, on s'arète
M.ABDOUN 32
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
car on est sur que f1 est "vrai" (1 + φ = 1). Sinon on continue à évaluer P2 , puis le suivant s'il y
en a d'autres jusqu'à avoir un produit "vrai" ou si on atteint la n, alors la valeur de la fonction est
"faux".
Le problème revient maintenant à "coder" un produit pour que son évaluation soit rapide : Les
variables d'entrée sont généralement rangées dans un "mot" (un octet par exemple g. 3.6).
Prenons l'exemple du produit P2 = a.b.d, il ne contient que les variables a, b et d, d'où le mot
de masque binaire M2 =0b00001011 = 0x0B. Le mot de valeur permet de préciser l'état desiré de
chacune des variables (1 : si direct, 0 : si complémenté). Continuons toujours pour le produit P2 ,
puisque a et b interviennent "complémentés", leurs positions seront à 0. Pour d, il intervient "direct",
donc sa position est à 1 dans le mot de valeur. D'où le mot de valeur associé à P2 : V2 =0b00001000
= 0x08.
M.ABDOUN 33
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
(E.M2 ) ⊕ V2 = 00000000
ou bien avec les opérateur du langage C
(E & M2 )ˆV2 = 00000000
Finalement, pour représenter la fonction f1 complètement, il faut donner deux mots de masque
et deux mots de valeur, et les ranger sous forme d'un tableau [M1 , V1 , M2 , V2 , 0]. Pour notre exemple :
La n du tableau est indiquée par l'utilisation d'un mot de masque 0x00. Notre pro-
á gramme utilisera ça pour terminer le traitement d'une fonction et conclure de sa valeur
"faux".
3.5 Exercices
La gure 3.7 représente une partie de l'interfaçage à un PIC18F242 d'un bouton poussoir départ
cycle : m, de deux ns de course a0 et a1 associés à un vérin A et de deux commandes de bobines
A− et A+ d'un distributeur électro-pneumatique.
M.ABDOUN 34
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
On se propose d'utiliser la méthode orientée données utilisant les mots de masque et les mot de
valeur, pour implanter les fonctions logiques de la gure 3.8. Les entrées sont rangées dans l'ordre
du bit de poids fort au bit de poids faible : e4 , e3 , e2 , e1 , et e0 . Les sorties rangées dans l'ordre
s3 , s2 , s1 , et s0 .
1. Exprimer chacune des fonctions logiques de sortie s3 ...s0 sous forme de sommes de produits.
2. Pour chaque sortie, donner le tableau mots de masque, mots de valeur se terminant par un
0x00. En utilisant le langage "C", on peut dénir un tableau (par exemple de la fonction s0 )
par :
M.ABDOUN 35
CHAPITRE 3. ENTRÉES SORTIES LOGIQUES
unsigned int i = 0, M, V;
L'appel de cette fonction se fera par exemple comme suit :
M.ABDOUN 36
Chapitre 4
Les interruptions
4.1 Introduction
Nous avons vu au chapitre precédent (voir gure 3.5), qu'on a utilisé une boucle de consul-
tation, on consulte périodiquement les entrées (polling loop) et qu'entre le point de lecture A de la
gure et le point de sortie B , se passe un temps τ (xe ou variable). Le temps de réponse du système
tr est le temps écoulé entre la lecture des entrées et l'aectation des sorties. En supposant que la
lecture des entrées et l'aectation des sorties consomme un temps négligeable devant le temps des
traitements qui est ∼ τ , on a τ < tr < 2.τ (pourquoi ?).
Parfois on veut que le système réponde plus rapidement à des événements intérieurs ou extérieurs
plus urgents. Pour celà, au lieu de laisser le programme consulter les états des entrées périodiquement,
on utilise les interruptions qui sont des événements qui vont attirer l'attention immédiate du CPU.
On utilisé ce mécanisme dans les applications critiques en termes de temps (exemple gestion de
l'airbag d'une voiture).
Une Interruption est un événement qui oblige le CPU à arrêter l'exécution normale du pro-
gramme, puis à exécuter un code de programme lié à l'événement à l'origine de l'interruption. Les
interruptions peuvent être générées en interne (par un événement à l'intérieur de la puce) ou en
externe (par un événement externe). Un exemple d'interruption interne est un débordement d'un
Timer ou la n d'une conversion Analogique/Numérique. Un exemple d'interruption externe est un
changement d'état de broche d'une E/S.
37
CHAPITRE 4. LES INTERRUPTIONS
Les interruptions de la famille PIC18F peuvent être divisées en deux groupes : haute priorité et
basse priorité. Les événements qui nécessitent plus d'attention peuvent être placées dans le groupe
de priorité le plus élevé. Une interruption de priorité élevée peut arrêter une interruption de priorité
basse en cours et accéder au CPU. Cependant, les interruptions de haute priorité ne peuvent pas être
arrêtées par des interruptions de faible priorité.
Mais si l'application n'a pas besoin de dénir des priorités pour les interruptions (toutes ont la
même priorité), le programmeur peut choisir de désactiver ce schéma de priorité an que toutes les
interruptions aient le même niveau de priorité, en laissant IPEN à 0, qui est sa valeur par défaut.
M.ABDOUN 38
CHAPITRE 4. LES INTERRUPTIONS
Chaque source d'interruption (sauf INT0) dispose de trois bits pour contrôler son fonctionne-
ment. Ces bits sont :
Un bit de ag pour indiquer si une interruption s'est produite. Ce bit a un nom se terminant
par. . .IF. Ces bits indicateurs d'interruption sont mis à 1 par la circuiterie de l'interruption
et doivent être mis à 0 par logiciel au début du sous-programme d'interruption pour réarmer
et préparer l'arrivée des interruptions suivantes.
Un bit de validation d'interruption pour activer ou désactiver la source d'interruption. Ce
bit a le nom se terminant par. . .IE
Un bit de priorité pour sélectionner une priorité élevée ou faible. Ce bit a un nom se terminant
par. . .IP. Ce bit n'est utile que si l'on a choisi d'activer les priorités : IPEN à 1.
Par exemple : L'interruption provoquée par le débordement du Timer0 (qui sera traité ultérieu-
rement), mettra en jeu les bits : TMR0IF, TMR0IE et TMR0IP.
Pour qu'une interruption soit acceptée par le CPU, les conditions suivantes doivent être remplies :
Le bit de validation d'interruption de la source d'interruption doit être activé. Par exemple,
si la source d'interruption était la broche d'interruption externe INT0, alors le bit INT0IE
du registre INTCON devrait être mis à 1 (voir gure 4.2). En C :
INT0IE = 1;
L'indicateur d'interruption de la source d'interruption doit être eacé. Par exemple, si la
source d'interruption était la broche d'interruption externe INT0, alors le bit INT0IF du
registre INTCON devrait être remis à 0. En C :
INT0IF = 0;
Le bit d'activation/désactivation d'interruption de périphérique PEIE d'INTCON devrait
être mis à 1 si la source d'interruption est un périphérique (et pas une interruption externe).
En C :
PEIE = 1;
Le bit d'activation/désactivation d'interruption globale GIE d'INTCON doit être mis à 1.
En C :
GIE = 1;
Avec une source d'interruption externe, nous devons normalement dénir si l'interruption doit
se produire lors de la transition front montant ou front descendant de la source d'interruption. Avec
M.ABDOUN 39
CHAPITRE 4. LES INTERRUPTIONS
les interruptions INT0, par exemple, cela se fait en mettant/eaçant le bit INTEDG0 de enregistrez
INTCON2. On pourrait dire la même chose pour INT1 (→ INTEDG1) et INT2 (→ INTEDG2) dans
le même registre INTCON2.
4.3.4 Applications
Il faut savoir que nous, comme programmeurs, quand on veut utiliser les interruptions, il faut
penser à deux choses :
1. une suite d'instructions en "C" pour les congurer. Souvent dans une fonction ayant la forme :
M.ABDOUN 40
CHAPITRE 4. LES INTERRUPTIONS
M.ABDOUN 41
CHAPITRE 4. LES INTERRUPTIONS
Exemple 1 :
Congurez INT1 comme une entrée d'interruption déclenchée par front descendant de faible
priorité, puis donnez un sous programme d'interruption, appelé int1_ISR qui permet d'incrémenter,
à chaque front descendant, une variable entière : compteur, initialement à 0.
Réponse :
Les bits suivants doivent être congurés avant que les interruptions déclenchées par front des-
cendant INT1 puissent être acceptées par le CPU en mode basse priorité :
M.ABDOUN 42
CHAPITRE 4. LES INTERRUPTIONS
#include <xc.h>
void init_int1() {
// configuration de l'interruption INT1, front descendant et faible priorité
IPEN = 1; // Puisqu'on va utiliser le schéma de priorité
TRISB1 = 1; // La broche RB1/INT1, en entrée
INTEDG1 = 0; // Réglez les interruptions INT1 pour qu'elles agissent sur front
// descendant
INT1IE = 1; // Validez l'interruption INT1
INT1IP = 0; // Indiquer que sa priorité est faible
INT1IF = 0; // Effacer l'indicateur ou flag INT1
GIEL = 1; // Activez les interruptions de faible priorité
GIEH = 1; // Activez globalement toutes les interruptions
}
void main(void)
{
M.ABDOUN 43
CHAPITRE 4. LES INTERRUPTIONS
init_int1();
// Boucle infinie
while (1)
PORTC = compteur;
}
Exemple 2 :
Congurez INT1 comme une entrée d'interruption déclenchée sur front montant ayant une prio-
rité élevée, puis donnez un sous programme d'interruption, appelé int1_ISR qui permet d'incré-
menter, à chaque front montant, une variable entière : compteur, initialement à 0.
Réponse :
Les bits suivants doivent être dénis avant que les alarmes déclenchées par front montant INT1
puissent être acceptées par le CPU en mode haute priorité :
1. Activez le schéma de priorité. Dénir IPEN = 1
2. Faites de INT1 une broche d'entrée. Dénir TRISB1 = 1
3. Réglez les interruptions INT1 pour le front montant. Dénir INTEDG1 = 1
4. Validez les interruptions INT1. Dénir INT1IE = 1
5. Activez la priorité élevée. Dénir INT1IP = 1
6. Eacer l'indicateur ou ag de INT1. Dénir INT1IF = 0
7. Activez globalement toutes les interruptions. Dénir GIEH = 1.
Le code source "C" est le suivant :
M.ABDOUN 44
CHAPITRE 4. LES INTERRUPTIONS
#include <xc.h>
void init_int1() {
// configuration de l'interruption INT1, front montant et haute priorité
IPEN = 1; // Puisqu'on va utiliser le schéma de priorité
TRISB1 = 1; // La broche RB1/INT1, en entrée
INTEDG1 = 1; // Réglez les interruptions INT1 pour qu'elles agissent sur front
// montant
INT1IE = 1; // Validez l'interruption INT1
INT1IP = 1; // Indiquer que sa priorité est haute
INT1IF = 0; // Effacer l'indicateur ou flag INT1
GIEH = 1; // Activez globalement toutes les interruptions
}
void main(void)
{
init_int1();
// Boucle infinie
while (1)
;
}
M.ABDOUN 45
CHAPITRE 4. LES INTERRUPTIONS
L'application qu'on va étudier, est une partie d'un asservissement de position d'une table de
machine-outil entraînée par un moto-réducteur à courant continu à travers un système vis-écrou. Un
capteur angulaire est couplé à l'arbre de la vis. L'objectif est d'interfacer ce capteur : Un codeur
incrémental, à une carte à base du PIC18F452.
Le principe de base de fonctionnement d'un codeur incrémental est illustré par la gure 4.4. Il
utilise un disque régulièrement percé de fentes le long d'un secteur et dont le centre est solidaire à
l'arbre de rotation. Un système d'émetteur-récepteur de lumière est placé de part et d'autre de la
roue (constitué par exemple d'une LED et d'un capteur infrarouge). Lorsque la lumière émise par
la LED franchie une des fentes du disque lors de sa rotation, le récepteur génère un signal logique
1. Lorsque la lumière heurte le disque plein, le récepteur émet un signal logique 0. Ainsi lorsque la
roue tourne en continu, le récepteur génère un train d'impulsion soit un signal carré. Ce signal nous
renseigne sur le nombre de passages de fentes ayant délé devant la cellule photo-électrique mais pas
sur le sens de rotation. Pour capter le sens de rotation il faut utiliser deux secteurs de fentes ou deux
capteurs photo-électriques décalés en quadrature, et donc fournissent deux signaux rectangulaire en
quadrature de phase (déphasés de 90deg) souvent nommés A et B (voir g. 4.5).
Le disque comporte au maximum 3 pistes. Une ou deux pistes extérieures divisées en (n) in-
tervalles d'angles égaux alternativement opaques et transparents. Et une troisième qui indique la
position le Top Zéro.
Pour un tour complet du codeur, le faisceau lumineux est interrompu (n) fois et délivre (n)
périodes de signaux carrés (A et B) en quadrature. Le déphasage de 90° électrique des signaux A et
B permet de déterminer le sens de rotation :
Si on tourne dans le sens 1, à chaque front montant du signal A, le signal B est dans l'état
zéro, on utilisera ce fait pour incrémenter un compteur (une variable dans le microcontrôleur).
Si on tourne dans le sens 2, à chaque front montant du signal A, le signal B est dans l'état
un, on utilisera ce fait pour décrémenter le compteur.
On parle de la Résolution du capteur comme le nombre N de points par tour, que peut
détecter le capteur.
M.ABDOUN 46
CHAPITRE 4. LES INTERRUPTIONS
M.ABDOUN 47
CHAPITRE 4. LES INTERRUPTIONS
Questions :
Sur la carte microcontrôleur (voir g. 4.6), on connecte le signal A du codeur à la broche
RB1/INT1 du PIC, et le signal B à sa broche RB2/INT2. L'objectif est de concevoir un programme
qui à partir des signaux A et B, met à jour une variable compteur de type int (initialement à 0)
qui est une image de la position angulaire de l'arbre du motoréducteur. Pour celà, on va utiliser les
interruptions pour acquérir ces signaux, car se sont des signaux assez rapides (et on a vu que les
interruptions sont utilisées lorsqu'il y a des signaux urgents à gérer).
1. En utilisant un codeur incrémental de n = 360 impulsions par tour, et en supposant que l'arbre
tourne à une vitesse de Narbre = 20tr/mn, déterminer la période TA (en secondes) du signal A.
2. Donner les instructions pour congurer l'interruption
Réponses :
1. En une minute, nous aurons Narbre × n impulsions sur A. Donc
60
TA =
Narbre × n
60
=
22 × 360
= 7, 6ms
Il faut donc vérier que notre solution permet bien de répondre rapidement (moins que 7, 6ms)
aux demandes d'interruption.
M.ABDOUN 48
CHAPITRE 4. LES INTERRUPTIONS
void init_PORTB() {
IPEN = 0; // pas besoin des priorités d'interruptions
M.ABDOUN 49
CHAPITRE 4. LES INTERRUPTIONS
void init_PORTC(void){
TRISC = 0x00; // on utilse le port C en sortie
LATC = 0x00; // l'initialiser à 00000000
}
Aecter compteur au PORTC dans main :
void main(void) {
init_PORTB();
init_PORTC();
while (1){
LATC = compteur; // faire sortir la valeur du compteur sur le PORTC
}
return;
}
4.4 Exercice
On reprend l'exemple 3 (voir section 4.3.4), mais cette fois-ci on veut améliorer la résolution de
l'acquisition en la multipliant par 2. On utilisera alors les changement fronts montants et descendants
du signal A comme source d'interruption.
Les broches du port RB4 à RB7 d'un PIC18Fxx2 (voir 8.8 PORTB Interrupt-on-Change)
peuvent être utilisées comme entrées d'interruption réagissant à tout changement de leur état lo-
gique, et qui provoquerait la mise à 1 du ag RBIF et ainsi une demande d'interruption au CPU.
Les bits de validation d'interruption et d'indicateur RBIE et RBIF sont dans le registre INTCON.
M.ABDOUN 50
CHAPITRE 4. LES INTERRUPTIONS
L'interruption de changement des broches RB4 :7 est gérée par les bits RBIE et RBIF,
W qui gèrent les changements des quatre broches en même temps. Il faut donc encore
un moyen pour detecter, dans notre sous programme d'interruption, laquelle de ces
broches à changé d'état. Por celà on va utiliser une variables : a_p de type __bit,
pour mémoriser la précédente valeur de la broche RB4 (le signal A) et la comparer à
son état actuel (par un ou exclusif).
int compteur = 0;
__bit a_p = 0;
M.ABDOUN 51
Chapitre 5
Les Timers
5.1 Introduction
Comme la plupart des microcontrôleurs, les PICs possèdent des périphériques appelés : Timers
qui permet de gérer la dimension temps. Les temporisateurs matériels sont utilisés pour les opérations
de temporisation et de comptage, permettant au processeur de poursuivre un autre processus pendant
que le processus de temporisation s'exécute. Le fonctionnement de base du temporisateur ; une entrée
d'horloge pilote un registre de comptage pour mesurer le temps ou compter des événements externes.
Sa fonctionnalité peut être étendue en utilisant des registres supplémentaires pour stocker les valeurs
de la minuterie, créant ainsi un module CCP. CCP signie capture/comparer/PWM.
52
CHAPITRE 5. LES TIMERS
Mode Compteur, et dans ce cas le registre s'incrémente à chaque arrivée d'un front de
l'événement externe conduit à l'entrée horloge H.
Dès que le registre compteur déborde (passe de 0xFF à 0, cas de 8-bits, ou de 0xFFFF à 0, cas de
16-bits), un drapeau (ag) est mis à 1, ce qui pourrait déclencher une interruption du CPU.
atteint 0xFF (pour un 8-bits par exemple). Ce qui provoque la mise à 1 du Flag puis l'entrée R de
la bascule, l'état de la Broche de sortie tombera alors à 0.
(256 × τ − 100 × τ )
λ=
256 × τ
156 × τ
= ∼ 0, 61
256 × τ
Et dans le cas général, si RC est la valeur chargée dans le Registre comparateur et Nmax la
valeur maxi du Registre Timer/Comparateur :
RC
λ=1− .
Nmaxi
On a alors la largeur de l'impulsion de la broche de sortie, qui varie selon la valeur de RC . D'où
l'appellation PWM (Pulse Width Modulation) ou Modulation à largeur d'impulsion.
La valeur moyenne du signal de sortie est Vmoy = λ×Vcc . On obtient donc une conversion
á d'une valeur numérique : RC en une valeur continue analogique : Vmoy . C'est une façon
d'économiser l'utilisation d'un composant convertisseur Numérique/Analogique externe
au MPU.
M.ABDOUN 54
CHAPITRE 5. LES TIMERS
M.ABDOUN 55
CHAPITRE 5. LES TIMERS
5.5.1 Timer0
Le Timer0 peut fonctionner en mode 8-bits ou 16-bits. Il a les caractéristiques de base suivantes :
Fonctionnement 8-bits ou 16-bits
Pré-diviseur programmable 8-bits
Source d'horloge externe ou interne
Génération d'interruption sur débordement
La gure 5.5, donne le principe de fonctionnement du Timer0 en mode 8-bits. L'interruption
TMR0 est générée lorsque le registre TMR0 déborde de 0xFF à 0x00 en mode 8 bits, ou de 0xFFFF
à 0x0000 en mode 16 bits. Ce débordement positionne le bit TMR0IF.
Le registre de contrôle du temporisateur 0 est T0CON, illustré à la gure 5.7. Les deux premiers
bits sont utilisés pour sélectionner le mode de fonctionnement 8-bits ou 16-bits et pour démar-
rer/stopper le temporisateur.
Pour choisir le mode 8-bits, il faut mettre le bit T08BIT à 1. Et dans ce cas seule la partie
8-bits TMR0L est utilisée pour l'initialiser ou pour le lire le timer. Dans le cas 16-bits ( T08BIT
à 0), on aura le même fonctionnement que précédemment, sauf qu'on utilise tout le registre 16-bits
TMR0.
Pour y accéder au registre 16-bits, on est obligé de le faire en deux temps et dans
W l'ordre :
Lecture : D'abord lire TMR0L puis lire TMR0H
Écriture : l'inverse ; d'abord écrire dans TMR0H puis écrire dans TMR0L.
M.ABDOUN 56
CHAPITRE 5. LES TIMERS
Dans une carte à base de PIC18F452, fonctionnant au rythme d'une horloge FOSC = 4M Hz ,
on veut utiliser le Timer0 sur 8-bits, pour provoquer une interruption périodique au bout de chaque
T secondes, après qu'on l'aie démarré (c-à-d à l'écriture de 1 dans le bit TMR0ON). Pour celà, on
M.ABDOUN 57
CHAPITRE 5. LES TIMERS
doit sélectionner l'entrée FOSC /4, utiliser le prescaler (le prédiviseur) avec un rapport de P S = 32.
Questions :
1. Donner la conguration du registre T0CON et préparer le MPU pourqu'il tient compte de
l'interruption provenant de TMR0 puis démarrer le Timer0.
2. Donner la forme du programme d'interruption
M.ABDOUN 58
CHAPITRE 5. LES TIMERS
4. Au lieu de compter 0 à 255 puis débordement (c-à-d 256 points), le Compteur comptera à partir
de NT M R0 jusqu'au débordement 255 -> 0, et donc il aura compté : 256 − NT M R0 points. La
formule deviendra :
4
T = × P S × (28 − NT M R0 ).
FOSC
Cette formule est plutôt utilisée dans l'autre sens ; c'est à dire à partir de la période T , déter-
miner la valeur à charger dans TMR0 : NT M R0 .
T × FOSC
NT M R0 = 28 − .
4 × PS
4
τ= × PS
FOSC
Donc si on souhaite une bonne résolution, il faut choisir un P S le plus petit
possible. Mais dans ce cas, l'intervalle de temps TM AX se trouve réduit.
Sur une chaîne d'emballage, les pièces doivent être assemblées par lots de 10. Lorsque le lot est
réalisé, un signal Fin de lot est émis : LOT_REALISE. Une carte PIC18F452 (g. 5.8) permet de
gérer le nombre de pièces par lot. Pour celà on utilisera le Timer0 en mode comptage. Le passage
d'une pièce est simulé par le bouton poussoir PASSAGE PIECE. Pour visualiser l'état du compteur
de pièces déjà passées n_pieces_fabriquees, on fait sortir son contenu sur le PORTD.
Questions :
M.ABDOUN 59
CHAPITRE 5. LES TIMERS
void init_PORTs(void){...}
2. On veut congurer le Timer0 en mode comptage sur 8-bits (pas sur 16-bits) car le nombre
maxi de pièces dans un lot est < 256. L'incrémentation se fait sur front montant sur la broche
RA4/T0CKI. Pour détecter le passage de Np pièces par lot, on utilise l'interruption sur
débordement du Timer0. Quelle est alors la valeur à charger dans le registre TMR0L pour
avoir une interruption à chaque passage de Np pièces ?
void init_timer0(void){...}
3. Donner le corps de la fonction :
M.ABDOUN 60
CHAPITRE 5. LES TIMERS
Réponses :
1. void init_PORTs(void) {
TRISA4 = 1; // RA4/T0CKI=PASSAGE_PIECE en entrée
TRISC7 = 0; // RC7=LOT_REALISE en sortie
TRISD = 0x00; // PORTD pour visualisation, en sortie
// Timer 0 en compteur
void init_timer0(void) {
T08BIT = 1; // n'utiliser qu'un octet pour comptage: TMR0L
T0CS = 1; // incrémentation sur front de l'entrée RA4/T0CKI
T0SE = 0; // front montant sur RA4/T0CKI
TMR0L = RECHARGE_TMR0;
M.ABDOUN 61
CHAPITRE 5. LES TIMERS
TMR0IF = 0;
}
}
4. La fonction n_pieces_passees, utilise la valeur actuelle dans TMR0L pour déduire le nombre
de pièces déjà comptées depuis le dernier LOT (depuis le dernier débordement du Timer0) et
donc
void main() {
unsigned int output;
init_PORTs();
init_timer0();
while (1) {
output = n_pieces_passees();
LATD = output;
}
}
5.5.4 Timer1
M.ABDOUN 62
CHAPITRE 5. LES TIMERS
La gure 5.9 est un schéma fonctionnel simplié du module Timer1. Le registre 5.10 détaille le
registre de contrôle Timer1. Ce registre contrôle le mode de fonctionnement du module Timer1 et
contient le bit de validation de l'oscillateur Timer1 (T1OSCEN). Timer1 peut être activé ou désactivé
en réglant ou en eaçant le bit de contrôle TMR1ON (T1CON<0>).
Le Timer1 peut être utilisée soit comme une minuterie, soit comme un compteur. Lorsque le
bit TMR1CS du registre T1CON est bas, l'horloge : FOSC /4 est sélectionnée pour le temporisateur.
Lorsque TMR1CS est haut, le module fonctionne comme un compteur cadencé à partir de l'entrée
T1OSI. Un circuit oscillateur à quartz, activé à partir du bit T1OSCEN de T1CON, est construit
entre les broches T1OSI et T1OSO où un cristal jusqu'à 200 KHz peut être connecté entre ces
broches. Cet oscillateur est principalement destiné à un fonctionnement en cristal à 32 KHz dans les
applications d'horloge temps réel. Un pré-diviseur (de fréquence) est utilisé dans le Timer1 qui peut
diviser la fréquence de synchronisation d'un facteur de 1, 2, 4 ou 8, selon la valeur des bits T1CKPS1
et T1CKPS0 du T1CON.
Le Timer 1 peut être conguré pour que la lecture/écriture puisse être eectuée soit en mode
16 bits (les deux registres TMR1H et TMR1L échantillonnés en même instant), soit en deux modes
8 bits. Le bit RD16 du registre T1CON contrôle ce mode. Lorsque RD16 est bas, les opérations
de lecture et d'écriture du temporisateur sont exécutées comme deux opérations de 8 bits. Lorsque
RD16 est au niveau haut, les opérations de lecture et d'écriture du temporisateur sont en 16 bits, et
on peut utiliser TMR1, qui est de 16-bits ; par exemple TMR1 = 0XFF45.
Si les interruptions du Timer1 sont activées (TMR1IE = 1), une interruption sera générée lorsque
la valeur du temporisateur passe de 0xFFFF à 0x0000, c-à-d lors d'un débordement.
M.ABDOUN 63
CHAPITRE 5. LES TIMERS
Donc pour cet exemple, on utilisera le timer0 en compteur (comme on l'a déjà fait) et le Timer1
en générateur d'impulsion (monostable). Quelle est la valeur à donner au prédiviseur : P S et quelle
est la valeur à recharger dans TMR0 : NT M R0 pour obtenir la durée fournie ?
Durée réglable par pas de 4µs, veut dire la résolution de TMR1 est de 4µs et donc la valeur du
M.ABDOUN 64
CHAPITRE 5. LES TIMERS
On a déjà vu que :
T × FOSC
NT M R0 = 216 −
4 × PS
125.10−3 × 8.106
= 65536 −
4×8
= 65536 − 31250
= 34286
Réponse :
#include <xc.h>
// -------
unsigned int n_pieces_emballees = 0;
void init_PORTs(void) {
M.ABDOUN 65
CHAPITRE 5. LES TIMERS
TMR0L = RECHARGE_TMR0;
TMR1 = RECHARGE_TMR1;
M.ABDOUN 66
CHAPITRE 5. LES TIMERS
// LC7 ^= 1;
LC7 = 1; // activer la sortie LC7
TMR1 = RECHARGE_TMR1; // préparer la durée de l'impulsion sur LC7
TMR1ON = 1; // lancer la tempo associée au Timer1
TMR0IF = 0;
} else if (TMR1IF && TMR1IE) { // durée sur sortie LC7 dépassée
LC7 = 0; // mettre la sortie LC7 à 0; fin de l'impulsion
TMR1ON = 0; // stopper la tempo du Timer1
TMR1IF = 0;
}
}
void main() {
unsigned int output;
init_PORTs();
init_timer1();
init_timer0();
GIE = 1;
while (1) {
output = n_pieces_passees();
M.ABDOUN 67
CHAPITRE 5. LES TIMERS
M.ABDOUN 68