Microcontrôleurs 8051

publicité
Les microcontrôleurs
de la
famille MCS-51
ISTIA – Année 2007-2008
-1-
Bertrand Cottenceau
Sommaire
1
2
3
4
Introduction du cours....................................................................................................................................4
1.1
Introduction............................................................................................................................................4
1.2
Rappels de notions élémentaires de micro-informatique...............................................................5
1.3
Qu’est-ce qu’un microcontrôleur ? .....................................................................................................6
1.3.1
Avantages des systèmes à base de microcontrôleurs...............................................................6
1.3.2
Inconvénients des systèmes à base de microcontrôleurs .......................................................6
La famille MCS-51 ..........................................................................................................................................7
2.1
Introduction............................................................................................................................................7
2.2
Caractéristiques du noyau MCS51 .....................................................................................................7
2.3
Espaces mémoires des microcontrôleurs MCS51 ............................................................................8
2.4
Microcontrôleurs de la famille MCS51 avec mémoire de programme interne..........................9
2.5
Mémoire vive interne (mémoire de données interne), SFR .........................................................10
2.6
Modes d’adressage et jeu d’instructions...........................................................................................12
2.6.1
Registres ........................................................................................................................................12
2.6.2
Adressage Immédiat....................................................................................................................12
2.6.3
Adressage direct ...........................................................................................................................12
2.7
Adressage indirect par registre ...........................................................................................................12
2.8
Lien entre registres R0 à R7 et la RAM interne .............................................................................13
2.9
Différence entre les registres SFR et la partie haute de la RAM interne ...................................13
2.10
La pile pour la famille MCS51 .....................................................................................................13
2.11
Espace d’adressage bit .....................................................................................................................14
2.12
Jeu d’instructions de la famille MCS51 ......................................................................................15
2.13
Directives d’assemblage ..................................................................................................................19
Programmer les microcontrôleurs MCS51 en langage C ......................................................................22
3.1
Le cross compilateur SDCC (Small Device C Compiler).............................................................22
3.2
Variables : types et tailles ....................................................................................................................22
3.2.1
Types standard.............................................................................................................................22
3.2.2
Types liés au noyau 51 (extensions du C) ..............................................................................23
3.3
Les fonctions : paramètres et variables locales................................................................................25
3.4
Assembleur inline.................................................................................................................................25
3.5
Les routines d'interruption ................................................................................................................25
3.6
Le mot clé volatile et les fonctions "naked" ....................................................................................26
3.7
Plusieurs fichiers source......................................................................................................................27
3.8
Simulation et génération du fichier .hex (pour programmation des mémoires).....................28
Les ports E/S des microcontrôleurs MCS51............................................................................................30
4.1
Structure du Port P1............................................................................................................................30
-2-
4.2
5
6
7
Structure du port P0............................................................................................................................31
Les Timers de la famille MCS51 ................................................................................................................32
5.1
Les fonctions des timers MCS51.......................................................................................................32
5.2
Modes de fonctionnement .................................................................................................................32
5.3
Utilisation des timers 0 et 1 ...............................................................................................................34
5.4
Le timer 2...............................................................................................................................................35
Le gestionnaire d’interruptions de la famille MCS51 ............................................................................36
6.1
Mécanisme de gestion des interruptions .........................................................................................36
6.2
Implantation logicielle en cas de gestion d’interruptions pour la famille MCS51 .................37
6.3
Autorisation et priorité des interruptions.......................................................................................38
6.4
Sources d’interruption externes.........................................................................................................40
6.5
Sources d’interruption timer..............................................................................................................40
6.6
Programme complet exploitant des interruptions (Famille MCS-51)........................................40
Mise en œuvre des microcontrôleurs MCS51..........................................................................................43
7.1
L’oscillateur ...........................................................................................................................................43
7.2
Entrée RST (reset).................................................................................................................................44
7.3
Les entrées-sorties parallèles................................................................................................................44
7.4
Les mémoires externes.........................................................................................................................46
7.4.1
Bus adresses/données dans la famille MCS51.......................................................................47
7.4.2
Mémoire de programme externe..............................................................................................48
7.4.3
Mémoire de données externe....................................................................................................51
7.4.4
Mémoire de programme externe et mémoire de données externe.....................................52
7.5
Périphériques externes.........................................................................................................................53
7.5.1
Périphérique d’entrées/sorties programmable : PIO 8255 ..................................................53
8
Annexe A : Familles technologiques..........................................................................................................57
9
Annexe B : Les mémoires et leur représentation .....................................................................................58
10
Annexe C....................................................................................................................................................63
10.1
Bascule D ..........................................................................................................................................63
10.2
Décodeurs..........................................................................................................................................63
-3-
1
Introduction du cours
1.1
Introduction
Les microcontrôleurs sont des circuits intégrés regroupant dans un même boîtier un microprocesseur
(CPU), des périphériques (entrées/sorties TOR, port série, temporisateurs, entrées/sorties analogiques,
I²C, CAN), de la mémoire vive et le plus souvent de la mémoire morte de programme, en d’autres
termes, tous les composants habituellement nécessaires à un système programmable.
Ces circuits sont particulièrement bien adaptés à la réalisation de systèmes de commande lorsque
peu d’entrées/sorties sont en jeu et que l’élaboration de la commande ne nécessite pas une grande
puissance de calcul. Dans certains cas, l’utilisation d’un système à base de microcontrôleur offre une
alternative à l’utilisation d’un automate industriel. A titre d’exemple, une entreprise de la région
choletaise conçoit et vend un système complet de commande/supervision de serres à l’usage des
horticulteurs. Le système proposé est modulaire ; chaque module possède un microcontrôleur qui doit
gérer des entrées/sorties (température, hygrométrie, commande des ouvrants, chauffage) et communiquer
avec les autres modules en réseau ModBus.
Le marché du semi-conducteur offre un choix très large de produits. Chaque fabricant ne propose
pas un seul microcontrôleur, mais des familles de microcontrôleurs. On peut citer à titre d’exemple : la
famille MCS51 (8x31,8x51) étudiée dans ce cours, la famille 68HCxxx Motorola (68HC11, 68HC811), la
famille PIC 16Cxx (16C84, 16F84) Microchip. Au sein d’une même famille, les microcontrôleurs
possèdent le même processeur et donc le même langage, seuls les périphériques changent. Ainsi, la
connaissance de la structure matérielle et logicielle d’un produit d’une famille permet une adaptation
rapide à tout microcontrôleur de la même famille.
Les microcontrôleurs du marché se distinguent principalement par la structure de leurs processeurs
(4,8,16 ou 32 bits, CISC 1 ou RISC), la taille des espaces mémoires, la nature et la quantité de
périphériques. Certains microcontrôleurs seront spécialisés dans la gestion d’entrées/sorties TOR,
d’autres auront la possibilité de gérer des grandeurs analogiques ou posséderont des ports I²C ou CAN.
Sur le plan logiciel, outre le fait que le jeu d’instructions des microcontrôleurs 8 bits est
généralement restreint (d’autant plus s’il est à structure RISC), on dispose pour certains processeurs
d’environnements de développement intégrés contenant un assembleur, un cross compilateur C et
même parfois un simulateur. Il existe également, notamment pour la famille MCS51, des noyaux temps
réel permettant de compenser le manque de puissance de calcul par une meilleure répartition des tâches.
En résumé, lorsqu’on décide de développer un nouveau produit à base de microcontrôleur, puisque
l’offre est très vaste, plusieurs paramètres vont orienter notre choix vers un produit plutôt qu’un autre :
1
-
le prix : il y a de très grands écarts de prix entre les produits, liés par exemple à la taille et au
type de mémoire, ainsi qu’à la nature et la quantité de périphériques.
-
les périphériques : on peut se demander si toutes les fonctions décrites dans le cahier des
charge seront réalisées par le microcontrôleur ou s’il faudra ajouter des périphériques
externes.
-
taille des espaces mémoire : l’espace mémoire programme sera-t-il suffisant pour
l’application ?
-
consommation : déterminant pour des produits destinés à fonctionner sur batterie
-
outils de développement : peut-on développer en langage évolué ? Existe-t-il un
environnement de développement intégré (éditeur, assembleur, compilateur, simulateur
/debugger) ?
-
expérience/savoir faire
Complex Instruction Set Computer (CISC) en opposition à Reduced Instruction Set Computer (RISC)
-4-
L’objectif de ce cours est de donner un aperçu des fonctionnalités des microcontrôleurs que l’on peut
rencontrer sur le marché en s’intéressant plus particulièrement à la famille MCS51 Intel pour laquelle
nous détaillerons la structure matérielle et logicielle, ainsi que l’exploitation de certains périphériques.
D’autre part, on présentera et expliquera des montages « standards » à base de 8xC31 permettant
d’exploiter des entrées/sorties telles que des boutons poussoirs, des LEDS ou des afficheurs. Enfin, les
principes généraux de dialogue entre un microcontrôleur et un circuit périphérique seront expliqués et
illustrés au travers de certains montages.
Bien qu’étudiées en particulier pour la famille MCS51, beaucoup de techniques utilisées dans ce
cours sont également réutilisables pour d’autres microcontrôleurs du marché.
1.2
Rappels de notions élémentaires de micro-informatique
Structure d’un système programmable :
CPU
Circuits
Processeur
Mémoires
Circuits
Interfaces
E/S
L’unité centrale de traitement (CPU) dialogue avec les circuits mémoire pour y lire des instructions,
dialogue avec les circuits mémoire pour y lire ou écrire des données au fil du programme, dialogue avec
les circuits périphériques d’entrée/sortie (e.g. clavier, écran) pour échanger des informations avec un
utilisateur du système.
Un programme est une suite d’instructions (décrites par des mots binaires) stockées en mémoire du
système et exécutables par le processeur. Le processeur lit et exécute séquentiellement les instructions
d’un programme. Parmi les instructions acceptées par un processeur (jeu d’instructions du processeur),
certaines instructions permettent des sauts inconditionnels ou conditionnés par l’état du processeur.
La façon la plus claire de représenter un programme est d’utiliser un organigramme où apparaissent
les opérations élémentaires du processeur ainsi que les sauts conditionnels ou inconditionnels.
On appelle langage machine le code binaire stocké dans la mémoire du système et langage
d’assemblage (parfois abusivement appelé « assembleur ») le langage littéral qui utilise des mnémoniques
pour décrire les opérations élémentaires du processeur.
Début
Les ovales délimitent le début et la fin.
A ppv 2
Les rectangles contiennent des actions, ici
l'affectation de 2 à A et l'incrément de A..
Le saut conditionnel est décrit par un losange.
A ppv A+3
A<9
non
Fin
-5-
oui
Un processeur possède plusieurs registres internes pour stocker et manipuler des données et/ou des
adresses. Outre ces registres d’usage général, un processeur dispose systématiquement d’un registre
pointeur d’instruction appelé IP (instruction pointer) ou PC (program counter). Le processeur gère ce
registre de manière à ce qu’il contienne en permanence l’adresse de la prochaine instruction à exécuter,
d’ailleurs un saut (conditionnel ou non) n’est rien d’autre qu’une réinitialisation du pointeur
d’instruction. Un processeur dispose également toujours d’un registre d’état qui contient des indicateurs,
notamment des indicateurs issus des opérations arithmétiques et logiques (indicateur de signe, de
débordement etc.).
Enfin, un processeur gère systématiquement une pile (structure de données LIFO), notamment pour
les exécutions de sous-programmes. A cet effet, un processeur possède un pointeur de pile appelé
généralement SP (stack pointer) qui mémorise en permanence l’adresse du sommet de la pile. La pile du
processeur est toujours implicitement utilisée quand le processeur exécute une instruction de saut à un
sous-programme (CALL en langage 8086) ainsi que lors de l’exécution d’une routine d’interruption.
Remarque : nous avons vu que la pile servait également à stocker temporairement la valeur de
registres susceptibles d’être modifiés par un sous-programme et qui ne le devraient pas. La technique
utilisée est la suivante : au début d’un sous-programme, on empile le contenu de tous les registres qui
sont utilisés par le sous-programme et qui ne sont pas des sorties 2 du sous-programme. Juste avant
l’instruction de retour de sous-programme (RET en 8086), on restaure les registres à partir de la pile.
1.3
Qu’est-ce qu’un microcontrôleur ?
Dans un système « classique » à base de microprocesseur, le processeur, les circuits mémoires (ROM
ou RAM) et les circuits d’interface E/S sont des entités distinctes du système, c’est-à-dire des circuits
intégrés différents qui communiquent entre eux grâce au bus adresses/données/commandes. Un
microcontrôleur intègre dans un même boîtier les fonctions suivantes :
1.3.1
-
une unité centrale (CPU)
-
de la mémoire vive pour les données, voire de la mémoire morte de programme
-
des ports E/S booléens Tout-Ou-Rien (TOR)
-
[selon le modèle] des timers, des ports série, des convertisseur A/N et/ou N/A, des sorties
PWM (ou MLI modulation de largeur d’impulsion), bus I²C, bus CAN
Avantages des systèmes à base de microcontrôleurs
Diminution de l’encombrement du circuit : un système à base de microcontrôleur possède
généralement assez peu de composants électroniques
Circuit imprimé au tracé simplifié.
Circuit plus fiable car moins de composants.
Diminution des coûts : un microcontrôleur coûte moins cher que la somme des composants qu’il
intègre.
1.3.2
Inconvénients des systèmes à base de microcontrôleurs
Ne convient pas nécessairement à tous les problèmes : un microcontrôleur n’offre pas une grande
puissance de calcul.
On ne peut pas toujours utiliser tous les périphériques simultanément : pour diminuer les coûts,
certaines broches sont multiplexées.
Il faut disposer d’un outil de développement spécifique/compilateur, simulateur).
2
un registre est dit de sortie s’il contient un résultat.
-6-
2
La famille MCS-51
2.1
Introduction
La famille MCS 51 représente un ensemble de microcontrôleurs 8 bits (bus de sonnées de 8 bits)
ayant la même unité centrale (même noyau). Tous les microcontrôleurs de cette famille ont donc le
même langage machine. A titre d’exemple, dans la famille MCS51 on trouve les microcontrôleurs
suivants :
80C31 : microcontrôleur ROMless (sans mémoire programme interne), 128 octets de RAM, 2
compteurs/temporisateurs 16 bits, 24 E/S TOR, 1 port série.
80C32 : ROMless, 256 octets de RAM, 3 compteurs/temporisateurs 16 bits, 24 E/S TOR, 1 port
série.
Note : pour ces microcontrôleurs, le programme doit être inscrit dans une mémoire externe.
87C51 : mémoire programme interne de 2K, 4K, 8K ou 16K, OTP ou EPROM
Note : ce microcontrôleur existe en de multiples versions ayant plus ou moins de mémoire interne
de programme.
C’est la société INTEL qui a conçu le noyau MCS51. Néanmoins, d’autres constructeurs ont acheté
une licence pour avoir le droit de développer des microcontrôleurs ayant ce noyau. On trouve donc sur
le marché, outre les produits Intel, des microcontrôleurs OKI, Dallas SC, Phillips ou Siemens. La société
ATMEL propose notamment des microcontrôleurs très populaires disposant de Flash Rom (ATMEL
89C51).
2.2
Caractéristiques du noyau MCS51
CPU 8 bits : le processeur de la famille MCS51 est un processeur 8 bits avec une architecture qui
suit en partie les principes RISC (Reduced Instruction Set Computer). Les 2/3 des instructions
s’exécutent en un seul cycle machine.
Remarque : un cycle machine correspond à 12 cycles de l’oscillateur. Avec un oscillateur à 12Mhz, un
cycle machine a une durée de 1 micro seconde.
Processeur booléen : certaines instructions sont prévues pour travailler avec un seul bit et une partie
de la RAM interne est adressable au niveau du bit (cela signifie que, dans une zone mémoire
particulière, certains bits peuvent être modifiés (initialisés ou complémentés) indépendamment des
autres bits). Grâce à ces instructions particulières, la gestion des ports E/S TOR est largement simplifiée.
Espaces d’adressage : contrairement au modèle Von Neumann où données et programme sont dans
le même espace d’adressage, les microcontrôleurs de la famille MCS51 possèdent plusieurs espaces
d’adressage différents.
Espace Mémoire Programme : on appelle ainsi la zone mémoire contenant le programme de
l’application. Cet espace mémoire est généralement composé d’une ou de plusieurs mémoires accessibles
uniquement en lecture (ROM, OTPROM, EPROM, EEPROM, Flash ROM).
Espaces Mémoires de Données : il y a plusieurs espaces d’adressage de données. Il y a la RAM
interne qui contient une centaine d’octets et la RAM externe qui peut contenir jusqu’à 64 Ko. Il faut
garder à l’esprit qu’il n’y a aucun mot commun entre la mémoire programme et les mémoires de
données.
Espace Adressable Bit par Bit : une partie de la RAM interne est adressable au niveau du bit.
Registres à fonctions spéciales (SFR) : les registres permettant de gérer les périphériques intégrés
sont regroupés dans un ensemble appelé SFR. Ces registres sont accessibles comme s’il s’agissait d’un
espace mémoire particulier. Les registres SFR sont atteints au moyen de 128 adresses différentes.
-7-
2.3
Espaces mémoires des microcontrôleurs MCS51
Une des caractéristiques les plus déroutantes, lorsque l’on s’initie aux microcontrôleurs de la famille
MCS51, est incontestablement la multiplicité des espaces d’adressages. Dans le modèle de Von
Neumann, le processeur ne dialogue qu’avec un seul espace d’adressage dans lequel il lit des instructions
et lit ou écrit des données. Le processeur 8086 vu en IUP2 M²AI suit globalement ces principes puisque
le code programme et les données sont dans le même espace d’adressage, mais à des adresses différentes.
Pour le noyau MCS51, c’est différent. Il y a de la mémoire pour stocker des instructions (mémoire
de programme) et plusieurs mémoires pour stocker des données (mémoire données interne, mémoire
données externes). Il y a même une zone où les bits sont accessibles un par un (zone d’adressage bit).
Enfin, certains registres, notés R0 à R7, utilisés par les instructions sont logés dans des zones de la
mémoire de données interne. Pour terminer cette description succincte, les registres des interfaces E/S
(tampons de ports, buffers liaison série, gestion contrôleur d’interruption), appelés SFR, sont accessibles
par les mêmes instructions que celles permettant la lecture et l’écriture en RAM interne. C’est pourquoi
les registres SFR figurent également sur les plans mémoire du noyau MCS51.
Le schéma suivant, qui sera expliqué partie par partie au fil du cours, présente l’ensemble des
différentes zones adressables du noyau MCS51.
FFFFh
FFFFh
adressage indirect
adressage direct
FFh
cette partie
haute n'existe que
sur certains
modèles
(8032,8052,8752)
FFh
Mémoire prog.
externe
128 octets
RAM interne
SFR
Mémoire données
externe
64 Ko
P0 à P3
buffers UART
contrôleur IT ...
/EA=0ou1
80h
80h
7Fh
zone adressage
bit par bit
bit[00h]-bit[7Fh]
RS1 = 1 RS0 = 1 R0-R7 banque 3
RS1 = 1 RS0 = 0 R0-R7 banque 2
RS1 = 0 RS0 = 1 R0-R7 banque 1
RS1 = 0 RS0 = 0 R0-R7 banque 0
30h
2Fh
20h
1Fh
18h
17h
10h
0Fh
Mémoire prog.
interne 2K, 4K,
8K ou 16K
si
Mémoire prog.
externe
si
/EA = 1
/EA = 0
08h
07h
00h
0000h
0000h
adresse octet
RAM interne + SFR
Mémoire programme (64Ko)
Mémoire données
externe (64Ko)
En raison de la multiplicité des espaces mémoire et des zones adressables, on utilisera les notations
suivantes pour distinguer les différents espaces d’adressage.
-8-
0000h
IRAM (RAM Interne) : correspond aux 128 ou 256 octets de RAM interne au microcontrôleur.
L’adresse utilisée pour atteindre un octet de la RAM interne est codée sur 8 bits.
IRAM[02h] = octet de la RAM interne d’adresse 02h
SFR (Special Function Registers) : l’ensemble des registres à fonctions spéciales. Ces registres sont
accessibles au moyen d’une adresse. Par contre, ils ne sont accessibles qu’en adressage direct. On utilisera
parfois cette notation pour qu’il n’y ait pas d’ambiguïté entre RAM interne et registres SFR. (voir détail
des SFR dans ce chapitre).
SFR[80h]
SFR[81h]
SFR[E0h]
d’atteindre
= registre d’adresse 80h, tampon du port P0
= registre d’adresse 81h, SP (stack pointer)
= registre d’adresse E0h, l’accumulateur (c’est une autre façon
A)
BIT : cette notation désignera l’espace d’adressage au niveau du bit. La taille de cet espace d’adressage
est de 256 bits. L’adresse d’un bit est donc une adresse sur 8 bits.
BIT[00h] = bit d’adresse 00h
BIT[14h] = bit d’adresse 14h
ROM : espace mémoire de programme. Cet espace mémoire contient le code machine de
l’application. La taille de cet espace est de 64 Ko, l’adressage se fait donc sur 16 bits.
ROM[0000h] = premier octet de la première instruction exécutée après mise
sous tension
Remarque : si nécessaire, on fera la différence entre IROM (la mémoire programme interne au
microcontrôleur) et XROM (mémoire programme externe au microcontrôleur) ajoutée pour étendre la
capacité du système.
XRAM : mémoire de données externe. On peut adjoindre de la mémoire de données externe au
microcontrôleur. Cet ajout de mémoire est facultatif. Il peut se faire au moyen de boîtiers de mémoires
statiques connectés au bus du microcontrôleur. Cet espace d’adressage a une taille de 64 Ko, l’adressage
de la mémoire de données externe s’effectue donc sur 16 bits.
XRAM[0000h]
externes ».
2.4
=
octet
d’adresse
0000h
dans
l’espace
mémoire
« données
Microcontrôleurs de la famille MCS51 avec mémoire de programme interne
Certains microcontrôleurs de la famille MCS51 possèdent de la mémoire de programme interne non
volatile. Elle a pour rôle de conserver le programme de l’application, même en absence d’alimentation.
Il s’agit, selon la référence, de mémoire de type ROM, OTPROM, EPROM, EEPROM ou Flash. Cette
mémoire n’est accessible qu’en lecture.
Lorsqu’un microcontrôleur contient de la mémoire programme interne, celle-ci doit être
programmée (c’est-à-dire écrite) avant que le microcontrôleur soit inséré dans le système. La
programmation d’une mémoire morte se fait soit chez le constructeur lorsqu’il s’agit de mémoire ROM,
soit au moyen d’un ordinateur de type PC muni d’un programmateur s’il s’agit d’EPROM ou
d’EEPROM.
Note : on utilise parfois génériquement le terme « ROM » pour désigner de la mémoire morte de
programme, même s’il s’agit en réalité d’EPROM, d’EEPROM ou de mémoire flash.
Les microcontrôleurs avec de la mémoire programme interne sont les plus utilisés car ils permettent
la réalisation de systèmes nécessitant très peu d’électronique.
Le pointeur d’instruction PC du noyau MCS51 est un pointeur 16 bits. L’espace d’adressage
mémoire programme fait donc au maximum 64 Ko (216). Autrement dit, l’application doit faire au plus
64 Ko de code. Les microcontrôleurs avec mémoire programme interne trouvés sur le marché
contiennent 2Ko, 4Ko, 8Ko ou 16Ko de mémoire programme interne, ce qui ne couvre pas les 64 Ko
d’espace d’adressage possible. On peut néanmoins compléter la mémoire de programme interne par de
la mémoire de programme externe. Cette dernière solution nécessite en revanche l’ajout de plusieurs
-9-
circuits externes. On verra dans le chapitre suivant les montages type permettant d’exploiter de la
mémoire externe.
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
NPN
FREQ=12MHz
19
18
39
38
37
36
35
34
33
32
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
VCC
Important : dans tous les cas, qu’il s’agisse de mémoire de programme interne ou externe, après mise
sous tension et initialisation du microcontrôleur, la CPU charge et exécute l’instruction située à l’adresse
0000h de la mémoire de programme.
31
30
29
9
21
22
23
24
25
26
27
28
80C51FA
Montage à base de 8051 (mémoire de programme interne) pilotant une LED
Bien que la mise en œuvre matérielle des microcontrôleurs soit abordée plus tard dans le polycopié,
la figure précédente présente un premier montage très simple utilisant un microcontrôleur avec de la
mémoire de programme interne (80C51). Ce système permet le pilotage d’une LED. Comme on le verra
plus tard, le quartz de 12 MHz est utilisé par l’oscillateur et la cellule RC (à droite du 80C51) est
nécessaire à l’initialisation du microcontrôleur (broche RST).
2.5
Mémoire vive interne (mémoire de données interne), SFR
adressage indirect
adressage direct
FFh
cette partie
haute n'existe que
sur certains
modèles
(8032,8052,8752)
FFh
128 octets
RAM interne
SFR
80h
P0 à P3
buffers UART
contrôleur IT ...
80h
7Fh
bit[78h]
bit[7Fh]
30h
2Fh
zone adressage
bit par bit
bit[09h]
bit[00h]
20h
bit[07h]
RS1 = 1 RS0 = 1 R0-R7 banque 3
RS1 = 1 RS0 = 0 R0-R7 banque 2
RS1 = 0 RS0 = 1 R0-R7 banque 1
RS1 = 0 RS0 = 0 R0-R7 banque 0
1Fh
18h
17h
10h
0Fh
R0 si RS0=0 et RS1=1
08h
07h
00h
R0 si RS0=RS1=0
adresse octet
-10-
Tous les microcontrôleurs de la famille MCS51 disposent de mémoire vive interne (RAM interne)
pour lire ou écrire des données. Elle est de petite taille : soit 128 octets (pour le 80C31 ou le 80C51), soit
256 octets (80C32, 80C52). Dans tous les cas, la RAM interne de données est adressée sur 8 bits.
La RAM interne stocke également la pile et des banques de registres d’usage général notés R0 à R7.
La constitution de la RAM interne est décrite dans la figure.
Le plan mémoire de la RAM interne représente également la zone des registres SFR. Bien qu’il ne
s’agisse pas véritablement de mémoire, les SFR sont accessibles à l’aide des mêmes instructions que celles
permettant d’atteindre la RAM interne. Les SFR sont les registres permettant de gérer les périphériques.
On y retrouve les registres des tampons des ports TOR (P0, P1, P2 et P3), les registres de gestion des
timers, les registres de configuration du contrôleur d’interruptions etc. Voici une description plus
détaillée, adresse par adresse, des registres SFR.
Nom
Fonction
Adresse
B
Registre pour multiplication et division
F0h
ACC
Accumulateur
E0h
PSW
Mot d’état
D0h
IP
Registre priorité des interruptions
B8h
P3
Tampon 8 bits du port E/S P3
B0h
IE
Masque des interruprions (IT Enable)
A8h
P2
Tampon 8 bits du port E/S P2
A0h
SBUF
Tampon de l’UART
99h
SCON
Configuration de l’UART
98h
P1
Tampon 8 bits du port E/S P1
90h
TH1
Registres poids fort timer 1
8Dh
TH0
Registres poids fort timer 0
8Ch
TL1
Registres poids faible timer 1
8Bh
TL0
Registres poids faible timer 0
8Ah
TMOD
Modes des Timers 0 et 1
89h
TCON
Configuration Timers 0 et 1
88h
PCON
Mode de consommation pour CMOS
87h
DPH
Registre 8 bits fort de DPTR
83h
DPL
Registre 8 bits faible de DPTR
82h
SP
Pointeur de pile
81h
P0
Tampon 8 bits du port P0
80h
La figure montre que la partie haute de l’espace RAM interne et les SFR possèdent les mêmes
adresses. On peut alors se demander comment l’on distinguera la RAM des SFR. En réalité, la partie
haute de la RAM interne n’est accessible qu’en adressage indirect alors que les registres SFR ne sont
accessibles qu’en adressage direct. Ce sera donc le mode d’adressage qui différenciera ces deux espaces
d’adressage.
Enfin, la partie basse de la RAM interne correspond également à un ensemble de registres généraux
notés R0 à R7.
-11-
2.6
Modes d’adressage et jeu d’instructions
Le jeu d’instructions du noyau MCS51 est réduit. Toutes les instructions sont réunies de manière
exhaustive sur une seule feuille au format A4 (à la fin du polycopié). Notons que les mnémoniques
utilisés par le langage d’assemblage 51 sont très proches de ceux du langage 8086.
2.6.1
Registres
Le processeur utilise un registre accumulateur noté A pour les transferts, les opérations
arithmétiques et les opérations logiques.
MOV A,#2
ADD A,#3
INC A
A ppv 2
A ppv A+3
A ppv A+1
Certaines instructions permettent également d’exploiter les registres R0 à R7 situés dans la partie
basse de la RAM interne.
MOV R0, A
MOV A, R1
ADD A, R2
2.6.2
R0 ppv A
A ppv R1
A ppv A+R2
Adressage Immédiat
Le langage d’assemblage MCS51 utilise le # pour indiquer une donnée immédiate (donnée figurant
dans le code instruction). L’assembleur utilisé en TP accepte des désignateurs de base : b pour binaire, h
pour hexadécimal et d (ou rien) pour décimal.
MOV A,#35h
MOV R3,#3d
ADD A,#00110011b
A ppv (35)h
R3 ppv 3
A ppv A + (00110011)b
Attention : tout ce que l’on explique ici est lié au programme assembleur utilisé. Il faut garder à l’esprit
que, bien que proposant des services équivalents, tous les assembleurs n’utilisent pas exactement la
même syntaxe.
2.6.3
Adressage direct
L’adressage direct en langage d’assemblage MCS51 n’utilise pas de symbole particulier, contrairement
au langage d’assemblage 8086 qui utilise les crochets.
MOV A,30h
MOV 00h, R3
ADD A,01h
A ppv IRAM[30h]
(A ppv l’octet d’adresse 30h dans la RAM interne)
IRAM[00h] ppv R3
(l’octet d’adresse 00h dans la RAM interne ppv R3)
A ppv A + IRAM[01h]
Attention : ne pas confondre ADD
A,01h (A ppv A + IRAM[01h])
et ADD
A,#1 (A ppv A+1)
Différences entre les langages d’assemblage 8086 et MCS51
8086
MOV AH,8
MOV AH,[0000]
(adressage immédiat A ppv 8)
(adressage direct)
MOV A,#8
MOV A,0
(adressage immédiat)
(adressage direct)
MCS51
2.7
Adressage indirect par registre
En mode d’adressage indirect, un opérande est désigné par une adresse et l’adresse de l’opérande est
contenue dans un registre.
-12-
Seuls deux registres peuvent contenir une adresse : les registres R0 et R1.
MOV A,@R0
A ppv IRAM[R0] où R0 contient une adresse
MOV R0,#40h
MOV @R0,#2
R0 ppv (40)h
IRAM[R0]=IRAM[40h] ppv 2
Exemple :
2.8
Lien entre registres R0 à R7 et la RAM interne
Nous avons vu que le noyau de la famille MCS51 possède des registres notés R0 à R7. Leur usage est
assez général et l’on remarque que beaucoup d’instructions peuvent les exploiter.
Pour être un peu plus précis, les registres R0 à R7 correspondent également à des adresses de la RAM
interne. A l’initialisation du microcontrôleur, les registres R0 à R7 correspondent physiquement aux
octets de la RAM interne d’adresses 00h à 07h. Mais ça peut changer par programmation.
En fait, la position des 8 registres R0 à R7 peut être située dans 4 banques différentes de registres. Le
choix de la banque de registre, et donc de la position des registres R0 à R7, dépend de deux bits de
sélection de banque appelés RS0 et RS1. Ces deux bits appartiennent au registre d’état PSW
(PSW=SFR[D0h]).
Lorsque RS0=RS1=0, les registres R0 à R7 sont dans la banque 0, c’est-à-dire
R0 équivaut à IRAM[00h] et R7 équivaut à IRAM[07h].
Lorsque RS0=1 et RS1=0, les registres R0 à R7 sont dans la banque 1, c’est-à-dire
R0 équivaut à IRAM[08h] et R7 équivaut à IRAM[0Fh],
et ainsi de suite pour les banques 2 et 3.
Attention : puisque les registres R0 à R7 sont stockés dans la RAM interne, il convient d’être prudent.
On peut très bien modifier un registre Ri sans s’en rendre compte.
Exemple (RS0=RS1=0) :
MOV R3,#4
MOV R0,#3
MOV @R0,#2
2.9
R3 ppv 4
R0 ppv 3
IRAM[03h] ppv 2, à cet instant IRAM[R0] correspond aussi
au registre R3
Différence entre les registres SFR et la partie haute de la RAM interne
On a vu que les registres SFR sont repérés par des adresses. Les instructions permettant de lire/écrire
les registres SFR sont les mêmes instructions que celles permettant le lire/écrire la RAM interne. Ce qui
distingue les deux espaces d’adressage, c’est le mode d’adressage.
La zone de la RAM interne allant de l’adresse 80h à FFh n’est accessible qu’en adressage indirect par
registre, par exemple à l’aide des instructions
MOV R0,#90h
MOV @R0,A.
IRAM[R0]=IRAM[90h] ppv A
Les registres SFR ne sont accessibles qu’en adressage direct, par exemple à l’aide d’une instruction
telle que
MOV 90h,A
SFR[90h] ppv A
2.10 La pile pour la famille MCS51
La pile du microprocesseur est stockée dans la RAM interne. Elle est de ce fait limitée à un
maximum de 256 octets.
A l’initialisation du microcontrôleur, le pointeur de pile SP (SP=SFR[81h]) est initialisé avec
l’adresse 07h. A la différence du 8086, la pile d’un microcontrôleur de la famille MCS51 croît vers les
adresses croissantes. Lorsqu’on empile un octet (on ne peut pas empiler plus qu’un octet à la fois
-13-
d’ailleurs), le pointeur SP est d’abord incrémenté de 1, puis l’emplacement désigné par SP reçoit la
valeur à mémoriser.
Notons que seules deux instructions permettent d’accéder à la pile : PUSH et POP. En outre, la valeur
à empiler doit être désignée en adressage direct.
Exemple :
PUSH 03h
équivaut à recopier IRAM[03h] (l’octet de la RAM interne d’adresse 03h) dans
la pile
En détaillant ce qui se passe pour les instruction d’accès à la pile, on peut résumer par
PUSH 03h
POP 02h
SP ppv SP+1
IRAM[SP] ppv IRAM[03h]
IRAM[02h] ppv IRAM[SP]
SP ppv SP-1
L’accès à la pile par les instructions PUSH et POP utilise toujours implicitement le pointeur SP qui
contient l’adresse de la RAM où l’on doit écrire ou prélever l’information. L’accès à la pile est donc vu
comme un accès mémoire indirect par le registre SP. Ceci pour dire que lorsque la pile croît, elle s’étend
dans la partie supérieure de la RAM interne, et non dans les SFR (ce qui serait fort dommage).
En fait, la pile peut très bien être placée dans la partie haute de la RAM interne (entre les adresses
80h et FFh), ceci en initialisant dès le début de l’application SP avec une valeur supérieure à 80h.
2.11 Espace d’adressage bit
Nous avons signalé que le processeur intégré aux microcontrôleurs de la famille MCS51 peut
manipuler des informations d’un seul bit (et non un octet ou un mot comme c’est le cas le plus
souvent). Cette caractéristique lui vaut l’appellation « processeur booléen ».
Toutes les informations ne sont pas accessibles bit par bit. Seules certaines zones de la mémoire vive
interne et des SFR sont adressables par bit.
Dans l’ensemble IRAM + SFR, seuls 256 bits sont adressables au niveau du bit. Ces 256 bits sont
désignés par une adresse sur 8 bits (00h à FFh). Ces zones sont représentées sur la figure page suivante.
Les 128 premiers bits adressables, notés BIT[00h] à BIT[7Fh], sont les bits des octets de la RAM
interne allant de l’adresse 20h à 2Fh. Le bit d’adresse 00h est le bit de poids faible de l’octet d’adresse
20h, le bit d’adresse 7Fh est le bit de poids fort de l’octet 2Fh.
Le bit d’adresse 00h, noté BIT[00h], correspond au bit de poids faible de l’octet IRAM[20h]
Le bit d’adresse 01h, noté BIT[01h], correspond au second bit de l’octet IRAM[20h]
Le bit d’adresse 07h, noté BIT[07h], correspond au bit de poids fort de l’octet IRAM[20h]
Le bit d’adresse 08h, noté BIT[08h], correspond au bit de poids faible de l’octet IRAM[21h] etc.
On voit que l’espace d’adressage des bits dépend de la RAM interne. Aussi, lorsque l’on modifie un
bit d’adresse comprise entre 00h et 7Fh, on modifie par conséquent un octet situé entre l’adresse 20h et
l’adresse 2Fh, et vice versa.
Les 128 derniers bits adressables sont des bits de certains registres SFR. Seuls les registres SFR dont
l’adresse finit par 0h ou 8h en hexadécimal sont des registres dont les bits peuvent être adressés bit par
bit. Autrement dit, les registres SFR[80h], SFR[88h], SFR[90h], SFR[98h] … sont des registres adressables
par bit.
Le bit d’adresse 80h, noté BIT[80h], est le bit de poids faible du registre SFR[80h].
Le bit d’adresse 87h, noté BIT[87h], est le bit de poids fort du registre SFR[80h].
Le bit d’adresse 88h, noté BIT[88h], est le bit de poids faible du registre SFR[88h].
-14-
FFh
B
F0h
E8h
ACC
E0h
E8h
PSW
D0h
SFR
P2
A0h
SCON
98h
P1
90h
TCON
88h
P0
80h
bit[96h]
bit[8Fh]
bit[87h]
bit[90h]
bit[88h]
7Fh
bit[80h]
bit[83h]
bit[78h]
bit[7Fh]
30h
2Fh
zone adressage
bit par bit
bit[09h]
bit[00h]
20h
bit[07h]
1Fh
18h
17h
10h
0Fh
08h
07h
00h
adresse octet
La figure montre que les ports P0 à P3 sont adressables bit par bit, ainsi que l’accumulateur (registre
A), le registre B et le registre PSW. Il convient de se reporter au tableau décrivant les registres SFR pour
savoir quel registres sont adressables par bit.
2.12 Jeu d’instructions de la famille MCS51
La feuille donnée en annexe décrit de manière exhaustive toutes les instructions du microcontrôleur.
On va se contenter ici de donner quelques précisions.
Opérations de transfert
MOV
: ce mnémonique regroupe toutes les instructions de transfert
Exemple : on rappelle à titre d’exemple quelques instructions utilisant le mnémonique MOV
MOV
MOV
MOV
MOV
A,R2
A,#8
12h,@R0
10h,11h
A ppv R2
A ppv 8
IRAM[12h] ppv IRAM[R0]
IRAM[10h] ppv IRAM[11h]
-15-
Pointeur long (DPTR) : les espaces d’adressage Mémoire Programme et Mémoire de Données Externe
sont des espaces de 64Ko. Ils nécessitent donc des adresses de 16 bits. Le pointeur DPTR permet
d’adresser ces espaces. Le registre DPTR de 16 bits est constitué des 2 registres DPL (poids faible de
DPTR) et DPH (poids fort de DPTR). Les registres DPH et DPL sont visibles dans les SFR,
DPH = SFR[ 83h] et DPL = SFR[82h].
Le jeu d’instructions contient l’instruction MOV DPTR,#data16 pour initialiser DPTR. La
donnée immédiate doit être une donnée de 16 bits.
MOV DPTR,#2000h
MOVC : ce mnémonique désigne un transfert depuis la mémoire de programme vers A. Ces instructions
permettent de lire des données dans la mémoire programme (ROM). Rappelons que, de toute façon, la
mémoire programme n’est accessible qu’en lecture.
MOVC A,@A+DPTR équivaut à A ppv ROM[DPTR+A]
Cette instruction permet de lire un octet situé en mémoire programme (dans la mémoire de
type ROM) à l’adresse A+DPTR. Cette instruction est utilisée pour exploiter des données écrites dans la
mémoire de programme. Il s’agit nécessairement de valeurs constantes inscrites lors de la
programmation de la mémoire programme (interne ou externe).
MOVC A,@A+PC équivaut à A ppv ROM[PC+A]
: ce mnémonique désigne les instructions permettant la lecture/écriture dans l’espace mémoire de
données externe. Cela permet d’accéder à de la RAM externe supplémentaire, ou bien, comme on le
verra plus loin dans le cours, cela permet d’accéder à des périphériques externes additionnels.
MOVX
MOVX A,@DPTR
MOVX @DPTR,A
A ppv XRAM[DPTR]
XRAM[DPTR] ppv A
: ce mnémonique désigne les instructions permettant l’échange du contenu de deux registres, ou
d’un registre et d’un emplacement en RAM interne.
XCH
XCH A,10h
tampon ppv A, A ppv IRAM[10h], IRAM[10h] ppv tampon
Opérations arithmétiques
: ce mnémonique désigne les instructions permettant l’addition (sans prise en compte de la retenue).
Toutes ces instructions utilisent le registre A pour accumuler le résultat.
ADD
ADD
ADD
ADD
ADD
A,10h
A,R3
A,@R1
A,#2
A
A
A
A
ppv
ppv
ppv
ppv
A+IRAM[10h]
A+R3
A+IRAM[R1] (adressage indirect)
A+2 (adressage immédiat)
: ce mnémonique désigne les instructions permettant l’addition avec prise en compte de la retenue.
Toutes ces instructions utilisent le registre A pour accumuler le résultat. Cette instruction dispose des
mêmes modes d’adressage que ADD.
ADDC
: ce mnémonique désigne les instructions permettant la soustraction avec prise en compte de la
retenue. Cette instruction dispose des mêmes modes d’adressage que ADD.
SUBB
INC, DEC
: instructions d’incrément/décrément de 1
INC
DEC
INC
DEC
A
R6
@R0
10h
A ppv A + 1
R6 ppv R6 - 1
IRAM[R0] ppv IRAM[R0] + 1
IRAM[10h] ppv IRAM[10h] – 1
MUL AB : cette instruction réalise le produit non signé du contenu du registre A et du contenu du
registre B et place les 8 bits de poids fort du résultat (16 bits) dans B et les 8 bits de poids faible dans A.
DIV AB : cette instruction réalise la division non signée du contenu du registre A par le contenu du
registre B et place le quotient (8 bits) dans A et le reste de la division (8 bits) dans B.
-16-
: ajustement décimal de A. Cette instruction est utilisée pour la manipulation des valeurs codées en
BCD. Le BCD (Binary Coded Decimal) est un code binaire qui représente chaque digit décimal par 4
bits BCD. Le chiffre 1 est codé 0001, le 2 est codé 0010 … le 9 est codé 1001. Un octet BCD permet la
représentation des valeurs décimales comprises entre 0 et 99. A titre d’exemple, 27 est codé (00100111),
56 est codé (01010110). Les opérations arithmétiques ne sont pas les mêmes en code binaire classique et
en BCD. Aussi, pour pouvoir additionner ou soustraire des valeurs BCD et conserver le résultat en
BCD, l’instruction DA A permet la correction d’un résultat.
DA A
Note : le code BCD est utilisé par exemple pour simplifier les affichages numériques sur des afficheurs 7
segments.
Exemple d’utilisation :
MOV A,#27h
ADD A,#56h
DA A
(27)h
(56)h
Ici A
Ici A
est le code BCD de 27
est le code BCD de 56
vaut (7D)h
vaut (83)h qui représente le code BCD de 27+56=83
Opérations logiques
ANL, ORL, XRL : opérations ET, OU et OU exclusif sur des octets. Ces instructions utilisent les mêmes
modes d’adressage que les instructions arithmétiques.
Opérations booléennes
On a vu que la mémoire possédait une zone d’adressage de bits. Certaines instructions sont prévues
pour manipuler des informations de 1 bit. Ces opérations logiques utilisent le bit de retenue CY du
registre PSW (SFR[D0h]) comme accumulateur. Le symbole C utilisé dans les instructions booléennes
représente donc le bit de retenue du processeur.
Exemple de quelques instructions manipulant les bits : toutes ces instructions utilisent des adresses de
bits, et non des adresses d’octets.
CLR C
SETB C
CLR 08h
SETB 07h
CPL 91h
ANL C,10h
ANL C,/10h
MOV C,23h
bit de retenue ppv 0
bit de retenue ppv 1
BIT[08h] ppv 0
(BIT[08h] = bit de poids faible de l’octet IRAM[21h])
BIT[07h] ppv 1
(BIT[07h] = bit de poids fort de l’octet IRAM[20h])
BIT[91h] ppv /BIT[91h]
(BIT[91h] = bit 1 du tampon du port 1)
C ppv C ET BIT[10h]
C ppv C ET /BIT[10h]
C ppv BIT[23h]
Remarque : le bit de retenue est également adressable directement puisqu’il appartient au registre PSW
dont l’adresse dans les SFR est D0h. Le bit de retenue est le bit 7 du registre PSW, par conséquent, son
adresse directe dans l’espace d’adressage des bits est D7h. Autrement dit, les deux instructions suivantes
ont le même effet, celui de complémenter C :
CPL C
(1 cycle, 1 octet)
CPL 0D7h
(1 cycle, 2 octets)
Les deux instructions précédentes s’exécutent en un seul cycle machine, en revanche la seconde fait
un octet de plus que la première puisque le code de l’instruction contient l’adresse D7h.
Sauts et ruptures de séquence
Les instructions de sauts requièrent une adresse (sur 11 ou 16 bits) ou un déplacement relatif (sur 8 bits).
La programmation en langage d’assemblage nous autorise néanmoins à utiliser des symboles (étiquettes)
pour préciser où doivent avoir lieu les branchements ; c’est l’assembleur qui se charge de calculer les
adresses directes ou relatives utilisées par les instructions de saut.
-17-
En particulier, bien qu’il existe plusieurs instructions de saut inconditionnel (AJMP, LJMP, SJMP), on
peut utiliser le mnémonique JMP pour désigner un saut inconditionnel ; c’est l’assembleur qui se
chargera d’appliquer l’instruction adéquate.
Suivent quelques séquences de programme utilisant des instructions de sauts. On a également donné le
code machine correspondant.
bcle:
0000 740A
0002 14
0003 70FD
MOV A,#10
DEC A
JNZ bcle
1
2
3
bcle:
MOV A,#10
DEC A
JNZ bcle
On voit que l’assembleur a calculé le déplacement –3 (soit FDh) pour l’étiquette bcle.
bcle:
0000 E4
0001 2402
0003 B414FB
CLR A
ADD A,#2
CJNE A,#20d,bcle
1
2
3
bcle:
CLR A
ADD A,#2
CJNE A,#20d,bcle
L’instruction DJNZ facilite la réalisation de boucles :
bcle:
MOV R3,#99
NOP
DJNZ R3,bcle
(1 cycle)
(1 cycle)
(2 cycles)
Cette dernière séquence permet notamment la réalisation de temporisations logicielles. Par
exemple, avec un quartz à 12Mhz, un cycle machine dure 1 micro seconde. Aussi, la dernière séquence
dure 200 cycles, soit 200 micro secondes.
Sous programmes
Le jeu d’instructions du noyau 8051 dispose également d’instructions permettant le réalisation de sousprogrammes. Les instructions ACALL et LCALL réalisent un saut à une adresse avec empilement de
l’adresse de retour. L’instruction RET dépile l’adresse de retour et revient au programme d’appel.
En pratique, on peut utiliser le mnémonique CALL en langage d’assemblage, l’assembleur se charge de
choisir l’instruction adéquate.
Le programme suivant donne un exemple de sous-programme réalisant une temporisation.
P1 EQU 90h
ORG 0000h
MOV P1,#00h
recommence:
CPL P1.0
CPL P1.2
CALL TEMPO
jmp recommence
TEMPO:
PUSH 00h
PUSH 01h
MOV 00h,#100
bcl2:
MOV 01h,#100
bcl1:
DJNZ 01h,bcl1
DJNZ 00h,bcl2
POP 01h
POP 00h
RET
END
-18-
Le sous-programme de temporisation réalise approximativement 100 boucles de 200 cycles soit,
avec un quartz de 12 Mhz, une temporisation d’un peu plus de 0,02 secondes.
2.13 Directives d’assemblage
On a vu dans le cours de micro-informatique que les programmes assembleurs utilisent, en plus des
mnémoniques d’instructions, des directives d’assemblage destinées à faciliter l’écriture de programmes
en langage de bas niveau.
Toutes les directives d’assemblages sont propres aux assembleurs utilisés et peuvent changer d’un
assembleur à un autre. Par exemple, l’assembleur ASM51.EXE impose de faire suivre les labels du
caractère « : » mais pas celui utilisé en séances de TP.
Directive EQU
Cette directive réalise une équivalence entre un nom et une valeur numérique. Concrètement, avant
la phase d’assemblage, l’assembleur va remplacer les occurrences d’une chaîne par une autre chaîne.
Par exemple, dans le programme suivant, les chaînes ACC et PORT1 sont remplacées par les chaînes
0E0h et 90h avant assemblage.
00E0
0090
1
2
3
4
5
6
7
8
9
0000
0000 75E001
0003 759030
ACC EQU 0E0h
PORT1 EQU 90h
ORG 0000h
MOV ACC,#1
MOV PORT1,#30h
END
L’instruction MOV ACC,#1 correspond donc à l’instruction MOV 0E0h,#1 soit encore SFR[E0h] ppv
1, ce qui écrit la valeur 1 dans le registre SFR d’adresse E0h, c’est-à-dire l’accumulateur.
Il faut être prudent avec l’utilisation des équivalences car on peut aussi bien réaliser de l’adressage
immédiat que de l’adressage direct.
VAR1 EQU 11h
VAR2 EQU 12h
ORG
MOV
MOV
MOV
END
0000h
VAR1,#1
VAR2,#VAR1
R0,#VAR2
IRAM[11h] ppv 1
IRAM[12h] ppv #11h
R0 ppv #12h
Dans l’exemple précédent, si l’on remplace les chaînes par leurs équivalences on obtient
MOV 11h,#1
MOV 12h,#11h
MOV R0,#12h
IRAM[11h] ppv 1
IRAM[12h] ppv #11h
R0 ppv #12h
Pour la première instruction, l’opérande de gauche est en adressage direct, celui de droite est une
donnée immédiate.
Pour la seconde instruction, l’opérande de gauche est en adressage direct, celui de droite est une
donnée immédiate.
Pour la troisième instruction, l’opérande de droite est une donnée immédiate.
-19-
Directive END
Cette directive indique à l’assembleur qu’il doit arrêter l’assemblage. Cette directive est indispensable
pour certains assembleurs.
Directive ORG
Cette directive réalise un alignement du code sur une adresse particulière. Cette directive sera
notamment utilisée pour aligner les routines d’interruption sur des adresses précises.
Directive BIT
Cette directive permet la définition d’une adresse de bit.
BIT_B1
BIT_B2
BIT 00h
BIT 01h
ORG 0000h
SETB BIT_B1
CLR BIT_B2
BIT[00h] ppv 1
BIT[01h] ppv 0
Calcul des adresses de bits
Certains assembleurs, comme ASM51.exe (mais pas celui de TP, hélas !), prennent en charge le
calcul des adresses de bits à partir d’une information de type [Adresse octet].[Numéro Bit].
Par exemple, le programme source suivant est assemblé correctement avec l’assembleur ASM51.EXE.
PORT1
VAR
EQU 90h
EQU 20h
ORG 0000h
SETB 21h.2
CLR 90h.5
SETB PORT1.2
CLR VAR.7
MOV C,VAR.2
END
Le fichier de listage après assemblage donne
0090
0020
0000
0000 D20A
0002 C295
0004 D292
0006 C207
0008 A202
1
2
3
4
5
6
7
8
9
10
11
12
13
14
PORT1
VAR
EQU 90h
EQU 20h
ORG 0000h
SETB 21h.2
CLR 90h.5
SETB PORT1.2
CLR VAR.7
MOV C,VAR.2
END
-20-
La notation 21h.2 correspond à l’adresse du bit numéro 2 de l’octet d’adresse 21h, après calcul son
adresse est en réalité 0Ah (revoir le paragraphe sur l’espace d’adressage des bits si vous avez un doute).
On voit que l’assembleur autorise également les équivalences avant le calcul d’adresse bit.
L’instruction SETB PORT1.2 correspond aussi à SETB 90h.2 soit la mise à 1 du bit numéro 2 de l’octet
d’adresse 90h (bit numéro 2 du tampon de port 1).
-21-
3
Programmer les microcontrôleurs MCS51 en langage C
3.1
Le cross compilateur SDCC (Small Device C Compiler)
Différents compilateurs C sont désormais disponibles pour les microcontrôleurs. Il s'agit plus
exactement de cross-compilateurs puisque la source est compilée sur une machine (ici il s'agira d'un PC)
et le code machine généré est destiné à un processeur différent (ici, il s’agira du processeur intégré aux
microcontrôleurs de la famille 8051).
On présente ici quelques caractéristiques du compilateur SDCC (source et documentation
disponibles sur http://sdcc.sourceforge.net/). Il s'agit d'un compilateur sous licence GPL (General
Public License) capable de générer du code pour différents microcontrôleurs (noyau 51, zilog z80, PIC).
Après installation de SDCC, la compilation s'effectue sous forme de lignes de commandes. Par
défaut, SDCC compile les sources pour produire du code compatible avec le noyau 51.
Exemple : éditer un fichier source (fichier texte avec l'extension .c) et exécuter la commande SDCC
(avec éventuellement des options)
/* source test.*/
char test;
D:\>sdcc test.c
void main(void)
{
test=0;
}
Ce chapitre présente quelques exemples et introduit les spécificités liées au fait que la cible est le
noyau 51.
3.2
Variables : types et tailles
3.2.1
Types standard
Le langage source est du C. On peut donc gérer des variables ayant les types suivants.
type
taille
valeurs
char
1 octet
-128 à +127
unsigned char
1 octet
0 à 255
int/short
2 octets
-32768 à +32767
unsigned int
2 octets
0 à 65535
long
4 octets
-231 à 231-1
float
4 octets
± 1.18E-38 à ± 3.39E+38
Codage des floats : Signe = 1 bit Exp. = 8 bits Mant. = 23 bits, la valeur est : (-1)S* 2(Exp-127) * 1,Mant.
Il ne faut néanmoins pas oublier que le noyau 51 est un processeur 8 bits. Les opérations entières ou
réelles sur 16 ou 32 bits ne sont donc pas aisément réalisées par le processeur du microcontrôleur. Ces
opérations numériques sont réalisées par des sous-programmes (fonctions) dont l'exécution est assez
longue (entre 200 et 800 cycles). Il convient donc de choisir les types les mieux adaptés au problème à
résoudre, faute de quoi le code machine risque d'être très lent.
-22-
Exemple : on présente ci-dessous un fichier source où des variables de type char et float sont utilisées.
Le cadre de droite présente une partie du fichier .lst où figure le source et le langage d'assemblage. Le
produit sur 8 bits peut être fait facilement, en revanche le produit de réels est réalisé dans un sousprogramme.
0031 75*00 FD
#include<8051.h>
char c1,c2,c3;
float f1,f2,f3;
void main(void)
{
int i;
c1=-3;
c2=2;
f1=1.3;
f2=-3.5;
for(i=0;i<5;i++)
{
c3=c1*c2;
f3=f1*f2;
c1++;
f1++;
}
}
3.2.2
0034 75*01 02
0037
003A
003D
0040
...
75*03
75*04
75*05
75*06
66
66
A6
3F
0053
0055
0058
0059
E5*00
75 F0 02
A4
F5*02
005B
005E
0061
0064
0067
006A
006D
0070
0072
0074
0076
0079
007C
007F
0082
75*00 00
75*01 00
75*02 60
75*03 C0
85*03 82
85*04 83
85*05 F0
E5*06
C0 02
C0 03
12s00r00
85 82*0B
85 83*0C
85 F0*0D
F5*0E
268 ; c1=-3;
270
mov
271 ; c2=2;
273
mov
274 ; f1=1.3;
276
mov
277
mov
278
mov
279
mov
_c1,#0xFD
_c2,#0x02
_f1,#0x66
(_f1 + 1),#0x66
(_f1 + 2),#0xA6
(_f1 + 3),#0x3F
291 ;c3=c1*c2;
294
mov
a,_c1
295
mov
b,#0x02
296
mul
ab
297
mov
_c3,a
298 ; f3=f1*f2;
300
mov
___fsmul_PARM_2,#0x00
301
mov
(___fsmul_PARM_2 + 1),#0x00
302
mov
(___fsmul_PARM_2 + 2),#0x60
303
mov
(___fsmul_PARM_2 + 3),#0xC0
305
mov
dpl,_f1
306
mov
dph,(_f1 + 1)
307
mov
b,(_f1 + 2)
308
mov
a,(_f1 + 3)
309
push
ar2
310
push
ar3
311
lcall ___fsmul
312
mov
_f3,dpl
313
mov
(_f3 + 1),dph
314
mov
(_f3 + 2),b
315
mov
(_f3 + 3),a
Types liés au noyau 51 (extensions du C)
Le noyau 51 possède des caractéristiques d'espaces d'adressage (RAM interne, externe, mémoire
programme, zone d'adressage des bits) qui sont supportées par le compilateur SDCC à travers certaines
extensions. On peut par exemple indiquer dans quelle mémoire les variables doivent être stockées.
Storage class data
Les variables data sont stockées dans la RAM interne en accès direct.
#include<8051.h>
data unsigned char tst_data;
void main(void)
{
tst_data=2;
}
; tst_data=2;
0031 75*00 02
254
mov
_tst_data,#0x02
Storage class xdata
Les variables xdata sont stockées dans la mémoire de données externe.
#include<8051.h>
xdata unsigned char tst_xdata;
void main(void)
{
tst_xdata=2;
}
0031 90s00r00
0034 74 02
0036 F0
-23-
254
255
256
252 ; tst_xdata=2;
mov
dptr,#_tst_xdata
mov
a,#0x02
movx
@dptr,a
Storage class idata
Les variables idata sont stockées dans la Ram interne en accès indirect, ce qui permet d'exploiter les
128 octets supplémentaires de RAM interne des modèles 8032, 8052...
#include<8051.h>
252 ; tst_idata=2;
idata unsigned char tst_idata;
void main(void)
{
tst_idata=2;
}
0031 78r00
254
mov
r0,#_tst_idata
0033 76 02
255
mov
@r0,#0x02
Storage class code
Les variables code sont stockées dans la mémoire de programme. Dès lors, les instructions de lecture
de mémoire programme sont utilisées pour y accéder.
#include<8051.h>
253 ; var=tst_code;
code unsigned char tst_code=2;
data unsigned char var;
void main(void)
{
var=tst_code;
}
0031 90s00r39
255
mov
dptr,#_tst_code
0034 E4
256
clr
a
0035 93
257
movc
a,@a+dptr
0036 F5*00
258
mov
_var,a
Storage class bit/sbit/sfr
Les variables bit sont stockées dans la partie de la ram interne adressable par bit (la variable
test_bit). Les mots clé sbit et sfr permettent de décrire les registres sfr ou les bits accessibles
directement.
#include<8051.h>
bit test_bit;
sbit at 0x80 PORT0_0;
0031 A2 80
0033 B3
0034 92*00
sfr at 0x90 PORT1;
0036 D2 80
void main(void)
{
test_bit=!PORT0_0;
PORT0_0=1;
PORT1=0x0F;
}
0038 75 90 0F
254 ;test_bit=!PORT0_0;
256
mov
c,_PORT0_0
257
cpl
c
258
mov
_test_bit,c
259 ;PORT0_0=1;
261
setb
_PORT0_0
262 ; PORT1=0x0F;
264
mov
_PORT1,#0x0F
/* 8051.h*/
#ifndef REG8051_H
#define REG8051_H
Remarque : le fichier d'inclusion 8051.h réalise la déclaration
des registres SFR standard.
-24-
/*
sfr
sfr
sfr
sfr
sfr
...
BYTE Register */
at 0x80 P0
;
at 0x81 SP
;
at 0x82 DPL ;
at 0x83 DPH ;
at 0x87 PCON ;
3.3
Les fonctions : paramètres et variables locales
Lorsque les performances du processeur le permettent (par exemple dans le cadre du C pour
processeur PC-Intel), les variables locales aux fonctions, ainsi que les paramètres échangés avec les
fonctions, sont stockés dans la pile. Ceci a pour effet que la portée d'une variable locale se limite au bloc
de la fonction. En ce qui concerne le passage d'arguments, le fait de passer les paramètres par la pile
autorise les appels récursifs (fonction réentrante).
Dans le cadre du langage C pour les microcontrôleurs, en raison des performances moindres du
processeur et de la limitation de la taille de la pile, les variables sont par défaut stockées dans la RAM
interne et les paramètres sont passés par registre. Dès lors, par défaut, les fonctions ne peuvent pas être
récursives. Pour que les fonctions puissent être ré-entrantes, le mot clé reentrant doit être ajouté après
l'en-tête de la fonction.
#include<8051.h>
char fact(char val) reentrant;
void main(void)
{
char var=fact(4);
}
char fact(char val) reentrant
{
if(!val) return val*fact(val-1);
else return 1;
}
3.4
Assembleur inline
Il est possible d'écrire des portions de programme en langage d'assemblage au sein de sources en
langage C. C'est surtout intéressant pour optimiser certains sous-programmes. Pour écrire en langage de
bas niveau, il suffit de mettre les instructions entre _asm et _endasm;.
#include <8051.h>
data unsigned char var=58;
void main(void)
{
/* mise à 1 du bit 0 de var */
_asm
mov a,_var
setb ACC.1
mov _var,a
_endasm;
}
3.5
Les routines d'interruption
Remarque : cette partie peut être laissée de côté en première lecture. Il convient de comprendre d’abord
le système de gestion d’interruptions sur les microcontrôleurs de la famille MCS-51.
SDCC a prévu certaines extensions pour les sous-programmes liés aux interruptions, en particulier
pour indiquer à quel type d'interruption correspond le sous-programme (le nom n'est pas imposé).
L'entête et le prototype des routines d'interruption doivent seulement être suivis du mot clé interrupt
et du numéro d'interruption.
-25-
Pour les microcontrôleurs de la famille 8051, les numéros d’interruptions utilisés dans les sources en
langage C sont les suivants
n° 0 pour l’IT externe 0,
n°1 pour l’IT timer 0,
n°2 pour l’IT externe 1, …
c’est-à-dire dans le même ordre que celui du vecteur d’interruptions (voir chapitre sur les
interruptions).
On remarque sur l'exemple suivant que le code généré pour la routine d'interruption est très
important comparé au traitement nécessaire. En effet, tous les registres utilisés par le compilateur sont
empilés/dépilés à chaque interruption, même si dans ce cas précis seul A est utilisé.
#include <8051.h>
void InitTimer(void);
void InitIt(void);
void IT_Timer0(void) interrupt 1;
void main(void){
InitIt();
InitTimer();
while(1);
/* seule la routine
d'IT est exécutée*/
}
void InitTimer(void){
TMOD=0x02;
TH0=156;
TR0=1;
}
_IT_Timer0:
push
push
push
push
push
mov
mov
cpl
mov
pop
pop
pop
pop
pop
reti
acc
b
dpl
dph
psw
psw,#0x00
a,_P1
a
_P1,a
psw
dph
dpl
b
acc
void InitIt(void){
IE=0x82;
}
void IT_Timer0(void) interrupt 1
{
P1=~P1; /* complément bit
à bit du port P1*/
}
3.6
Le mot clé volatile et les fonctions "naked"
Le modificateur volatile signale au compilateur que la variable est susceptible d'être modifiée
localement par le programme mais aussi par des facteurs extérieurs, par exemple une routine
d'interruption. La déclaration d'une variable en tant que volatile avertit le compilateur de ne pas faire
d'hypothèses sur la valeur de la variable pendant l'évaluation des expressions dans lesquelles elle apparaît
car la valeur peut changer à tout moment. Les variables partagées entre le programme principal et les
interruptions doivent donc être déclarées volatile.
Par ailleurs, on a vu dans l'exemple précédent que le compilateur met en place par défaut un certain
nombre de sauvegardes pour les routines d'interruption. On peut préciser de ne pas le faire en indiquant
que l'on souhaite une version simplifiée (_naked). Dès lors, le programmeur est entièrement responsable
des sauvegardes à effectuer.
Dans le cas de programmes avec routines d'interruption, on peut rendre celles-ci plus rapide en les
écrivant complètement en langage de bas niveau. Par exemple, ci dessous, la routine d'interruption
-26-
modifie une variable déclarée volatile globale en RAM (volatile data unsigned char
varCommune;).
void IT_Timer0(void) interrupt 1 _naked
{
_asm
push ACC
mov a,_varCommune
cpl a
mov _varCommune,a
pop ACC
reti
_endasm;
}
L'application complète est la suivante.
#include <8051.h>
void InitItTimer(void);
void IT_Timer0(void) interrupt 1 _naked;
volatile data unsigned char varCommune;
void main(void)
{
InitItTimer();
/*lecture de la variable modifiée dans l'IT Timer 0*/
while(1) P1=varCommune;
}
void InitItTimer(void)
{
TMOD=0x02;
TH0=156;
TR0=1;
IE=0x82;
}
void IT_Timer0(void) interrupt 1 _naked
{
_asm
push ACC
mov a,_varCommune
cpl a
mov _varCommune,a
pop ACC
reti
_endasm;
}
3.7
Plusieurs fichiers source
Lorsqu'un seul fichier source contient la fonction main ainsi que les sous-programmes, la
commande SDCC réalise la compilation du fichier puis l'édition des liens (link). Lorsqu'une application
est répartie dans différents fichiers, la commande SDCC ne peut compiler qu'un seul fichier source à la
fois. Il faut donc compiler chacun des fichiers puis réaliser les liens (toujours avec SDCC).
-27-
/* fonction.c*/
#include<8051.h>
/*main.c*/
#include <8051.h>
void InitItTimer(void)
{
TMOD=0x02;
TH0=156;
TR0=1;
IE=0x82;
}
void InitItTimer(void);
volatile data unsigned char varCommune;
void main(void)
{
InitItTimer();
while(1) P1=varCommune;
}
void IT_Timer0(void) interrupt 1
{
varCommune++;
}
Dans ce cas, les commandes à exécuter sont les suivantes :
- compilation des deux fichiers sources (option -c compilation sans linkage). La compilation crée
deux fichiers objet (extension .rel)
- utilisation de sdcc pour réaliser les liens. La commande prend en entrée les fichiers objet .rel.
Le fichier contenant le code de la fonction main() doit être le premier argument de la commande.
D:> sdcc -c fonction.c
D:> sdcc -c main.c
D:> sdcc main.rel fonction.rel
3.8
Simulation et génération du fichier .hex (pour programmation des mémoires)
La compilation de source.c fournit plusieurs fichiers en sortie :
-source.asm : source en langage d'assemblage créé par le compilateur
- source.lst : source en langage d'assemblage + code machine
- source.rst : fichier .lst mis à jour par le linker
- source.rel ou source.o : fichier objet utilisé en entrée du linker
- source.ihx : le module au format Intel hex.
Le simulateur JSIM (disponible à http://home.t-online.de/home/Jens.Altmann/jsim-e.htm) peut
utiliser le fichier .ihx comme entrée, à la condition d'avoir compilé le programme avec l'option -debug.
D:> sdcc --debug main.c
Remarque : on peut également utiliser l'éditeur JFE (Jens Altmann File Editor) pour éditer et lancer la
compilation d'un fichier source.
-28-
Génération du fichier hex : le fichier .ihx n'est pas au bon format pour les programmateurs de
mémoire. On doit donc utiliser la commande packihx pour convertir dans le format .hex
D:> packihx fic.ihx>fic.hex
-29-
4
Les ports E/S des microcontrôleurs MCS51.
On va étudier ici la structure interne et la programmation des ports E/S des microcontrôleurs de la
famille MCS51.
4.1
Structure du Port P1
Le schéma de principe d’un bit du port P1 est le suivant. Le port P1 au complet reproduit ce schéma
pour les 8 lignes P1.0 à P1.7.
Les tampons de bits du port P1 sont des bascules D. Les micro-commandes gérant le port sont
-
Ecriture du tampon : entrée D de la bascule
-
Lecture du tampon : buffer à sortie 3 états.
-
Lecture de la broche : buffer à sortie 3 états.
Le signal de lecture du tampon place la sortie de la bascule D sur le bus de données interne au
microcontrôleur. Le niveau logique des broches P1.x du microcontrôleur sont lus sur le signal « Lecture
broche ». Le niveau logique de la sortie de la bascule D est mis sur le bus interne sur le signal « Lecture
tampon ».
Certaines instructions conduisent à une lecture du tampon, d’autres à une lecture de la broche.
Pourquoi ?
Les ports E/S sont bidirectionnels, et il n’est pas toujours très fiable de lire l’état d’une sortie en
prélevant le niveau de la broche. En effet, le niveau logique de la broche du circuit intégré dépend de la
charge qui lui est appliquée.
Par exemple, si la broche du port est dans l’état 1, et si elle est reliée à la base d’un transistor
bipolaire, il est possible que le potentiel de cette broche soit proche de 0,7 V, ce qui sera interprété
comme un niveau logique 0 !
-30-
Par conséquent, lorsque le port est utilisé en sortie, le tampon du port (la bascule D) tient lieu de
mémoire de l’état d’une sortie, et c’est le tampon que l’on doit lire pour connaître l’état d’une sortie.
Certaines instructions lisent le tampon de port, d’autres l’état de la broche.
Les instructions qui lisent ou modifient le tampon du port sont :
ANL
ORL
XRL
JBC
CPL
SETB Px.x
INC
DEC
DJNZ
MOV Px.x,C
CLR Px.x
Les autres instructions lisent l’état de la broche.
Exemple : lorsque l’instruction suivante est exécutée
PORT3 EQU 0B0h
ANL PORT3,#01
l’opération réalisée ne concerne que le registre. Les broches du port ne sont pas lues. Pour réaliser la
même opération à partir des niveaux présents sur les broches, on doit exécuter
MOV A,PORT3
ANL A,#01
Utilisation d’un port E/S comme port d’entrée
On obtient la valeur logique d’une entrée en lisant le niveau de la broche du microcontrôleur. Il est
donc nécessaire que la sortie /Q de la bascule soit à 0 pour lire un niveau correct sur la broche. Lorsque
la sortie /Q est à 1, le transistor entre le broche et la masse est passant et le niveau lu sur la broche est
alors systématiquement 0.
D’ailleurs, durant la phase d’initialisation du microcontrôleur, les registres de tampon de port P0 à P3
sont initialisés avec la valeur FFH, pour que ces ports puissent être utilisés comme ports d’entrée.
4.2
Structure du port P0
Le port P0 peut être soit un port E/S 8 bit, soit un bus 8 bits multiplexé [A0-A7]/[D0-D7] lorsque le
microcontrôleur exploite une mémoire de programme et/ou une mémoire de données externe.
Lorsque qu’utilisé comme port de sortie, on doit ajouter des résistances de pull-up externes. En effet,
la résistance de pull-up interne n’est active qu’en mode bus adresses/données.
-31-
5
Les Timers de la famille MCS51
Les microcontrôleurs de la famille MCS51 possèdent 2 (8031, 8051) ou 3 timers (8032, 8052).
Chaque timer est doté d’un compteur 16 bits accessible sous la forme de 2 registres 8 bits situés dans
l’espace SFR.
Pour les timers 0 et 1, les compteurs 16 bits sont stockés dans les registres TH0/TL0 et TH1/TL1.
TH0
TL0
TH1
TL1
(SFR[8Ch])
(SFR[8Ah])
(SFR[8Dh])
(SFR[8Bh])
:
:
:
:
8
8
8
8
bits
bits
bits
bits
forts du timer 0
faibles du timer 0
forts du timer 1
faibles du timer 1
La configuration de ces timers est réalisée via les registres TMOD (modes de fonctionnement) et
TCON (contrôle).
TMOD (SFR[89h]) : modes de fonctionnement des timers 0 et 1
TCON(SFR[88h]) : contrôle des timers 0 et 1
5.1
Les fonctions des timers MCS51
Un timer peut assurer deux fonctions distinctes
Le comptage : dans cette fonction, le compteur 16 bits est incrémenté sur la détection d’événements
extérieurs. Les événements comptés sont des fronts descendants sur la broche T0 (P3.4) pour le compteur
0 et sur la broche T1 (P3.5) pour le compteur 1.
T0 (P3.4) : entrée de comptage du timer 0
T1 (P3.5) : entrée de comptage du timer 1
La temporisation : dans sa fonction temporisation, le timer compte des cycles machine. C’est donc
l’oscillateur du microcontrôleur qui fournit la base de temps. On rappelle d’ailleurs que pour un quartz
de 12MHz, un cycle machine dure 1 micro seconde.
5.2
Modes de fonctionnement
Les temporisateurs disposent de plusieurs modes de fonctionnement. L’explication de ces modes est
plus simple par l’intermédiaire de schémas où sont représentés tous les paramètres de configuration des
timers.
Le premier schéma représente le fonctionnement des timers 0 ou 1 en mode 0.
SFR[89h]
GATE C/T M1
TMOD
SFR[88h]
M0 GATE C/T M1
M0
TF1
TCON
TR1 TF0 TR0 IE1
adressable
Osc
÷12
IT1 IE0 IT0
par
bit
TCON.5
C/T=0(TMOD.2)
TL0
TH0
TF0
(5
(P3.4)
(TCON.4)
bits)
(8
bits)
C/T=1
T0
TR0
&
(TMOD3)
(P3.2)
GATE
≥1
Timer 0 en mode 0 (M1= M0= 0)
/INT0
-32-
interruption
Le second schéma représente le fonctionnement du mode 1.
SFR[89h]
GATE C/T M1
TMOD
SFR[88h]
M0 GATE C/T M1
M0
TF1
TCON
TR1 TF0 TR0 IE1
adressable
÷12
Osc
IT1 IE0 IT0
par
bit
TCON.5
C/T=0(TMOD.2)
TL0
TH0
TF0
(8
(P3.4)
(TCON.4)
bits)
(8
bits)
interruption
C/T=1
T0
TR0
&
(TMOD3)
(P3.2)
GATE
≥1
Timer 0 en mode 1 (M1= 0 M0= 1)
/INT0
Le schéma suivant représente le fonctionnement d’un timer en mode 2.
SFR[89h]
GATE C/T M1
TMOD
SFR[88h]
M0 GATE C/T M1
M0
TF1
TCON
TR1 TF0 TR0 IE1
adressable
Osc
÷12
IT1 IE0 IT0
par
bit
TCON.5
C/T=0(TMOD.2)
TL0
TF0
(8
(P3.4)
(TCON.4)
interruption
bits)
C/T=1
T0
TR0
rechargement
&
TH0
(TMOD3)
(P3.2)
GATE
≥1
(8
bits)
Timer 0 en mode 2 (M1= 1 M0= 0)
/INT0
On voit que la fonction compteur ou temporisateur est sélectionnée en positionnant le bit C/T
(TMOD.2 pour timer 0 et TMOD.7 pour timer 1) soit à 0 pour la fonction temporisateur, soit à 1 pour
la fonction compteur de fronts descendants sur la broche Tx (P3.4 ou P3.5).
Ensuite, l’activation du comptage ou de la temporisation dépend
-
du bit TRx (TCON.4 ou TCON.6 selon timer)
et, si le bit GATE (TMOD.3 ou TMOD.7 selon timer) est à 1
-
du niveau de la broche /INTx (P3.2 ou P3.3)
Lorsque le bit GATE est à 1, l’activation du compteur dépend à la fois du bit TRx et de la présence
d’un niveau 1 sur la broche /INTx. On peut ainsi contrôler le comptage ou la temporisation par un
signal extérieur appliqué à la broche /INTx.
Remarque : en fonction compteur, la broche Tx n’est lue qu’une fois par cycle machine. Il faut donc
deux cycles pour détecter un front descendant sur cette broche. Par conséquent, la fréquence maximale
du comptage sur une broche Tx est la fréquence de l’oscillateur divisée par 24.
On a donné 3 modes de fonctionnement. Il y en a un quatrième qui bloque le timer 1 mais permet
d’avoir deux compteurs 8 bits à partir des registres TH0 et TL0. Le compteur de registre TL0 est alors
contrôlé par les bits de contrôle normalement attribués au timer 0 et le compteur de registre TH0 est
contrôlé par les bits de contrôle normalement attribués au timer 1.
-33-
En mode 0, les timers 0 et 1 sont des compteurs 13 bits. En mode 1, les timers sont des compteurs 16
bits et en mode 2, les timers sont des compteurs 8 bits à rechargement automatique (THx est écrit dans
TLx).
5.3
Utilisation des timers 0 et 1
En fonction compteur ou temporisateur, un timer incrémente son registre compteur, soit sur occurrence
d’un front descendant sur la broche Tx (fonction compteur), soit à chaque cycle machine (fonction
temporisateur).
Lorsqu’il y a débordement du registre compteur, par exemple lors du passage de FFFFh à 0000h dans le
cas d’un comptage 16 bits, le bit TFx (Timer Flag) situé dans le registre TCON est mis à 1 par le
processeur. De plus, un signal d’interruption est généré par le timer.
Supposons que l’on souhaite exploiter le timer 0 comme temporisateur 16 bits. Après avoir chargé une
valeur dans TH0/TL0 et après avoir activé le timer0 (TR0=1), on connaîtra la fin de la temporisation
soit en scrutant le bit TF0 (TCON.4) soit en exploitant le signal d’interruption (voir chapitre suivant).
Exemple de configuration et d’utilisation du timer 0 en temporisateur 16 bits
On va donner un exemple de programme utilisant le timer 0 en temporisateur 16 bits. On suppose que
l’oscillateur a une fréquence de 12 MHz. On cherche à créer un sous-programme réalisant une
temporisation de 10 milli secondes.
Mot de configuration : TMOD = (x x x x 0 0 0 1)b
(Timer 0 en temporisateur 16 bits)
Puisque GATE=0, le timer 0 est activé quand TR0 = 1.
La fin de la temporisation a lieu lorsque TF0 passe à 1.
Si l’on souhaite une temporisation de M cycles de 1 micro seconde, puisque le timer 0
incrémente son registre, il faut mettre 65 536 – M dans le registre initialement pour que le débordement
ait lieu après M cycles. Dans notre exemple, on doit mettre 65536 – 10000 dans le registre 16 bits avant
de lancer le timer, c’est-à-dire 55536 = (D8F0)h.
---------------------------------------------------------------TH0 EQU 8Ch
; adresse de TH0
TL0 EQU 8Ah
; adresse de TL0
TMOD EQU 89h
; adresse de TMOD
TCON EQU 88h
; adresse de TCON
TR0 BIT TCON.4
; adresse du bit TR0
TF0 BIT TCON.5
; adresse de l’indicateur de débordement
…
MOV TMOD,#1 ; timer0 en temporisateur 16 bits
CALL TEMPO
;(2 cycles) appel du sous-programme
…
TEMPO:
CLR TF0
(1 cycle)
CLR TR0
(1 cycle)
MOV TH0,#0D8h
(2 cycles)
MOV TL0,#0F0h
(2 cycles)
SETB TR0
(1 cycle)
bcle:
JNB TF0,bcle
RET
(1 cycle)
end
----------------------------------------------------------------
-34-
En réalité, le sous programme TEMPO dure 10 micro secondes de plus en raison du temps
d’appel CALL et des instructions CLR, MOV, SETB et RET. On peut donc ajuster la valeur chargée dans
le compteur pour que la temporisation soit plus précise.
TEMPO:
CLR TF0
CLR TR0
MOV TH0,#0D8h
MOV TL0,#0FAh
SETB TR0
bcle:
JNB TF0,bcle
RET
5.4
(1
(1
(2
(2
(1
cycle)
cycle)
cycles)
cycles)
cycle)
(1 cycle)
Le timer 2
Les microcontrôleurs 8052 possèdent un troisième timer noté timer 2. C’est un compteur 16 bits qui
peut fonctionner en compteur d’événements ou en temporisateur. Il est contrôlé par le registre T2CON
(SFR[C8h]).
Si besoin, on trouve la description de la configuration et du fonctionnement de ce timer dans la
documentation constructeur.
-35-
6
Le gestionnaire d’interruptions de la famille MCS51
Les microcontrôleurs de la famille MCS51 possèdent 5 sources d’interruption, et le 8052 en possède
une 6ième provenant du timer supplémentaire (timer 2).
Les sources d’interruption sont
• 2 sources d’interruption externes sur les broches /INT0 (P3.2) et /INT1(P3.3)
• 2 sources d’interruption Timer 0 et Timer 1 (sur débordement des registres)
• 1 source d’interruption Port Série
• 1 source d’interruption Timer 2 (pour le 8052 uniquement)
Toutes ces sources d’interruption sont masquables, c’est-à-dire autorisables ou non par logiciel. Lors
de l’initialisation du microcontrôleur, toutes ces sources sont inhibées.
6.1
Mécanisme de gestion des interruptions
Les microcontrôleurs MCS51 possèdent un contrôleur d’interruptions intégré. Le mécanisme
d’interruption est dit vectorisé sur adresse fixe. Autrement dit, une zone de la mémoire de programme est
dédiée au service de gestion des interruptions.
Occupation de l’espace mémoire programme
Après la phase d’initialisation du microcontrôleur, l’adresse 0000h est chargée dans le pointeur
d’instruction PC. Le microcontrôleur exécute donc l’instruction située à l’adresse 0000h. Mais, la zone
inférieure de l’espace programme, à partir de l’adresse 0003h, est dédiée au service des interruptions.
0000h
RESET
0003h
IT externe 0
(/INT0)
000Bh
IT timer 0
0013h
IT externe 1
(/INT1)
001Bh
IT timer 1
0023h
IT série
Il y a une adresse fixe par service d’interruption. Dans l’hypothèse où toutes les sources
d’interruption sont exploitées, il y a 8 octets de mémoire destinés à recevoir le début de chaque service
d’interruption.
Principe
Si une source d’interruption donnée est autorisée, l’interruption provoque un saut à l’une des
adresses décrites ci-dessus. Par exemple, dans le cas où l’interruption timer 0 est autorisée, un
débordement du timer 0 va provoquer un saut à l’adresse 000Bh.
Remarque : si aucune interruption n’est utilisée, la zone mémoire [0003h-0033h] peut être librement
utilisée par le logiciel.
-36-
Chaque service d’interruption dispose de 8 octets. Si cet espace est insuffisant pour traiter
complètement l’interruption, on place dans ces 8 octets une instruction de saut pour poursuivre le
traitement du service d’interruption à une autre adresse de la mémoire.
Puisque le microcontrôleur commence l’exécution à partir de l’adresse 0000h, on remarque que seuls
3 octets permettent d’accueillir une instruction de saut, pour passer au delà de la zone de traitement des
interruptions. Un programme exploitant une source d’interruption débute généralement par
l’instruction LJMP (instruction de saut long qui occupe 3 octets) située à l’adresse 0000h. Ce saut
désigne des instructions situées au delà de la zone d’interruption.
0000h
LJMP debut
0003h
services d'IT
debut:
programme
principal
Exécution d’une interruption sur MCS51
Si le processeur accepte une interruption, celle-ci provoque un saut au sous-programme de service
correspondant à la source (adresse 0003h pour /INT0, 000Bh pour timer 0 etc.).
Le saut est comparable à une instruction CALL :
-
il y a sauvegarde sur la pile de l’adresse de retour au programme interrompu
-
un indicateur est positionné pour signaler le déroulement d’une interruption
Le retour depuis une routine d’interruption
-
est fait grâce à l’instruction RETI (Interrupt Return), celle-ci récupère sur la pile l’adresse où
le processeur doit reprendre l’exécution après traitement de l’interruption
-
nettoie l’indicateur interne d’interruption pour signaler que le traitement de l’interruption
est terminé et que le processeur pourra traiter une autre interruption.
Attention : à la différence d’un processeur plus évolué (comme le 8086), il n’y a pas sauvegarde
automatique des indicateurs. Si besoin, il est nécessaire de prendre en charge, dans la routine de
traitement d’interruption, la sauvegarde et le restitution du registre d’état (PSW) via la pile.
6.2
Implantation logicielle en cas de gestion d’interruptions pour la famille MCS51
On donne ici la structure d’un programme qui exploite 2 sources d’interruption, l’interruption timer
1 (001Bh-0022h) et l’interruption série (0023h-002Ah).
Une implantation possible est la suivante :
ORG 0000h
LJMP debut_prog
Alignement sur l’adresse 001Bh, qui est le
début de la routine d’IT Timer1
ORG 001Bh
PUSH PSW
PUSH ACC
LJMP IT_TIMER1
-37-
ORG 0023h
PUSH PSW
PUSH ACC
LJMP IT_SERIE
La routine d’IT Timer1 se poursuit ici.
IT_TIMER1:
; instructions de la routine
; d’interruption timer 1
POP ACC
POP PSW
RETI
IT_SERIE:
; instructions de la routine
; d’interruption série
POP ACC
POP PSW
RETI
Le programme principal commence ici, grâce au
saut LJMP debut_prog.
debut_prog :
; programme principal
6.3
Autorisation et priorité des interruptions
Après l’initialisation du microcontrôleur, toutes les interruptions sont inhibées. Leur validation et
leur priorité sont gérées via des registres particuliers de l’espace SFR.
Validation des interruptions
Chacune des sources d’interruption peut être validée ou invalidée individuellement en activant ou
désactivant un bit dans le registre IE (Interrupt Enable SFR[A8h]).
IE (SFR[A8h])
EA
-
- ES ET1 EX1 ET0 EX0
Chaque bit du registre IE permet d’activer ou non l’interruption qui lui est associée. Si le bit est à 1,
l’interruption est validée, si le bit est à 0 l’interruption est inhibée.
EX0 (IE.0) : bit de validation de l’interruption externe 0
EX1 (IE.2) : bit de validation de l’interruption externe 1
ET0 (IE.1) : bit de validation de l’interruption timer 0
ET1 (IE.3) : bit de validation de l’interruption timer 1
ES (IE.4) : bit de validation de l’interruption série
EA (IE.7) : bit de validation générale. Si EA=0, elles sont toutes inhibées, sinon seules celles dont le
bit est à 1 sont actives.
-38-
Exemple de programmation du contrôleur d’interruptions :
IE EQU 0A8h
EA BIT IE.7
MOV IE,#0001 0001b
SETB EA
; masque d’IT. Prépare la prise en compte de
l’IT
; externe 0 et de l’IT série
; active les IT
Priorité des interruptions
Chaque source d’interruption bénéficie d’un niveau de priorité parmi deux valeurs. Le niveau de
priorité de chaque source est déterminé par le contenu du registre IP (IT priority).
Une interruption de faible priorité peut être interrompue par une source d’interruption de plus forte
priorité, mais pas par une source de même niveau de priorité.
Si deux demandes sont simultanées (ce qui est possible car les demandes ne sont prises en compte
qu’une fois par cycle)
-
celle de niveau de priorité le plus élevé est prioritaire
-
si les deux sont de même niveau, l’ordre de priorité est déterminé par une scrutation dans
l’ordre IT ext. 0 (plus prioritaire) , IT Timer 0, IT ext. 1, IT Timer 1, IT série (moins
prioritaire).
IP (SFR[B8h])
-
-
- PS PT1 PX1 PT0 PX0
IP.0 (PX0) : priorité de la source d’interruption externe 0
IP.1 (PT0) : priorité de la source d’interruption timer 0
IP.2 (PX1) : priorité de la source d’interruption externe 1
IP.3 (PT1) : priorité de la source d’interruption timer 1
IP.4 (PS) : priorité de la source d’interruption série
Le fonctionnement du contrôleur d’interruptions se résume par le schéma suivant :
-39-
6.4
Sources d’interruption externes
Les interruptions externes 0 et 1 dépendent des signaux appliqués aux broches /INT0 (P3.2) et /INT1
(P3.3). On peut programmer le microcontrôleur pour que l’événement déclencheur des interruptions
externes soit la détection d’un niveau bas sur la broche /INTx ou la détection d’un front descendant sur
la broche /INTx.
Le choix entre ces deux modes d’interruption est réalisé par positionnement des bits ITx du registre
TCON (SFR[88h]).
SFR[88h]
TF1
TR1 TF0 TR0 IE1
adressable
TCON
IT1 IE0 IT0
par
bit
IT0 (TCON.0) : bit de sélection du type d’interruption externe 0.
IT0 = 0 : interruption sur niveau bas sur la broche /INT0 (P3.2)
IT0 = 1 : interruption sur front descendant sur la broche /INT0
IT1 (TCON.2) : bit de sélection du type d’interruption externe 1.
IT1 = 0 : interruption sur niveau bas sur la broche /INT1 (P3.3)
IT1 = 1 : interruption sur front descendant sur la broche /INT1
L’état des sources d’interruption externes est signalé par les sémaphores IE0 (TCON.1) et
IE1(TCON.3). En début de routine d’interruption, le processeur met le sémaphore correspondant à 1
pour signaler l’exécution de la routine.
ATTENTION : lorsque l’interruption externe est programmée pour s’exécuter sur front descendant, le
processeur nettoie lui-même le sémaphore IE0 ou IE1 à la fin de la routine d’interruption. En revanche,
si l’interruption externe est programmée pour avoir lieu sur détection d’un niveau bas, c’est à la charge
de la routine d’interruption de signaler quand la routine se termine. Il faut alors prévoir de remettre le
sémaphore IE0 ou IE1 à 0 en fin de routine, sans quoi le processeur ne reprendra jamais en compte cette
interruption.
6.5
Sources d’interruption timer
Les timers génèrent des signaux d’interruption lorsque les flags TFx (TF0=TCON.5 et TF1=TCON.7)
passent à 1.
Nous avons vu que lorsque l’on utilise les timers sans exploiter les interruptions, on doit remettre le
bit TFx à 0 une fois que le débordement du timer est détecté.
Lorsque l’on exploite les sources d’interruption timer, en fin de routine de traitement de
l’interruption timer, le processeur nettoie automatiquement le flag TFx pour qu’un signal d’interruption
ait lieu au prochain débordement du timer.
6.6
Programme complet exploitant des interruptions (Famille MCS-51)
Pour ce programme, la source d’interruption exploitée est un front négatif sur la broche /INT0
(P3.2). Le programme recopie en binaire sur le port P1, le nombre de fronts négatifs détectés sur l’entrée
d’interruption /INT0.
Le montage est le suivant : un bouton poussoir est connecté à l’entrée d’interruption externe 0.
Chaque appui va générer un front descendant sur la broche /INT0 (la cellule RC filtre les rebonds). Les
8 LEDS représentent en binaire le nombre d’appuis sur le bouton poussoir.
-40-
1
2
3
4
5
6
7
8
9
18
17
16
15
14
13
12
11
ULN2803
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
VCC
10
Le montage :
31
30
29
9
21
22
23
24
25
26
27
28
80C51FA
Le programme :
; definition des symboles
debut equ
P1
PSW
ACC
IE
TCON
IT0
EA
equ
equ
equ
equ
equ
bit
bit
0000h
90h
0D0h
0E0h
0A8h
88h
TCON.0
IE.7
;
;
;
;
PORT1
mot d’état
A
registre de validation des IT
; choix du type d’IT sur INT0 (niveau/front)
; validation générale des IT
; variables du programme
NbA equ
00h
; variable IRAM[00h]: nombre de fronts sur /INT0
; structure du programme
ORG debut
LJMP debut_prog
; vecteur d’interruptions
ORG debut+3h
PUSH PSW
PUSH ACC
LJMP IT_EXT0
; programme principal
debut_prog: MOV NbA,#0
CALL Config_it
sans_fin:
MOV P1,NbA
JMP sans_fin
-41-
; procédure de préparation du gestionnaire d’interruptions
Config_it: CLR EA
MOV IE,#01h
; autorise IT externe 0 seulement
SETB IT0
; IT sur front négatif sur /INT0
SETB EA
RET
; routine de traitement de l’interruption externe 0
IT_EXT0:
INC NbA
POP ACC
POP PSW
RETI
END
Remarque : lorsque l’interruption externe 0 a lieu sur un front négatif, le drapeau IE0 (TCON.1)
est remis à 0 par le processeur. Il est donc inutile de le faire en fin de routine dans ce cas.
-42-
7
Mise en œuvre des microcontrôleurs MCS51
Dans ce chapitre, on va étudier des circuits standards à base de microcontrôleurs de la famille
MCS51 en expliquant les fonctions principales du circuit.
On donne tout d’abord le brochage des microcontrôleurs MCS51 en boîtier PLCC44 ou DIP 40.
7.1
L’oscillateur
Le fonctionnement d’un microprocesseur est toujours cadencé par un circuit d’horloge. On se
rappelle en effet que l’exécution d’une opération élémentaire d’un processeur (lecture/écriture d’une
donnée mémoire, opération arithmétique…) nécessite toujours l’exécution de plusieurs micro
commandes successives et invisibles depuis l’extérieur. Ces micro commandes évoluent au rythme d’un
signal périodique (l’horloge).
Pour la plupart des microcontrôleurs, une partie du circuit oscillateur est interne au circuit intégré. Il
ne reste ensuite qu’à ajouter un élément externe, comme un quartz ou un résonateur céramique voire
même simplement une cellule RC (pour les PIC), pour que l’oscillateur fonctionne. Puisque le
résonateur est externe, on peut en choisir la fréquence, dans une limite maximale donnée par le
constructeur, en l’accordant au besoin du cahier des charges.
Par exemple, si le temps n’est pas une grandeur critique, on a parfois intérêt à diminuer la fréquence
de l’oscillateur. En effet, pour les technologies à base de transistors MOS qui sont certainement les plus
répandues, la consommation électrique a lieu essentiellement lors des commutations des transistors.
Aussi, en diminuant la fréquence de l’oscillateur, on diminue également la consommation du circuit, ce
qui peut être intéressant pour des circuits fonctionnant sur batteries.
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
31
30
29
9
21
22
23
24
25
26
27
28
80C51FA
La figure précédente montre le montage préconisé par le constructeur pour un microcontrôleur
80C51FA (se reporter aux documentations constructeurs pour les valeurs exactes). Le microcontrôleur
dispose en interne d’un étage inverseur auquel est relié le quartz via les broches XTAL1 et XTAL2.
Remarque : on peut également utiliser un signal périodique externe que l’on connecte à l’entrée
XTAL1 (voir documentation constructeur en cas de besoin).
-43-
7.2
Entrée RST (reset)
Après mise sous tension, le microcontrôleur doit réaliser une phase d’initialisation interne,
notamment d’un certain nombre de registres (IP, SP, tampons de ports etc) . Cette initialisation doit
avoir lieu alors que l’oscillateur est déjà stable.
L’initialisation du microcontrôleur se fait en maintenant suffisamment longtemps son entrée RESET
(actif à l’état haut) au niveau haut. L’entrée RST dispose d’un trigger de Schmitt, il suffit donc d’ajouter
une cellule RC bien dimensionnée pour que l’initialisation du microcontrôleur se fasse correctement. Là
encore, la constante de temps (RC) est fournie dans la documentation constructeur. L’initialisation doit
durer 24 cycles oscillateur après que l’oscillateur soit stabilisé.
10
11
12
13
14
15
16
17
19
18
FREQ=12MHz
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
VCC
1
2
3
4
5
6
7
8
31
30
29
9
21
22
23
24
25
26
27
28
80C51FA
7.3
Les entrées-sorties parallèles
L’utilisation des ports entrée/sortie des microcontrôleurs est très simple mais doit faire l’objet de
quelques précautions.
Les sorties
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
NPN
19
18
39
38
37
36
35
34
33
32
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
31
30
29
9
21
22
23
24
25
26
27
28
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
XTAL1
XTAL2
VCC
Compte tenu des technologies utilisées, les ports entrées-sorties ne peuvent fournir ou absorber que
des courants de très faibles valeurs. Aussi, ces courants sont-ils parfois insuffisants pour allumer une
simple LED, ce qui est le cas pour les microcontrôleurs de la famille MCS51. Dans ce cas, la commande
d’une LED peut être obtenue à l’aide d’un montage à transistor bipolaire comme le montre la figure
suivante.
80C51FA
1
2
3
4
5
6
7
8
9
18
17
16
15
14
13
12
11
ULN2803
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
80C51FA
-44-
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
31
30
29
9
21
22
23
24
25
26
27
28
VC C
10
Lorsqu’on veut reproduire ce même montage pour 8 sorties parallèles, par exemple l’ensemble du
port P1, on peut utiliser un composant référencé ULN2803 qui n’est rien d’autre qu’un ensemble de 8
montages Darlington dans un même boîtier.
Les entrées
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
FREQ=12MHz
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
VCC
En ce qui concerne les entrées parallèles, il est important de savoir qu’en technologie MOS, une
entrée en l’air est à un état indéterminé. La connexion d’interrupteurs ou de boutons poussoirs doit se
faire avec des résistances de tirage (« pull-up »).
31
30
29
9
21
22
23
24
25
26
27
28
80C51FA
Lorsque l’interrupteur (ou le bouton poussoir) est ouvert, la résistance tire le potentiel de l’entrée vers
le niveau logique haut, lorsque l’interrupteur est fermé, le niveau de l’entrée est alors 0.
On peut permuter l’interrupteur et la résistance mais, dans certaines technologies, les entrées
consomment plus lorsqu’elles sont à l’état bas. On choisira donc plutôt cette solution, même si l’on lit
un niveau 0 sur la broche lorsque l’interrupteur est fermé.
Les rebonds
Il faut avoir à l’esprit que pour les interrupteurs et les boutons poussoirs, des phénomènes de
rebonds ont lieu lors des changements d’état. Aussi, lorsque l’on scrute l’état d’un bouton poussoir, on
doit séparer deux lectures successives de plusieurs millièmes de secondes pour avoir une image fiable de
l’état (ouvert ou fermé) du contact. Par exemple, l’ouverture ou la fermeture d’un contact suit le
chronogramme suivant. La phase transitoire dure quelques dizaines de milli-secondes.
Les claviers
Lorsque beaucoup de boutons poussoirs doivent être lus, il peut sembler pénalisant d’occuper autant
d’entrées du microcontrôleur qu’il y a de boutons poussoirs à lire. Si le microcontrôleur dispose de
ports bidirectionnels, on peut utiliser des techniques différentes pour limiter le nombre de broches
occupées.
Une possibilité est de réaliser une matrice où chaque bouton du clavier va réaliser un contact entre
une ligne et une colonne. Sur le montage suivant, on montre l’exemple d’un clavier 9 boutons, disposé
en matrice 3 lignes/3 colonne. Au lieu d’utiliser 9 lignes d’entrées, le montage n’utilise que 6 lignes
bidirectionnelles.
Dans la situation où aucun bouton n’est enfoncé, si l’on lit toutes les lignes et colonnes comme des
entrées, le microcontrôleur voit un niveau 1 sur chacune des broches P1.0 à P1.5.
Quand un bouton est enfoncé, il y a alors 2 façons de lire le clavier.
Première méthode. On applique/on écrit un niveau bas sur toutes les colonnes (P1.3 à P1.5) et on
lit les lignes (P1.0 à P1.2). En lisant les lignes, on va voir un niveau bas dans une ligne, celle dont
dépend le bouton enfoncé. Ensuite, on inverse les rôles. On applique un niveau bas sur les lignes (P1.0 à
P1.2) et on lit les colonnes (P1.3 à P1.5). On va lire un niveau bas dans une colonne, celle dont dépend
le bouton enfoncé.
-45-
10
11
12
13
14
15
16
17
FREQ=12MHz
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
VCC
1
2
3
4
5
6
7
8
31
30
29
9
21
22
23
24
25
26
27
28
80C51FA
Pour cet exemple, si l’on obtient le jeu de valeurs suivant
Valeurs écrites
P1.3
0
P1.4
0
Valeurs lues
P1.5
0
P1.0
1
P1.2
0
P1.3
1
Valeurs écrites
P1.0
0
P1.1
0
P1.1
0
P1.2
1
Valeurs lues
P1.4
1
P1.5
0
on déduit que le bouton enfoncé est à l’intersection de la ligne P1.1 et de la colonne P1.5.
Seconde méthode Cette deuxième méthode n’utilise pas de port bidirectionnel. Les colonnes seront
seulement des sorties et l’on lira les lignes (ou l’inverse).
On va appliquer successivement les combinaisons suivantes sur les colonnes :
P1.3
0
1
1
P1.4
1
0
1
P1.5
1
1
0
Un 0 est écrit sur une colonne, alors que toutes les autres sont maintenues à 1, puis les lignes sont
lues. Ensuite, on change le 0 de colonne et l’on lit de nouveau les lignes etc.
Si l’on lit les valeurs suivantes et qu’un seul bouton du clavier est enfoncé, on ne doit lire qu’un seul
0 sur une ligne pour une seule des combinaisons de colonnes.
Valeurs écrites
P1.3
0
1
1
P1.4
1
0
1
Valeurs lues
P1.5
1
1
0
P1.0
1
0
1
P1.1
1
1
1
P1.2
1
1
1
Sur cet exemple, on déduit que le bouton enfoncé est à l’intersection de la colonne P1.4 et de la ligne
P1.0. Notons que l’on aurait très bien pu arrêter la scrutation après avoir obtenu la position du bouton
enfoncé. Par conséquent, on obtient la position d’un bouton en au plus 3 écritures/lectures.
7.4
Les mémoires externes
Bien que l’intérêt premier d’un microcontrôleur est d’avoir besoin de peu de composants pour être
opérationnel, certains microcontrôleurs peuvent exploiter des mémoires externes. C’est le cas
notamment de tous les microcontrôleurs de la famille MCS51 ainsi que ceux de la famille 68HC11
Motorola.
-46-
Cette exploitation de mémoires externes signifie avant tout que le microcontrôleur est capable de
générer un bus adresses/données/commandes externe. On va voir dans un premier temps sur quelles
broches du microcontrôleur le bus est accessible.
7.4.1
Bus adresses/données dans la famille MCS51
Pour ne pas avoir à multiplier les broches, les constructeurs de microcontrôleurs ont généralement
choisi de faire sortir le bus adresses/données sur des broches ayant une autre fonction dans le cas où ce
bus ne serait pas exploité. D’ailleurs, la plupart des broches d’un microcontrôleur sont multifonctions.
Pour les microcontrôleurs de la famille MCS51, le bus adresses/données est disponible sur les
broches attribuées également aux ports P0 et P2. Aussi, l’utilisation du bus externe nous prive-t-elle par
conséquent de 16 lignes d’entrées/sorties logiques !
Pour la famille MCS51, le bus adresses/données externe est un bus de largeur 8 bits pour les données
et de largeur 16 bits pour les adresses. Les 24 bits du bus sont fournis par les 16 broches de P0 et P2
grâce à un multiplexage de certaines informations.
Multiplexage du port P0
Lorsque le bus externe est utilisé, le port P0 va fournir à la fois les 8 bits de poids faible de l’adresse
et les 8 bits de données. On va noter [A0-A15] les 16 bits d’adresse et [D0-D7] les 8 bits de données.
Un cycle de lecture ou d’écriture mémoire est divisé en 2. Dans une première partie du cycle, les 8
bits de poids faible d’adresse [A0-A7] sont présents sur les broches P0.0 à P0.7. Dans la seconde partie du
cycle, les mêmes broches P0.0 à P0.7 correspondent au bus de données [D0-D7]. En ce qui concerne le
port P2, il délivre tout au long du cycle les 8 bits de poids fort d’adresses [A8-A15].
Soulignons par ailleurs que le bus d’adresses est un bus unidirectionnel alors que le bus de données
est bidirectionnel. Aussi, dans un même cycle, le port P0 peut être tour à tour port d’entrée ou de sortie.
Le chronogramme d’un cycle du bus externe est le suivant.
Démultiplexage du port P0
L’exploitation du bus externe, par une mémoire par exemple, n’est possible qu’à la condition de
reconstituer le bus adresses/données complet. En effet, une mémoire ne peut être lue ou écrite qu’à la
condition que tous les bits d’adresse soient présents simultanément sur les broches d’adresse de la
mémoire. On doit donc démultiplexer le port P0 de manière à obtenir les 8 bits d’adresse [A0-A7] et les
8 bits de données [D0-D7] sur des bus distincts.
Dans le chronogramme du cycle du bus, on voit que le microcontrôleur génère le signal ALE
(address latch enable) sur la broche 30 quand les 8 bits A0-A7 sont stables sur le port P0. Ce signal
indique le moment où les 8 bits d’adresse doivent être « capturés » sur le port P0. On peut donc
mémoriser ces 8 bits par 8 bascules D dont le signal d’écriture est piloté par la broche ALE du
microcontrôleur.
-47-
Verrou 8 bits 74xx373 ou 74xx573
Les composants référencés 74xx373 ou 74xx573 contiennent 8 bascules D commandées par un même
signal LE (latch enable). Ce sont donc les composants les plus fréquemment utilisés pour démultiplexer
le port P0. Le montage suivant montre comment on réalise ce démultiplexage.
[D0-D7]
[A0-A7]
10
11
12
13
14
15
16
17
FREQ=12MHz
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
2
3
4
5
6
7
8
9
31
30
29
9
11
1
VCC
1
2
3
4
5
6
7
8
D0
D1
D2
D3
D4
D5
D6
D7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
19
18
17
16
15
14
13
12
LE
OE
74HC573
21
22
23
24
25
26
27
28
80C51FA
Remarque : l’entrée /OE du 74HC573, qui commande les sorties 3 états des bascules D, est ici reliée
à la masse (niveau 0). Autrement dit, le bus [A0-A7] n’est jamais dans l’état « haute impédance », chacun
de ses fils est soit dans l’état 0 soit dans l’état 1, et ce à tout moment. On verra d’autres montages où
l’utilisation des verrous 8 bits sera légèrement différente et pour lesquels l’entrée de commande /OE ne
sera pas en permanence à l’état 0.
7.4.2
Mémoire de programme externe
Dans un premier temps, on a regardé comment les microcontrôleurs de la famille MCS51 généraient
le bus externe adresses/données. Nous n’avons pas encore vu quelles commandes de lecture ou d’écriture
le microcontrôleur générait pour accéder à des mémoires.
Lorsque nous avons commencé à étudier la famille MCS51, nous avons vu que les microcontrôleurs
de cette famille possédaient en réalité plusieurs espaces mémoires distincts. Il y a un espace de mémoire
de programme, un espace de mémoire de données interne, et un espace de mémoire de données externes.
En fait, le microcontrôleur va utiliser des signaux de lecture ou de lecture/écriture différents pour
chacun de ces espaces mémoire.
Un microcontrôleur de type MCS51 dialogue avec une mémoire de programme externe en activant
la broche /PSEN (program store enable). Pendant un cycle du bus externe, un niveau bas (0 logique) sur
cette broche signifie que le microcontrôleur lit un octet en mémoire de programme. Exprimé
différemment, le microcontrôleur active la broche /PSEN pour lire un octet d’instruction dans la
mémoire de programme externe.
Ceci se voit plus simplement sur le chronogramme d’un cycle de lecture d’une mémoire de
programme externe (page suivante).
Dans un cycle de lecture en mémoire de programme externe, le microcontrôleur génère une adresse
comme nous l’avons vu précédemment, puis, quand l’adresse 16 bits complète [A0-A16] est disponible et
stable, le microconrôleur active sa broche /PSEN (elle passe à 0). Le microcontrôleur laisse s’écouler un
peu de temps pour qu’une donnée 8 bits se stabilise sur le bus de données (c’est-à-dire sur le le port P0)
puis la lit, ce qui est noté INSTR. IN sur le chronogramme.
-48-
L’exploitation d’une mémoire de programme externe de type ROM se fait donc en démultiplexant le
bus externe, comme vu précédemment, et en reliant la sortie /PSEN du microcontrôleur à la broche de
commande /OE de la mémoire de programme.
Broche /EA
La broche /EA (External Address), qui est une entrée du microcontrôleur, joue également un rôle
pour l’accès à la mémoire de programme.
Lorsque l’on applique un niveau 0 sur cette broche (i.e. on relie /EA à la masse), le microcontrôleur
n’utilise que la mémoire de programme externe, et ce dès la mise sous tension. Dans ce cas, après mise
sous tension, le microcontrôleur commence à charger et exécuter les instructions à partir de l’adresse
0000h en mémoire de programme externe, et ceci même si le microcontrôleur possède une mémoire de
programme interne !
Remarque : par conséquent, un microcontrôleur ayant de la mémoire de programme interne non
effaçable (le 8051 par exemple) peut toujours être réutilisé dans une autre application, à condition de
l’utiliser avec de la mémoire de programme externe et de placer /EA=0 dans ce cas.
Lorsque l’on applique un niveau 1 sur la broche /EA, le microcontrôleur charge et exécute les
instructions à partir de la mémoire de programme interne. Dans ce cas, le bus externe n’est pas généré
après mise sous tension, en tout cas pas pour les accès aux instructions 3 . Par contre, dès que le
processeur commence à exécuter des instructions situées à une adresse supérieure à la capacité de la
mémoire de programme interne, le microcontrôleur se met automatiquement à générer le bus externe
pour accéder à la partie supérieure de la mémoire de programme.
Par exemple, si un microcontrôleur possède 4 Ko octets de mémoire de programme interne, on peut
compléter ces 4 Ko par 60 Ko de mémoire de programme externe. Dans ce cas, on relie la broche /EA
au niveau 1 (Vcc). Dès que le pointeur d’instruction PC dépasse la valeur 0FFFh, le bus externe est
automatiquement généré. Quand on relie /EA à Vcc, il y a commutation automatique entre mémoire de
programme interne et externe au delà de la capacité de mémoire de programme interne (revoir les plans
mémoires dans le chapitre précédent).
La figure suivante montre un montage avec de la mémoire de programme interne. Il s’agit d’un
circuit à base de 8051 qui possède de la ROM interne. Pour que le microcontrôleur commence son
exécution sur la ROM interne, la broche /EA est connectée au niveau 1 (Vcc). Dans cette configuration,
Attention, en revanche le bus externe sera généré si une instruction doit accéder à la mémoire de données
externe.
3
-49-
toues les ports P0 à P3 sont donc utilisables comme lignes d’entrées ou sorties. C’est en quelque sorte la
configuration minimale.
10
11
12
13
14
15
16
17
19
18
39
38
37
36
35
34
33
32
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
VCC
1
2
3
4
5
6
7
8
31
30
29
9
21
22
23
24
25
26
27
28
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
80C51FA
Le montage suivant présente un microcontrôleur démuni de mémoire programme interne. Le 8031
est un microcontrôleur ROMless (sans ROM interne). Il est donc indispensable que le programme de
l’application soit inscrit dans une mémoire non volatile externe (ROM, PROM, EPROM, EEPROM ou
Flash ROM).
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
XTAL1
XTAL2
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
EA/VPP
ALE/PROG
PSEN
RST
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
2
3
4
5
6
7
8
9
31
30
29
9
11
1
D0
D1
D2
D3
D4
D5
D6
D7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
19
18
17
16
15
14
13
12
10
9
8
7
6
5
4
3
25
24
21
23
2
LE
OE
74HC573
20
22
27
1
21
22
23
24
25
26
27
28
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
D0
D1
D2
D3
D4
D5
D6
D7
11
12
13
15
16
17
18
19
CE
OE
PGM
VPP
27C64
80C31
On retrouve à la fois le démultiplexage du port P0 et la connexion du bus adresses/données à la
mémoire programme 27C64 (EPROM de 8 Ko). Pour cette application, la broche /EA est reliée à la
masse car le programme doit être lu dans la mémoire externe. Le signal /PSEN est connecté à l’entrée de
lecture /OE de l’EPROM. L’EPROM est en permanence active : son entrée /CE (chip enable) est reliée à
la masse.
Une EPROM 27C64 a une capacité de 8Ko, soit un bus d’adresses de 13 bits [A0-A12]. Dans cette
application, les bits d’adresse [A13-A15] disponibles sur les broches [P2.5-P2.7] ne sont pas exploités.
Le schéma précédent n’est pas facile à lire car tous les signaux sont représentés. On peut donner une
version équivalente où les bus sont représentés par des traits gras sur lesquels sont notés les signaux
véhiculés (ce sera la représentation utilisée par la suite).
[D0-D7]
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
XTAL1
XTAL2
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
EA/VPP
ALE/PROG
PSEN
RST
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
2
3
4
5
6
7
8
9
31
30
29
9
11
1
D0
D1
D2
D3
D4
D5
D6
D7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
19
18
17
16
15
14
13
12
[A0-A7]
LE
OE
74HC573
[A8-A12]
10
9
8
7
6
5
4
3
25
24
21
23
2
20
22
27
1
21
22
23
24
25
26
27
28
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
CE
OE
PGM
VPP
27C64
80C31
-50-
D0
D1
D2
D3
D4
D5
D6
D7
11
12
13
15
16
17
18
19
7.4.3
Mémoire de données externe
Les microcontrôleurs de la famille MCS51 possèdent un espace d’adressage « DONNEES
EXTERNES ». Cela signifie que l’on peut ajouter jusqu’à 64 Ko de mémoire volatile (RAM).
Physiquement, le microcontrôleur utilise le même bus adresses/données pour la mémoire de
programme externe et la mémoire de données externe. Seuls les signaux de commande diffèrent. On a
vu que le microcontrôleur active le signale /PSEN pour lire un octet en mémoire programme. Il utilise
deux autres signaux pour lire et écrire en mémoire de données externe.
La broche /RD (P3.7) fournit le signal de lecture de mémoire de données externe et la broche /WR
(P3.6) donne le signal d’écriture. Notons que ces deux broches appartiennent en fait au port P3, et qu’il
s’agit une fois de plus de broches multifonctions.
A l’exception des signaux de commande, le montage permettant d’exploiter une RAM externe est
identique au montage utilisant une ROM externe.
[D0-D7]
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
2
3
4
5
6
7
8
9
31
30
29
9
11
1
D0
D1
D2
D3
D4
D5
D6
D7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
19
18
17
16
15
14
13
12
[A0-A7]
LE
OE
74HC573
[A8-A14]
21
22
23
24
25
26
27
28
/WR
/RD
10
9
8
7
6
5
4
3
25
24
21
23
2
26
1
20
27
22
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
D0
D1
D2
D3
D4
D5
D6
D7
11
12
13
15
16
17
18
19
CE
WE
OE
62256
80C51FA
Dans l’exemple précédent, le programme de l’application est en mémoire de programme interne, par
conséquent la broche /EA doit être est reliée au niveau 1 (Vcc). Le démultiplexage du port P0 est
classique. La mémoire RAM de référence 62256 est une mémoire de 32 Ko et possède donc un bus de 15
bits [A0-A14]. La broche P2.7 (A15) est laissée non connectée.
Pour la partie commande, le signal /RD (P3.7) pilote la lecture de la RAM (/OE) et le signal /WR
(P3.6) pilote l’écriture de la RAM (/WE).
Il faut bien comprendre que les signaux /RD et /WR ne sont générés qu’en phase de lecture ou
d’écriture dans l’espace mémoire données externes. Seules les instructions dont le mnémonique est
MOVX permettent l’accès à cet espace mémoire.
-51-
Pour fixer les idées, dans l’exécution de la suite d’instructions
MOV A,#1
MOV DPTR,#2000h
MOVX @DPTR,A
XRAM[2000h] ppv 1
l’exécution de l’instruction MOVX @DPTR,A conduit à placer l’adresse contenue dans DPTR sur le bus
d’adresses, c’est-à-dire l’adresse 2000h. Ensuite, le processeur active le signal ALE pour verrouiller l’octet
de poids faible [A7-A0] en sortie du verrou 74xx573, puis le processeur place la donnée contenue dans A
sur le bus de données, c’est-à-dire la donnée 01h, et enfin le processeur active le signal /WR pour que la
RAM mémorise la donnée.
Inversement, dans l’exécution de la séquence
MOV DPTR,#1000h
MOVX A,@DPTR
A ppv XRAM[1000h]
il s’agit d’une lecture dans l’espace de mémoire de données externe. Chronologiquement, le
processeur place l’adresse 1000h sur le bus d’adresses, verrouille la partie basse de l’adresse en
déclenchant ALE, active le signal /RD pour lire la mémoire, attend que la donnée se stabilise sur le bus
de données, et copie pour finir la donnée présente sur le bus de données dans le registre A.
En résumé, l’activation de /RD ou /WR est consécutive à l’exécution d’une instruction dont le
mnémonique est MOVX. L’activation du signal /PSEN quant à elle a lieu à chaque fois que le processeur a
besoin de lire un octet en mémoire de programme ; il s’agit le plus souvent d’octets d’instructions, mais
il peut s’agir aussi de données présentes dans la mémoire de programme. La lecture de données dans la
mémoire de programme s’effectue à l’aide des instructions dont le mnémonique est MOVC.
7.4.4
Mémoire de programme externe et mémoire de données externe
Puisque les deux espaces d’adressages « PROGRAM » et « EXTERNAL DATA » sont différents, on
peut réaliser un système contenant à la fois de la ROM externe et de la RAM externe.
Le montage suivant donne un exemple d’une telle application.
[A0-A7]
[D0-D7]
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
XTAL1
XTAL2
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
EA/VPP
ALE/PROG
PSEN
RST
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
2
3
4
5
6
7
8
9
31
30
29
9
11
1
[D0-D7]
D0
D1
D2
D3
D4
D5
D6
D7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
19
18
17
16
15
14
13
12
[A0-A7]
LE
OE
[A8-A12]
74HC573
10
9
8
7
6
5
4
3
25
24
21
23
2
20
22
27
1
21
22
23
24
25
26
27
28
[D0-D7]
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
D0
D1
D2
D3
D4
D5
D6
D7
11
12
13
15
16
17
18
19
[A8-A12]
[A13-A14]
CE
OE
PGM
VPP
10
9
8
7
6
5
4
3
25
24
21
23
2
26
1
20
27
22
27C64
[A8-A12]
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
D0
D1
D2
D3
D4
D5
D6
D7
11
12
13
15
16
17
18
19
CE
WE
OE
62256
/WR
/RD
80C31
[A13-A14]
La mémoire 27C64 (EPROM de 8Ko) et la mémoire 62256 (RAM statique de 32Ko) partagent le
même bus adresses/données mais sont commandées par des signaux différents : /PSEN active la lecture
de la ROM et /RD et /WR activent la lecture et l’écriture de la RAM. Ces deux mémoires ne sont jamais
actives en même temps.
On remarque que les bits [A13-14] ne sont utilisés que par la RAM statique qui possède une capacité
mémoire plus importante que la ROM, et donc un bus d’adresse plus large.
-52-
7.5
Périphériques externes
L’exploitation de circuits périphériques externes ne présente pas plus de difficulté que l’utilisation de
mémoires externes. Par ailleurs, comme nous l’avons déjà dit, il est toujours préférable d’essayer de
trouver un microcontrôleur qui contienne déjà la fonction recherchée plutôt qu’ajouter celle-ci au
moyen d’un circuit périphérique. Néanmoins nous allons donner ici quelques exemples d’exploitation
de périphériques.
7.5.1
Périphérique d’entrées/sorties programmable : PIO 8255
La société Intel propose un circuit périphérique pour gérer les entrées et sorties TOR : le PIO 8255.
Ce composant figure notamment sur les cartes MC51 utilisées en travaux pratiques. En outre, il s’agit
d’un périphérique assez facile à exploiter. Le brochage du 8255 est le suivant.
34
33
32
31
30
29
28
27
5
36
9
8
35
6
D0
D1
D2
D3
D4
D5
D6
D7
PA0
PA1
PA2
PA3
PA4
PA5
PA6
PA7
RD
WR
A0
A1
RESET
PB0
PB1
PB2
PB3
PB4
PB5
PB6
PB7
CS
PC0
PC1
PC2
PC3
PC4
PC5
PC6
PC7
4
3
2
1
40
39
38
37
18
19
20
21
22
23
24
25
14
15
16
17
13
12
11
10
8255A
Le 8255 dispose de 3 ports 8 bits notés [PA0-PA7], [PB0-PB7] et [PC0-PC7] programmables en entrée
ou en sortie, d’un bus de données 8 bits [D0-D7], d’un bus d’adresse 2 bits [A0-A1], d’un signal
d’initialisation RESET et des signaux de commande habituels /CS, /RD et /WR.
Le 8255 nécessite une phase d’initialisation. On peut exploiter pour cela le signal RST d’initialisation
du microcontrôleur.
Les 4 adresses accessibles à l’aide des bits d’adresse A0 et A1 permettent d’accéder à 4 registres de
configuration et de donnée du périphérique.
Lorsque le composant est activé (/CS=0), le fonctionnement est le suivant :
A1
A0
/RD
/WR
Opération
0
0
0
1
Lecture Port A (Port A -> bus de données)
0
1
0
1
Lecture Port B (Port B -> bus de données)
1
0
0
1
Lecture Port C (Port C -> bus de données)
1
1
0
1
Lecture du registre de commande (commande->bus de d.)
0
0
1
0
Ecriture Port A (bus de données -> Port A)
0
1
1
0
Ecriture Port B (bus de données -> Port B)
1
0
1
0
Ecriture Port C (bus de données -> Port C)
1
1
1
0
Ecriture du registre de commande (bus de d. -> commande)
Le registre atteint via l’adresse (11)b est le registre de configuration du périphérique. Le mot de
commande placé dans ce registre permet la configuration des ports E/S.
Mot de commande du 8255 (à écrire dans le registre de commande)
-53-
Le mot de commande 8 bits du 8255 est constitué de la manière suivante :
D7 D6 D5 D4 D3 D2 D1 D0
1/2 Port C (faible)
0 = sortie
1 = entrée
D7=1
Mode
00 =
01 =
10 =
11 =
groupe 1
mode 0
mode 1
mode 2
mode 2
Port B
0 = en sortie
1 = en entrée
Groupe 2
0 = mode 0
1 = mode 1
Port A
0 = en sortie
1 = en entrée
1/2 Port C (fort)
0 = sortie
1 = entrée
Les 3 ports A, B et C sont répartis en 2 groupes.
Groupe 1 : Port A + ½ Port C fort [PC7-PC4]
Groupe 2 : Port B + ½ Port C faible [PC3-PC0]
Chaque groupe peut être configuré en 2 ou 3 modes de fonctionnement :
Mode 0 : mode entrée-sortie classique (unidirectionnel)
Mode 1 : Strobed Input/Output (communication avec handshaking)
Mode 2 : Mode bidirectionnel sur port A. Les broches peuvent être tour à tour entrée ou sortie.
Pour des raisons de simplicité, nous n’utiliserons en TP que le mode 0 pour chacun des groupes. Dans
ce mode, une fois la configuration effectuée, le port demeure soit port d’entrée soit port de sortie.
Utilisation du 8255 dans un système à base de 8051
Le montage suivant exploite un 8255. Le périphérique est accessible, comme la RAM, dans l’espace
Données Externes.
A0
A1
[D0-D7]
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
19
18
T2/P1.0
T2EX/P1.1
ECI/P1.2
CEX0/P1.3
CEX1/P1.4
CEX2/P1.5
CEX3/P1.6
CEX4/P1.7
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
RxD/P3.0
TxD/P3.1
INT0/P3.2
INT1/P3.3
T0/P3.4
T1/P3.5
WR/P3.6
RD/P3.7
EA/VPP
ALE/PROG
PSEN
RST
XTAL1
XTAL2
P2.0/A8
P2.1/A9
P2.2/A10
P2.3/A11
P2.4/A12
P2.5/A13
P2.6/A14
P2.7/A15
39
38
37
36
35
34
33
32
2
3
4
5
6
7
8
9
31
30
29
9
11
1
21
22
23
24
25
26
27
28
D0
D1
D2
D3
D4
D5
D6
D7
19
18
17
16
15
14
13
12
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
[A0-A7]
LE
OE
74HC573
[A8-A14]
A15
/WR
/RD
10
9
8
7
6
5
4
3
25
24
21
23
2
26
1
20
27
22
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
D0
D1
D2
D3
D4
D5
D6
D7
11
12
13
15
16
17
18
19
34
33
32
31
30
29
28
27
/RD
/WR
5
36
9
8
35
/A15 6
D0
D1
D2
D3
D4
D5
D6
D7
PA0
PA1
PA2
PA3
PA4
PA5
PA6
PA7
RD
WR
A0
A1
RESET
PB0
PB1
PB2
PB3
PB4
PB5
PB6
PB7
CS
CE
WE
OE
PC0
PC1
PC2
PC3
PC4
PC5
PC6
PC7
62256
80C51FA
1
4
3
2
1
40
39
38
37
18
19
20
21
22
23
24
25
14
15
16
17
13
12
11
10
2
8255A
Pour ce montage, la RAM est active pour toutes les adresses [0000h-7FFFh] puisque /CERAM=A15. Le
8255 est actif pour les autres adresses [8000h-FFFFh].
Le plan mémoire n’a donc aucune zone non attribuée. En revanche, bien que le 8255 n’ait que 4
registres, il occupe ici 32 Ko dans le plan mémoire ! Il y a donc recouvrement : chaque registre du 8255
-54-
peut-être atteint avec 8Ko adresses différentes ! Par exemple, toute adresse dont les bits A15, A1 et A0
valent 1 permet d’atteindre le registre de commande du 8255 !
Exemple de programme d’utilisation du 8255 (pour ce montage !)
Attention, ce programme ne fonctionne que pour cette répartition du plan mémoire. On ne peut pas
réutiliser cet exemple sans précaution.
---------------------------------------------------------------ADR_8255 EQU 08000h
; adresse de base du 8255
ORG 0000h
MOV A,#10000010b
MOV DPTR,#ADR_8255+3
MOVX @DPTR,A
; configuration du 8255
; adresse du registre de contrôle
; XRAM[8003h] ppv (10000010)b
sans_fin :
MOV DPTR,#ADR_8255+1
MOVX A,@DPTR,
MOV DPTR,#ADR_8255
MOVX @DPTR,A
JMP sansfin
end
----------------------------------------------------------------
Dans un premier temps, le programme précédent configure le 8255. On écrit pour cela un mot de
commande dans le registre de commande du 8255, c’est-à-dire à l’adresse 8003h dans l’espace de données
externes. Cette configuration définit le port A comme port de sortie et le port B comme port d’entrée.
Ensuite, le programme exécute une boucle infinie de lecture du port B (adresse 8001h) et d’écriture
de cette valeur sur le port A (adresse 8000h).
Le même programme en langage C
On peut également donner le programme en C correspondant.
Les 4 variables déclarées au tout début sont alignées sur les 4 adresses (dans l’espace de données
externes) du 8255. Là encore, l’écriture du programme est intimement liée à la configuration matérielle
et au plan mémoire (espace données externes).
---------------------------------------------------------------#include<8051.h>
// adresse du port A du 8255
volatile xdata at 0x8000 unsigned char portA;
// adresse du port B du 8255
volatile xdata at 0x8001 unsigned char portB;
volatile xdata at 0x8002 unsigned char portC;
// adresse du registre de configuration du 8255
volatile xdata at 0x8003 unsigned char config8255;
void main()
{
-55-
config8255=0x82;
// le mot de configuration est 10000010b
while(1)
{
portA=portB;
}
}
----------------------------------------------------------------
-56-
8
Annexe A : Familles technologiques
En électronique, les fonctions logiques sont réalisées à l’aide de transistors. Les différentes familles
technologiques correspondent d’une part aux transistors utilisés, bipolaires ou à effet de champ, et aux
montages utilisés pour réaliser les fonctions logiques élémentaires (inversion, et,ou).
Les différentes familles se distinguent principalement par la vitesse de commutation des portes
(temps de propagation), leur consommation électrique et leur intégration (nombre de fonctions par
unité de surface).
Famille TTL (Transistor Transistor Logic) et dérivés
Les composants TTL sont à base de transistors bipolaires. L’alimentation de ces circuits est 5V.
Il s’agit d’une technologie assez rapide, en comparaison avec les composants MOS, mais qui est
caractérisée par une forte consommation et une faible intégration.
Dérivés :
TTL L : Low Power (consommation plus faible)
TTL LS : Schottky (plus rapide que TTL)
ECL : Emitter Coupled Logic : (encore plus rapide)
Famille MOS et dérivés
Famille logique utilisant les transistors à effet de champ (NMOS ou PMOS). La famille CMOS
(complementary MOS) utilise des transistors NMOS et PMOS.
Il s’agit d’une technologie beaucoup moins rapide que TTL. En revanche, et c’est pourquoi cette
technologie est la plus utilisée pour les processeurs et les mémoires, la consommation est aussi beaucoup
plus faible et le niveau d’intégration est beaucoup plus élevé.
Dérivés :
HCMOS High Speed CMOS ( plus rapide)
HCT MOS : compatible TTL
Remarque : en technologie MOS, la consommation des composants a lieu principalement lors des
commutations des transistors. Pour les processeurs, la consommation augmente donc avec la fréquence
de l’oscillateur.
Remarque : lorsque l’on associe sur un même circuit des composants d’une même famille
technologique, on n’a pas trop de soucis. En revanche, c’est plus délicat entre différentes familles,
notamment en raison des niveaux logiques et d’alimentation. C’est le rôle de la technologie HCT qui
donne une certaine compatibilité entre TTL et MOS.
-57-
9
Annexe B : Les mémoires et leur représentation
Les mémoires sont des composants électroniques capables d’emmagasiner et restituer des
informations. Les mémoires stockent les informations sous forme de mots binaires (un mot = ensemble
de n bits). On appelle « case mémoire » ou « cellule mémoire » ou « point mémoire » le dispositif
électronique capable de mémoriser un bit d’information. Dans le cas de mémoires RAM statiques, ce
point mémoire est constitué d’une bascule.
Une case mémoire contient donc soit un 0 soit un 1 sous forme d’un niveau bas ou haut (le
potentiel dépend de la technologie utilisée).
On peut voir une mémoire comme une matrice de cases mémoires. Le nombre de cellules mémoires
(bits) de cette matrice représente sa capacité. Elle est exprimée en bits ou Kbits.
On ne peut pas accéder à chaque cellule séparément. Les mémoires sont organisées en mots de M
bits. L’organisation d’une mémoire est le nombre N de mots de M bits contenus dans la mémoire : c’est
un couple N×M. Par exemple, une mémoire 256×8 représente une mémoire de 256 octets. Une mémoire
1024×16 représente une mémoire de 1024 mots de 16 bits, que l’on notera généralement 1K×16 (1024 =
210 = 1K).
On voit donc généralement une mémoire comme un tableau dont chaque case est numérotée. Le
numéro de la case s’appelle son adresse. Une mémoire 256×8 possède 256 adresses.
Exemple : mémoire 8×16.
Puisque les adresses et les données sont par nature binaires, on représente ces informations en base
hexadécimale (plus rarement en binaire).
0h
24D5h
1h
1200h
2h
1000h
3h
0000h
4h
0001h
5h
1EF4h
6h
23BFh
7h
FE34h
Bus adresses/données
Sur un circuit mémoire, les données et les adresses sont des informations binaires véhiculées par des
broches du composant.
Les broches d’adresse sont des entrées d’une mémoire permettant de spécifier quel mot mémoire l’on
veut atteindre. L’ensemble des broches d’adresse est appelé bus d’adresses.
Les broches de données sont les broches (sorties ou entrées/sorties selon le type de mémoire)
permettant de véhiculer les informations contenues dans la mémoire. L’ensemble des broches de
données est appelé bus de données.
Ensuite, d’autres broches d’entrée, appelées broches de commande, permettent le pilotage de la mémoire
(signal d’activation, signal de lecture, signal d’écriture).
Exemple : Mémoire 16×8 accessible en lecture et écriture.
Pour pouvoir mémoriser 16 octets il faut en tout 128 cellules mémoires (sa capacité) agencées en 16
mots de 8 bits (son organisation est 16×8).
-58-
Cette mémoire stocke 16 mots, il y a donc 16 adresses différentes (notées de 0h à Fh), une par mot
mémoire. En codage binaire, les adresses de cette mémoire nécessitent donc 4 bits d’information (24=16).
Chaque donnée (chaque mot) de la mémoire est codée sur 8 bits.
Par conséquent, le bus d’adresses de cette mémoire fait 4 bits, et le bus de données fait 8 bits. Puisque
cette mémoire est accessible en lecture et écriture, il y aura également des signaux de commande pour
différencier l’opération de lecture et l’opération d’écriture.
Exemple : Mémoire 2K×16 accessible en lecture et écriture.
Pour pouvoir mémoriser 2048 mots de 16 bits, il faut en tout 32768 cellules mémoires (sa capacité
est aussi notée 32Kbits) agencées en 2048 mots de 16 bits chacun (son organisation est 2048×16).
Cette mémoire stocke 2048 mots, il y a donc 2048 adresses différentes (notées en hexa de 000h à
7FFh). En codage binaire, les adresses de cette mémoire nécessitent donc 11 bits d’information
(211=2048). Chaque donnée (chaque mot) de la mémoire est codée sur 16 bits.
Par conséquent, le bus d’adresses de cette mémoire fait 11 bits, et le bus de données fait 16 bits.
Puisque cette mémoire est accessible en lecture et écriture, il y aura également des signaux de commande
pour différencier l’opération de lecture et l’opération d’écriture.
Exemple : Mémoire 32Ko accessible en lecture seule.
Pour pouvoir mémoriser 32768 octets, il faut en tout 262144 cellules mémoires (sa capacité est aussi
notée 256Kbits) agencées en 32768 mots de 8 bits chacun (son organisation est 32K×8).
Cette mémoire stocke 32K mots, il y a donc 32768 adresses différentes (notées en hexa de 0000h à
7FFFh). En codage binaire, les adresses de cette mémoire nécessitent donc 15 bits d’information
(215=32K). Chaque donnée (chaque mot) de la mémoire est codée sur 8 bits.
Par conséquent, le bus d’adresses de cette mémoire fait 15 bits, et le bus de données fait 8 bits.
Puisque cette mémoire n’est accessible qu’en lecture, il y aura également une broche de commande de
lecture mais évidemment pas de signal d’écriture.
Représentation d’un circuit mémoire.
On va représenter un circuit mémoire 2M×N par un rectangle où
les broches d’adresses seront notées de A0 à AM-1
les broches de données seront notées de D0 à DN-1
le signal de lecture sera noté /RD (read) ou /OE (output enable)
le signal d’écriture sera noté /WR (write) ou /WE (write enable)
le signal de sélection de boîtier /CS(chip select) ou /CE (chip enable)
bus d'adresses
(entrée)
bus unidirectionnel
D0
D1
A0
A1
D n-1
A m-1
/CS
/RD
bus de données
(entrée/sortie)
bus bidirectionnel
/WR
bus de commandes
(entrée)
Remarque : on a fourni ici la représentation d’une mémoire accessible en lecture et écriture (RAM).
Bus d’adresses : m broches notées A0 à Am-1. En appliquant des niveaux logiques à ces broches, on
précise l’adresse du mot mémoire à atteindre.
-59-
Bus de données : n broches notées D0 à Dn-1. Pour une mémoire accessible en lecture/écriture, ce
bus est bidirectionnel. Pour une mémoire accessible uniquement en lecture, ce bus est unidirectionnel ;
suivant les commandes appliquées, ce bus est soit en entrée, soit en sortie.
Pour une mémoire accessible en lecture/écriture, lorsque ce bus est en sortie (lors d’une lecture de la
mémoire), c’est le circuit mémoire qui impose un niveau logique (une tension) à chacune des broches
D0 à Dn-1.
Bus de commande : on « pilote » la mémoire en appliquant des niveaux particuliers à ces broches.
Noter que tous ces signaux sont actifs à 0.
/CS : /Chip Select (actif au niveau bas)
permet d’activer ou non la mémoire
/RD : / ReaD (actif au niveau bas)
lecture de la mémoire
/WR : /WRite (actif au niveau bas)
écriture de la mémoire
Mémoires accessibles en lecture/écriture
Elles sont appelées mémoires RAM (Random Access Memory). On trouve principalement deux types
de RAM : les RAM statiques et les RAM dynamiques. Le point mémoire d’une RAM statique est une
bascule. Le point mémoire d’une RAM dynamique est un condensateur. En raison de fuites de courant,
les RAM dynamiques perdent leurs informations et doivent être réécrites périodiquement. Les RAM
statiques conservent leurs informations tant qu’elles sont sous tension. Dans tous les cas, les RAM sont
des mémoires volatiles : elles perdent leurs informations hors tension (quoiqu’il existe des RAM
utilisant une pile pour sauvegarder les informations).
Représentation d’une RAM
bus d'adresses
(entrée)
bus unidirectionnel
D0
D1
A0
A1
D n-1
A m-1
/CS
/OE
bus de données
(entrée/sortie)
bus bidirectionnel
/WE
bus de commandes
(entrée)
Mémoires accessibles en lecture seule
Elles sont appelées ROM (Read Only Memory) ou mémoires mortes. Ces mémoires mémorisent
leurs informations par un procédé de programmation ou de gravage.
ROM : mémoire programmée à la construction (économiquement intéressant uniquement pour des
grandes séries).
Hormis les ROM, les mémoires suivantes sont programmables sur site.
PROM : ROM programmable. La programmation se fait par claquage de fusibles. Cette
programmation est ensuite définitive.
EPROM (Erasable PROM). Mémoire programmable. La programmation se fait électriquement mais
la mémoire est effaçable par exposition aux ultra violets. On reconnaît ces mémoires à leur fenêtre de
quartz sur le dessus du composant.
OTPROM : même technologie que EPROM donc même méthode de programmation. Le composant
ne dispose pas par contre de fenêtre d’effacement. Même s’il est potentiellement effaçable, il ne l’est pas
pratiquement. Il est un peu moins cher (économie d’une fenêtre de quartz !).
-60-
EEPROM (Electrically Erasable PROM) : Programmable et effaçable électriquement. Elle s’efface
mot par mot.
Flash ROM : Programmable et effaçable. La mémoire s’efface en une fois.
Représentation d’une ROM
D0
D1
A0
A1
bus d'adresses
(entrée)
D n-1
A m-1
bus unidirectionnel
bus de données
(sortie seul)
/CS
bus bidirectionnel
/OE
bus de commandes
(entrée)
Modes de fonctionnement d’une mémoire RAM (φ représente 0 ou 1)
/CS
/OE
/WE Am-1 à A0
D n-1 ..D0
1
φ
φ
φ
φ
0
1
1
φ
φ
0
0
1
φ
Broches
Lecture de la mémoire. Le circuit mémoire place les broches
D0 à Dn-1 en D0 à Dn-1 à un niveau logique représentant le contenu du mot
sortie.
dont l’adresse figure sur les broches A0 à Am-1
0
1
0
φ
Broches
Ecriture de la mémoire. Les niveaux logiques présents sur les
D0 à Dn-1 en broches D0 à Dn-1 sont mémorisés dans le mot mémoire dont
entrée
l’adresse figure sur les broches A0 à Am-1
0
0
0
φ
φ
Description
Mémoire inactive. Son contenu ne peut être ni lu ni écrit.
Mémoire active. Tant qu’il n’y a aucune commande de lecture
ou d’écriture, son contenu n’évolue pas et elle ne délivre aucune
information sur le bus de données.
Etat Interdit.
Exemple : mémoire de 4 mots de 6 bits chacun (4 × 6)
Représentation sous forme de tableau
D0
D1
D2
D3
D4
D5
bus d'adresses
A0
A1
0
1
2
3
010000
010110
001111
111110
bus de données
Ici, Mem[2] vaut (010110)b.
/CS
/RD
/WR
L'adresse est codée sur
2 bits A0 et A1,
il y a donc 4 adresses différentes
bus de commandes
-61-
Ce mot a une taille de 6 bits,
les données sont véhiculées sur
les broches D0 à D5.
Une opération d’écriture et de lecture de cette mémoire 4 × 6
Mem [3] <- (101000)b
opération d'écriture
Modification de la mémoire (en gras)
adresse
D0
D1
D2
D3
D4
D5
3=
(11)b
1
1
A0
A1
0
0
0
1
0
1
0
1
2
3
010000
010110
001111
101000
bus de données
en entrée
/CS
/RD
0
1
/WR
Suite à cette opération,
le mot Mem[3] est modifié.
0
opération d'écriture
bus de données <- Mem [2]
Contenu de la mémoire avant
l'opération de lecture
opération de lecture
adresse
D0
D1
D2
D3
D4
D5
2=
(10)b
0
1
A0
A1
/CS
/RD
0
0
/WR
0
1
2
3
010000
010110
001111
101000
1
1
1
1
0
0
bus de données en sortie,
c'est la mémoire qui impose
un niveau logique sur ces broches.
1
opération de lecture
Remarque : toutes les informations aux bornes de la mémoire sont binaires. Néanmoins, pour des raisons
évidentes de concision, les adresses et les données seront pratiquement systématiquement exprimées en
hexadécimal. Aussi, si vous n’êtes pas à l’aise, n’hésitez pas à repasser à l’expression binaire pour bien
comprendre le fonctionnement des systèmes, comme cela est fait sur les dessins ci-dessus.
-62-
10 Annexe C
Divers circuits sont utilisés dans les montages figurant dans ce polycopié. On rappelle succinctement
quelques uns des composants utilisés.
10.1 Bascule D
Une bascule D est un circuit séquentiel. L’entrée D est recopiée sur la sortie Q quand le signal Clk
est à 1. Lorsque le signal Clk revient à 0, la sortie Q conserve sa valeur (effet mémoire).
D
Clk
Clk
D
Q
1
0
0
Qt-1
11
0
1
Qt-1
2
Q
/Q
1
0
1
0
1
1
EN
C1
1D
19
3
18
4
17
5
16
6
15
7
14
8
13
9
12
74HC573
Les circuits 74xx373 et 74xx573 contiennent 8 bascules D ayant le même signal de recopie C. En
outre, ils possèdent des sorties 3 états activées par le signal /EN (enable). On utilise ce composant pour
démultiplexer le port P0 sur les microcontrôleurs MCS51.
10.2 Décodeurs
Il s’agit de circuits logiques combinatoires. Le niveau des sorties ne dépend que des niveaux des
entrées. Sur un décodeur, une combinaison des entrées n’active qu’une sortie à la fois. Les sorties sont
généralement actives à niveau bas pour piloter des entrées de sélection de mémoires (/CS).
2
3
A
B
1
E
Y0
Y1
Y2
Y3
1
2
3
4
5
6
7
6
4
5
74HC139
A
B
C
E1
E2
E3
Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
15
14
13
12
11
10
9
7
74HC138
Le circuit 74xx138 est un décodeur 3:8 et le 74xx139 est un décodeur 2:4. La table de vérité du
décodeur 2 :4 est :
B
A
E
/Y0
/Y1
/Y2
/Y3
∅
∅
0
1
1
1
1
0
0
1
0
1
1
1
0
1
1
1
0
1
1
1
0
1
1
1
0
1
1
1
1
1
1
1
0
-63-
-64-
Références bibliographiques
« Microcontrôleurs 8051 et 8052 » B. Odant, Dunod Tech.
« Mise en œuvre et applications du microcontrôleur 8051 » P. Kauffmann, MASSON
« Le microprocesseur et son environnement » Robert Du Bois, Dunod Tech.
-65-
Téléchargement