DORKEL Aymeric CHEVRET Anthony

78
DORKEL Aymeric CHEVRET Anthony TTravaux d'Initiative Personnelle Encadrés Les microcontrôleurs 8-bits Institut National des Sciences Appliquées de Strasbourg Années 2005/2006 STH 2 – ST 5

Transcript of DORKEL Aymeric CHEVRET Anthony

Page 1: DORKEL Aymeric CHEVRET Anthony

DORKEL Aymeric CHEVRET Anthony

TTravaux d'Initiative Personnelle Encadrés

Les microcontrôleurs 8-bits

Institut National des Sciences Appliquées de Strasbourg Années 2005/2006

STH 2 – ST 5

Page 2: DORKEL Aymeric CHEVRET Anthony

- 2 -

Page 3: DORKEL Aymeric CHEVRET Anthony

Les microcontrôleurs 8-bits

Durant le vingtième siècle l’électronique telle que nous la connaissons actuellement

est née. L’invention du transistor durant les années 50 a permis la création des microprocesseurs qui ont ouvert l’ère de l’électronique programmable. Que sont les microcontrôleurs, et pourquoi sont-ils des éléments essentiels des applications électroniques aujourd’hui ?

Les microcontrôleurs représentent une évolution des microprocesseurs en

diminuant le nombre de composants annexes nécessaires à leur fonctionnement. Ils se développent parallèlement à leurs pères et sont destinés à des applications nécessitant moins de puissance de calcul mais un fort taux d’intégration et des coûts réduits.

Il existe une très large variété de microcontrôleurs, des plus petits modèles aux fonctions extrêmement basiques, généralement basés sur des architectures 8-bits, au plus imposants, exploitant des architectures 32-bits, en passant par des modèles spécialisés, que ce soit dans le traitement du signal comme les DSP (« Digital Signal Processor », processeur pour signaux analogiques) ou dans la sécurité comme les microcontrôleurs sécurisés.

Nous limiterons notre étude aux microcontrôleurs 8-bits, dont les principes de

fonctionnement sont souvent extensibles aux architectures plus complexes. Nous n’étudierons pas le fonctionnement des périphériques qu’ils intègrent mais nous présenterons tout de même leur base sur le principe des entrées – sorties.

Les connaissances nécessaires pour pouvoir aborder ce rapport sont très réduites,

elles se limitent à des notions d’électricité, d’automatisme et de programmation. Toutefois les annexes renforceront certains points nécessaires à la compréhension ou à l’approfondissement du dossier.

- 3 -

Page 4: DORKEL Aymeric CHEVRET Anthony

- 4 -

Page 5: DORKEL Aymeric CHEVRET Anthony

Sommaire

Introduction au sujet 3

I Présentation 7 1. Définitions essentielles 7 2. Utilisation 8 3. Dates clés pour les microcontrôleurs 8-bits 9 4. Le marché du microcontrôleur 10 5. Boîtiers pour microcontrôleurs 11 6. Caractéristiques électriques 13

II Le choix d’un exemple : le digicode 15 1. Utilisation de notre circuit 15 2. Schéma du circuit et explications de son fonctionnement 16 3. La carte et son typon 17 4. Fonctionnement du programme C 18

III Le fonctionnement du C.P.U. 25 A. Eléments nécessaires à la compréhension 25

1. Mémoire et notion d’adresse (extension : modes d’adressage) 25 2. Les entrés – sorties 26

B. Traitement des instructions de base : instructions logiques, arithmétiques,… 31 1. Instruction 31 2. Registre de travail 32 3. Compteur ordinal 33 4. Traitement de l’instruction : décomposition, séquençage, pipeline 33

C. Traitement des instructions complexes : branchements, routines, interruptions 37 1. Branchements et implications sur le pipeline 37 2. Routines & pile 37 3. Interruption 39

D. Compilation 41 1. Notions de langage 41 2. La compilation 42 3. Exemples 42

Synthèse 47

Annexes 49 Annexe A : Bascules, compteurs & registres 51Annexe B : Jeu d’instructions, concepts CISC & RISC 59 Annexe C : Architectures Von Neumann & Harvard 65 Annexe D : Code source de l’exemple 69

Bibliographie 77

Index 79

- 5 -

Page 6: DORKEL Aymeric CHEVRET Anthony

- 6 -

Page 7: DORKEL Aymeric CHEVRET Anthony

Présentation

Avant de présenter plus en détail le fonctionnement des microcontrôleurs 8-bits,

nous allons pour commencer brièvement en décrire les composants principaux, mais également nous intéresser aux domaines dans lesquels ils sont utilisés, qui en sont les principaux producteurs et à quoi ressemblent-t-ils physiquement. Nous citerons aussi les dates clés de la naissance et de l’évolution des microcontrôleurs.

1. Définitions essentielles

Qu’est ce qu’un processeur ? Tiré de l’anglais « Central Process Unit (CPU) » (Unité centrale de traitement), le

processeur est une unité de traitement d’information. Il est capable d’exécuter un programme au rythme d’une fréquence fournie par un oscillateur. Tous les calculs et divers processus occasionnés lors du traitement de ce programme sont également gérés par le processeur. Il est cependant incapable de stocker tout un programme et les données qui sont nécessaires à son exécution. Pour fonctionner correctement, le processeur doit donc disposer d’au moins une mémoire où se trouvent ces différentes informations.

Qu’est ce qu’un microprocesseur ? Il remplie exactement les mêmes fonctions qu’un processeur mais ses dimensions lui

permettent de tenir sur un seul circuit intégré, le processeur pouvant quant à lui occuper plusieurs cartes.

Du à la généralisation du microprocesseur et à la disparition des processeurs volumineux, on confond par abus de langage les deux termes.

- 7 -

Page 8: DORKEL Aymeric CHEVRET Anthony

Qu’est ce qu’un microcontrôleur ? Le microcontrôleur est un circuit intégré comprenant essentiellement un

microprocesseur, ses mémoires et des éléments personnalisés selon l'application. Les éléments internes au microcontrôleur sont extrêmement variés, ils dépendent de la technologie du microcontrôleur, de son niveau de gamme, de sa marque. On peut dire que chaque model de microcontrôleur possède ses propres éléments internes mais certains d’entre eux se retrouvent dans la plupart des microcontrôleurs. Dans le schéma ci-dessous, on aperçoit les composants classiques tels un convertisseur analogique numérique (CAN) et des interfaces série et parallèle afin de communiquer avec l’extérieur.

Figure I.1.1 : schématisation simpliste de la composition d’un microcontrôleur

2. Utilisation du microcontrôleur Le microcontrôleur est un composant électronique programmable, peu encombrant

doté d’une basse consommation ; ses atouts le rendent facilement intégrable dans des produits utilisés au quotidien comme les appareils domestiques, les périphériques d'ordinateurs ou les automobiles. Il peut également entrer en compte dans la conduite de processus industriels ou même en tant que composant de missiles.

- 8 -

Page 9: DORKEL Aymeric CHEVRET Anthony

3. Dates clés pour les microcontrôleurs 8-bits Apparaissant au milieu des années quatre vingt, le microcontrôleur 8-bits a

beaucoup évolué jusqu’à aujourd’hui, ceci grâce aux améliorations consécutives des microprocesseurs et des mémoires qui y sont associées. La « loi de Moore » prévoit que le nombre de transistors inscriptibles sur une même surface de silicium double tous les dix huit mois, ce qui a permis d’utiliser des processeurs plus performants dans les microcontrôleurs ou d’en réduire la taille. L’évolution de l’ « EEPROM » (Electrically Erasable Read Only Memory / Mémoire à lecture seule effaçable électriquement) et l’apparition de la mémoire Flash qui allie vitesse élevée, durabilité et faible consommation ont également contribuées au développement des microcontrôleurs.

Suivant les utilisations faites du microcontrôleur, le choix entre les concepts « CISC » et « RISC » peut amener une amélioration substantielle. Ces concepts sont présentés en annexe.

1946 | Création de l' « ENIAC » (Electronic Numerical Integrator and Calculator /

Calculateur et intégrateur numérique électronique) par P. Eckert et J. Mauchly. L’« ENIAC » est considéré comme le premier ordinateur, il occupait alors plusieurs salles et ce programmait grâce à des câbles.

1947 | Invention du transistor par William Bradford Shockley, Walter H. Brattain et

John Bardeen. 1948 | Première machine de Von Neumann fonctionnant : la « Baby » a été

construite à l’université de Manchester. 1954 | Premier transistor commercial au silicium conçu par « Texas Instrument » 1958 | Invention du circuit intégré par Jack Kilby chez « Texas Instrument » 1968 | Fondation de « Intel » 1971 | Création du premier microprocesseur : le « 4004 » d’Intel, unité de calcul à 4

bits, cadencé à 108 kHz. 1984 | Fondation d’ « Atmel ».

| Motorola développe le microcontrôleur MC 68HC11 de 8 bits. 1989 | Fondation de « Microchip » et lancement de leur série PIC16C5X. 1990 | Premier microcontrôleur PIC de « Microchip » à 8 broches. 1995 | Premier microcontrôleur 8-bits RISC d’Atmel à mémoire Flash. 2003 | « Microchip » devient le premier fournisseur de microcontrôleurs 8-bits. 2004 | Motorola se sépare de sa filiale s’occupant des microcontrôleurs qui devient

« Freescale ».

- 9 -

Page 10: DORKEL Aymeric CHEVRET Anthony

4. Le marché du microcontrôleur Tout d’abord, voici une liste non exhaustive des principaux fournisseurs de

microcontrôleurs 8-bits. Analog Devices Atmel Cypress Dallas Fairchild

Infineon Maxim Microchip Temic Zilog

Texas Instruments On Semiconductor Philips Semiconductor Motorola (Freescale) National Semiconductor

Parmi tous les constructeurs de microcontrôleurs 8-bits se dégagent essentiellement

Atmel, Microchip Technology et Motorola qui est maintenant devenu Freescale. Ce dernier est un des premiers constructeurs et a fondé sa réputation notamment

grâce au MC 68HC11 qui est l’un des premiers microcontrôleurs 8-bits du marché. Atmel est plus connu pour ses séries « AVR 8-bits RISC » parmi lesquels figurent

trois niveaux de gamme : les « Attiny » représentant la gamme bon marché, les « At90 » pour le milieu de gamme et les « Atmega » regroupant le haut de gamme.

Dans le même style, trois catégories de performance sont également retrouvées chez Microchip. Il s’agit de trois groupes : « Baseline Architecture » (Architecture de base), « Mid Range Architecture » (Architecture de gamme moyenne) et « High Range Architecture » (Architecture haute gamme). La notoriété acquise au fil des années, notamment fondée sur la série des 16F8X, a permis à Microchip de devenir le premier fournisseur de microcontrôleurs 8-bits en 2003.

- 10 -

Page 11: DORKEL Aymeric CHEVRET Anthony

5. Boîtiers pour microcontrôleurs Le circuit du microcontrôleur est gravé dans du silicium, sa taille est très réduite, de

l’ordre de 0.2 mm². Afin de l’utiliser, il faut pouvoir l’installer sur un circuit. Pour cela, il est implanté dans différents boîtiers adaptés à ses différentes utilisations.

Boîtier PDIP Le boîtier PDIP (Plastic Dual Inline Package, que l’on peut traduire par boîtier

plastique à double rangé de pattes) est le plus “grand” des boîtiers disponibles, c’est à dire que pour un nombre de pattes donné, ses dimensions sont les plus élevées. Il s’agit du modèle le plus commun pour les prototypes et petites séries, ses dimensions nominales sont de 22,80mm x 7,94mm x 3,30mm (longueur x largeur x épaisseur) ce qui permet une implantation ne nécessitant pas de matériel dédié.

L’exemple qui suit est celui d’un PIC 16F628 de Microchip.

Figure I.5.1 : brochage 16F628 en boîtier PDIP Figure I.5.2 : Boîtier PDIP 18 pattes

Figure I.5.3 : Photo d’un PIC 16F628 en boîtier PDIP

11

Page 12: DORKEL Aymeric CHEVRET Anthony

Boîtiers SOIC et SSOP Afin d’intégrer au mieux les microcontrôleurs dans les circuits en réduisant la place

qu’ils occupent, de nouveaux standards ont été crées. La figure I.5.4 représente toujours une vue du PIC16F628 mais en boîtier SOIC (« Small Outline Integrated Circuit » traduisible par petit circuit intégré). Les caractéristiques sont différentes : 11,53mm x 10,34mm x 2,31mm (longueur x largeur x épaisseur).

Figure I.5.5 : Boîtier SSOP 20 pattes

Figure I.5.4 : Boîtier SOIC 18 pattes

La figure I.5.5 ne semble pas différer beaucoup de sa voisine mais en intégrant une

paire de patte supplémentaire, le 16F628 type SSOP (Shrink Small Outline Package/Petit circuit intégré rétréci) occupe encore moins d’espace : 7,80mm x 7,20mm x 1,75mm (longueur x largeur x épaisseur).

Boîtier QFN La figure I.5.6 représente un model carré de

microcontrôleur, il s’agit du 16F628 de type QFN (Quad Flat No leads package/Carré plat sans patte). L’espace utilisé est moindre puisque ses dimensions sont réduites afin de le rendre le plus plat possible : 6mm x 6mm x 0,90mm (coté x coté x épaisseur).

Figure I.5.6 : Boîtier QFN

- 12 -

Page 13: DORKEL Aymeric CHEVRET Anthony

Autre exemple de boîtier : TQFP Les microcontrôleurs disposant d’un nombre élevé d’entrés sorties ne sont que

rarement disponibles en boîtier type PDIP. Par exemple, l’ATMEL Atmega 128 n’est commercialisé que dans deux formats, dont le TQFP, « Thin Profile Plastic Quad Flat Package » (boîtier plat carré en plastique à profil fin).

6. Caractéristiques électriques

Figure I.5.7 : Atmega 128 en boîtier TQFP

La plupart des microcontrôleurs sont basés sur des circuits type C-MOS car cette

technologie n’induit qu’une faible consommation et permet donc d’utiliser une alimentation des plus simples ; or la fréquence interne du microcontrôleur est dépendante de la tension d’entrée donc celle-ci doit tout de même être assez élevée pour assurer le bon fonctionnement du programme.

La figure I.6.1 présente, ci-dessous, la gamme de tension acceptable par le PIC16F628 en fonction de la fréquence désirée.

Pour notre exemple, nous avons décidé de prendre une alimentation de 3V facilement concevable avec deux piles de 1,5V.

Figure I.6.1 : La région grisée indique la combinaison tension/fréquence acceptable pour le PIC16F628

- 13 -

Page 14: DORKEL Aymeric CHEVRET Anthony

- 14 -

Page 15: DORKEL Aymeric CHEVRET Anthony

Le choix d’un exemple : le digicode

Un exemple était nécessaire pour illustrer notre rapport et justifier nos affirmations par un cas concret. Les TIPE n’étant pas un projet de conception, nous nous sommes donc limité au minimum et avons décidé de créer un circuit des plus simples, un digicode. Celui-ci n’utilise que les fonctions de base du microcontrôleur et n’exploite quasiment aucun des périphériques que nous n’étudions pas.

1. Utilisation de notre circuit Lorsque le digicode fonctionne correctement et attend la saisie d’un code, la LED

verte clignote doucement, avec un rapport cyclique très faible. Lorsque l’utilisateur presse un bouton, la LED jaune s’allume, lorsqu’il le relâche,

elle s’éteint. Cela permet de confirmer chaque saisie. Pour entrer un code, il est nécessaire que l’intervalle de temps entre 2 touches soit

inférieur à 5s sinon il faut recommencer le code depuis le début. La même chose se produit lorsqu’une mauvaise touche ne correspondant pas au code est appuyée.

Lors de l’entrée du code valide, la LED verte clignote rapidement durant 8 secondes puis reste allumée 2 secondes. Tout autre code n’a aucun effet mis à part celui de reconfiguration.

- 15 -

Page 16: DORKEL Aymeric CHEVRET Anthony

La reconfiguration du code d’accès fait appel à l’utilisateur qui doit effectuer la suite des opérations suivantes :

Appuyer simultanément sur les 3 boutons d’une des diagonales du clavier, ce qui entraîne le clignotement de la LED rouge.

Saisir l’ancien code (si celui-ci n’est pas entré avant 4s, alors la modification du code d’accès est avortée). La bonne saisie sera indiquée par le clignotement de la LED verte (ainsi que la LED rouge)

Saisir le nouveau code, la LED jaune va clignoter (ainsi que la LED rouge) et la LED verte s’éteindre.

Saisir une nouvelle fois le nouveau code, la LED jaune s’arrête de clignoter après l’appui sur la première touche et reprend son rôle de confirmation de saisie.

Si le code a été retapé à l’identique alors la reconfiguration s’est effectuée avec succès et le nouveau code est en place ; sinon la procédure est arrêtée et c’est l’ancien code qui est actif.

Durant toute cette étape de reconfiguration, toute attente de plus de 4s sans appui entraînera la fin de la tentative de modification.

2. Schéma du circuit et explications de son fonctionnement Voici le schéma de notre digicode, suivit d’explications concernant son

fonctionnement.

Figure II.2.1 : schéma du circuit (valeurs des composants non significative)

- 16 -

Page 17: DORKEL Aymeric CHEVRET Anthony

Le connecteur J1 sert à la programmation du microcontrôleur. Grâce à la diode D5, la tension d’alimentation fournie lors de la programmation ne se propage pas dans le reste du circuit, ce qui nous permet de différencier la tension de programmation de la tension d’utilisation. Nous programmons le microcontrôleur en 5V, mais en phase d’utilisation, nous l’alimentons en 3V (grâce au connecteur J2), plus aisé à générer (deux piles 1.5 V AA en série suffisent). En mode programmation, nous devons appliquer une tension de 12V sur la patte MCLR du PIC, en utilisation, 3V. La diode D4 évite la propagation du 12V dans le circuit d’alimentation du mode utilisation.

Le clavier, composé des neufs boutons poussoirs PB1 à PB9, est du type « matriciel ». En effet, 6 fils suffisent pour lire l’état des neuf touches. Il nous suffit pour cela de placer à 5V les colonnes du clavier par les sorties du microcontrôleur et de lire l’état des entrées correspondant aux lignes. Si un bouton est appuyé, l’entrée sera à l’état haut, sinon, elle sera à l’état bas car tiré à la masse par les résistances R1 à R6.

Le microcontrôleur choisi supporte mieux un courrant entrant qu’un courant sortant, c’est pour cela que les LED sont commandées de façon inverse (une patte à l’état haut éteint la diode qui lui est connectée).

3. La carte et son typon

Figure II.3.1 : typon de la carte réalisé en simple face avec un seul pont On peut reconnaître sur le typon l’ensemble des composants du schéma. Le routage

a été déterminé par l’esthétique de la carte et certaines règles de tracé limitant les microcoupures et les erreurs, que nous ne détaillerons pas dans notre rapport.

- 17 -

Page 18: DORKEL Aymeric CHEVRET Anthony

4. Fonctionnement du programme C Pour décrire simplement le fonctionnement du programme exécuté par le

microcontrôleur, nous allons utiliser des logigrammes (parfois appelés « algorigrammes »). Ils permettent la suivit du déroulement de l’exécution sans nécessairement avoir à comprendre le code exécuté par le microcontrôleur.

Désignation des principaux éléments d’un logigramme

Figure II.4.1 :Début ou fin d’organigramme.

Figure II.4.2 :Traitement d’information. (entrées / sorties / données)

Figure II.4.3 :Sous programme : portion de programme considérée comme une simple opération.

Figure II.4.4 :Embranchement de test.

Figure II.4.5 :Renvoi : utilisé deux fois pour assurer la continuité lorsqu’une ligne n’est pas représentée.

Condition

Si condition réalisée

Si condition non réalisée

- 18 -

Page 19: DORKEL Aymeric CHEVRET Anthony

Programme de lancement Ce programme est celui qui est exécuté en premier par le microcontrôleur. Il nous

permet d’initialiser des variables et des états et de configurer le timer 1 pour qu’il lance l’exécution du programme principal toutes les 40ms.

Une variable w sert à stocker la position du chiffre du code actuellement attendu,

plus de détail sont disponibles dans le logigramme du programme principal.

Figure II.4.6 : logigramme d’attente du microcontrôleur

- 19 -

Page 20: DORKEL Aymeric CHEVRET Anthony

Programme principal Ce programme est appelé toutes les 40 ms par une interruption du timer 1,

configurée lors de l’initialisation.

Figure II.4.7 : logigramme de vérification du code d’accès

- 20 -

Page 21: DORKEL Aymeric CHEVRET Anthony

Gestion de la LED jaune La LED jaune doit s’allumer lors de l’appui sur une touche et s’éteindre lorsque

aucune touche n’est pressée. A chaque fois que nous voudrons actualiser son état, nous appellerons cette

fonction.

Figure II.4.8 : logigramme de confirmation de saisie d’une touche (gestion de l’état de la LED jaune)

- 21 -

Page 22: DORKEL Aymeric CHEVRET Anthony

LN Lecture du clavier : Cette fonction est appelée à chaque fois que l’on souhaite lire l’état du clavier. Elle

retourne le résultat dans la variable V. V peut prendre le numéro de la touche enfoncée, mais également 11 si trois touches diagonales sont pressées.

Figure II.4.9 : logigramme indiquant les touches enfoncées

- 22 -

Page 23: DORKEL Aymeric CHEVRET Anthony

M configReconfiguration du code : Ce programme est appelé lors de l’entrée en procédure de reconfiguration du code.

Figure II.4.10.a : début du logigramme de reconfiguration du code d’accès

- 23 -

Page 24: DORKEL Aymeric CHEVRET Anthony

Figure II.4.10.b : fin du logigramme de reconfiguration du code d’accès

- 24 -

Page 25: DORKEL Aymeric CHEVRET Anthony

Le fonctionnement du C.P.U.

A. Eléments nécessaires à la compréhension

La partie suivante concerne les mémoires, pour de plus amples informations sur leur

fonctionnement, consulter les annexes A et C.

1. Mémoire et notion d’adresse Un microcontrôleur a besoin de mémoire pour fonctionner, aussi bien pour stocker

les instructions qu’il doit exécuter que pour stocker des variables de travail. Celle-ci peut être constituée de bascules RS. A chaque bit correspond une bascule.

Vu qu’il ne peut être physiquement connecté à plusieurs milliers de bits de mémoire

simultanément, un système d’adressage a été mis en place. Le microcontrôleur donne l’adresse de la partie de la mémoire qu’il veut consulter et peut soit y écrire soit en lire la valeur.

La majorité des microcontrôleurs utilisent deux “ zones de mémoires ” : une pour le

programme et une pour les variables. Cette séparation comporte de nombreux avantages, dues aux différences d’utilisation de ces mémoires. La mémoire contenant le programme n’est modifiée que lors de la programmation du composant, elle est bien plus souvent lue. Elle doit également être sauvegardée lors de coupures d’alimentation. La technologie utilisée est couramment la mémoire “ flash ”. La mémoire contenant les données est autant lue qu’écrie. Elle n’a pas besoin d’être préservée lors des coupures d’alimentation, car celles-ci provoquent de toute façon un redémarrage du composant.

Si on donnait une adresse à chaque bit de mémoire, la quantité d’adresses serait très

élevée. L’adressage se fait donc par octets, c’est à dire par groupes de bits. Dan des le cas de la mémoire destinée aux données, ces groupes sont des octets, c’est à dire des groupes de huit bits.

Une adresse est une donnée, elle possède donc un type. Il s’agit d’un entier non

signé. La taille de celui-ci dépend beaucoup de l’architecture du microcontrôleur. Par exemple, les microcontrôleurs Atmel Atmega utilisent des adresses mémoire stockées sur deux octets. Un calcul des plus simples nous montre que cela limite l’adressage à 65536 octets de mémoire, ce qui est amplement suffisant pour un microcontrôleur. Les modèles Microchip PIC 16F utilisent des adresses mémoire codées sur sept bits (souvent stockées dans une variable d’un octet), ce qui limite l’adressage à 128 octets de mémoire, ce qui est insuffisant pour des applications complexes. Pour palier ce problème, ce constructeur a organisé la mémoire de ses microcontrôleurs en plusieurs “ banques de mémoire ” (“ rambank ”) Le 16F88 en dispose de quatre. Pour accéder à un octet, il faut configurer la banque de mémoire utilisée et ensuite donner son adresse.

- 25 -

Page 26: DORKEL Aymeric CHEVRET Anthony

Etant donné que ce mode de gestion de la mémoire en complique l’accès (il faut toujours spécifier la banque utilisée puis l’adresse), le constructeur a placé sur certains modèles une partie de la mémoire de chaque banque en commun. Par exemple, sur le 16F88, les 16 derniers octets de chaque banque correspondent à la même mémoire.

L’accès à des variables dont on peut avoir besoin couramment est grandement

simplifié, il n’est plus nécessaire de spécifier la banque de mémoire à laquelle elles appartiennent. Par contre, cette méthode restreint la quantité totale de mémoire adressable : sans cette subtilité, quatre banques utilisant des adresses sur sept bits permettaient d’adresser 4x128 = 512 octets de mémoire. Avec celle-ci, on ne peut qu’adresser 4x(128-16)+16 = 464 octets de mémoire. Cet inconvénient n’est pas gênant car le 16F88 ne dispose pas d’autant de mémoire.

2. Les entrées - sorties Pour communiquer avec le circuit dans lequel ils sont implantés, les

microcontrôleurs utilisent les niveaux de tension électrique des pattes de leurs boîtiers. A part certaines aux fonctions essentielles (alimentation par exemple), la majorité sont utilisables comme des entrées - sorties (I/O : input/output), ce qui leur permet aussi bien de recevoir des informations provenant de l’extérieur du microcontrôleur que d’en transmettre.

Le programme du microcontrôleur peut donc définir une patte comme étant une

sortie et y appliquer un niveau logique ou comme étant une entrée et en lire le niveau logique.

Dans le cas du digicode illustrant ce document, certaines pattes configurées en sorties permettent

d’allumer ou non des LED, quand d’autres configurées en entrée servent à lire l’état des boutons du clavier.

Les entrées - sorties constituent le périphérique le plus basique du microcontrôleur.

La méthode utilisée par le processeur pour communiquer avec ce périphérique est similaire avec celles utilisées pour communiquer avec tous les autres (convertisseur analogique/numérique, bus, etc.), c’est pourquoi c’est le seul périphérique qui est présenté dans ce dossier.

Les pattes des microcontrôleurs sont regroupées en ports, un port correspond à huit pattes. A chaque port sont associés plusieurs octets de configuration, selon le type de microcontrôleur. Dans chacun de ces octets, un bit correspond à une patte du circuit.

Pour protéger le composant des surtensions, on trouve

généralement deux diodes connectées comme le montre la figure III.A.2.1. Si la tension appliquée à la patte dépasse la tension d’alimentation du microcontrôleur majorée de la tension de polarisation de D1, le courant circule de la patte vers l’alimentation. Si elle est inférieure à la masse de plus de la tension de polarisation de D2, le courant circule de la patte vers la masse. Dans de nombreux cas, cette circulation de courant protège l’entrée car elle provoque une chute de tension sur la patte.

Figure III.A.2.1 : protection d’une entrée

- 26 -

Page 27: DORKEL Aymeric CHEVRET Anthony

Le cas des modèles 16F de Microchip Ces microcontrôleurs associent à chaque port deux registres, nommés TRIS et

PORT. Le registre TRIS sert à définir les pattes comme des entrées ou des sorties, un état haut correspond à une entrée, un état bas à une sortie. La lecture du registre PORT permet d’obtenir le niveau de tension appliqué à une patte, si celle-ci est configurée en sortie, l’écriture dans le registre PORT permet de lui affecter un état.

La figure A représente le schéma électrique simplifié de câblage d’une patte. Le bit

du registre PORT correspondant à cette patte est représenté par la bascule « données », celui du registre TRIS par la bascule « sens ». Lorsque « sens » est à l’état haut, les deux interrupteurs N et P sont ouverts, aucune tension n’est imposée sur la patte. Lorsque sens est à l’état bas, si « données » est à l’état haut P est fermé et N est ouvert, si « données » est à l’état bas P est ouvert et N est fermé. Lors de la lecture de TRIS, la valeur de la bascule « sens » est placée sur le bus de données. Lors de la lecture de PORT, l’état de la patte est stocké dans la bascule « lecture » et la sortie de celle-ci est placée sur le bus de données.

Figure III.A.2.2 : câblage simplifié d’une patte de PIC 16F

- 27 -

Page 28: DORKEL Aymeric CHEVRET Anthony

Le cas des modèles Atmega d’ ATMEL Contrairement à leurs homologues de Microchip, les ATMEL Atmega associent à

chaque port trois registres : DDR (Data Direction Register, Registre d’Orientation des Données), PORT et PIN. Deux registres n’étaient pas suffisants car sur ces modèles on peut activer une résistance de tirage aux entrées.

La figure B représente le schéma électrique simplifié de câblage d’une patte. La mise

à l’état haut de DDR désactive la résistance de tirage et place l’état logique de PORT sur la patte. La mise à l’état bas de DDR permet l’activation de la résistance de tirage en fonction de l’état de PORT et n’impose plus d’état à la patte, qui est alors configurée en entrée. Le registre PIN continent toujours la valeur logique de la patte, mais le module de synchronisation induit un décalage entre le contenu du registre et l’état réel de la patte. Les fonctions « sommeil » du microcontrôleur influent sur les entrées de celui-ci pour en diminuer la consommation électrique comme le montre le schéma, mais ce point ne sera pas abordé.

Figure III.A.2.3 : câblage simplifié d’une patte d’ATMEL Atmega

- 28 -

Page 29: DORKEL Aymeric CHEVRET Anthony

Les cas plus complexes Pour beaucoup de pattes les schémas de câblage simplifiés contrôlant réellement

leur état sont bien plus complexes que ceux présentés, pour plusieurs raisons. Les autres périphériques des microcontrôleurs sont souvent multiplexés avec des entrées/sorties et prennent le contrôle de la patte lorsqu’ils sont activés. Des systèmes de déclenchement d’interruptions sont parfois associés à des pattes, afin de permettre l’exécution d’une partie précise du programme en cas de changement d’état logique de la patte.

- 29 -

Page 30: DORKEL Aymeric CHEVRET Anthony

- 30 -

Page 31: DORKEL Aymeric CHEVRET Anthony

B. Traitement des instructions de base : instructions logiques, arithmétiques,…

1. Instruction Une instruction est une opération élémentaire que le microcontrôleur peut

accomplir. Le programme que celui-ci exécute est une suite d’instructions, stockées dans la mémoire programme.

Exemple d’instruction : incrémenter un registre Les instructions sont divisées en deux parties distinctes : le code opération qui

représente l’action que le microcontrôleur doit accomplir et le code opérande qui correspond au(x) paramètre(s) nécessaire(s) à cette action.

Dans l’instruction “ ajouter 5 ”, “ ajouter ” est le code opération, “ 5 ” est le code

opérande. La dimension de ces deux parties n’est pas constamment la même, mais dans tous

les cas la totalité de l’instruction a une dimension définie, liée au mode d’adressage de la mémoire stockant le programme. Par exemple, sur les microcontrôleurs Microchip PIC 16F, les instructions sont stockées sur 14 bits. La figure III.B.1.1 montre la répartition opération – opérande pour différentes instructions.

On peut classer les instructions en plusieurs grandes catégories.

Les opérations arithmétiques et logiques (additions, opérations de logique sur les octets)

Les opérations sur les bits (opérations de logique bit à bit) Les opérations de test et de branchement (saut à une instruction donnée du

code, saut conditionnel) Les instructions de transfert de données (chargement d’une valeur de la

mémoire dans un registre, écriture d’une valeur d’un registre dans la mémoire)

Les instructions spécifiques (concernant les modes du microcontrôleur, les périphériques)

- 31 -

Page 32: DORKEL Aymeric CHEVRET Anthony

Figure III.B.1.1 : répartition opération – opérande pour différents types d’instructions

2. Registre de travail Un registre de travail est une unité de mémoire très proche du cœur du

microprocesseur, sur laquelle il peut influer très simplement. La majorité des instructions utilisent le ou les registres de travail du microcontrôleur.

Les microcontrôleurs disposent d’un nombre plus ou moins élevé de registres de travail. Par exemple, le PIC 16F88 ne dispose que d’un unique registre de travail, nommé W (comme “ Work ”, travail, en anglais). L’Atmega 128 dispose de 32 registres de travail.

L’instruction “ ajouter 5 ” agit directement sur un registre de travail : celui-ci se voit

incrémenté de 5.

- 32 -

Page 33: DORKEL Aymeric CHEVRET Anthony

3. Compteur ordinal Les instructions du code exécuté par le microcontrôleur sont traitées les unes après

les autres. Pour connaître l’instruction qu’il doit traiter, le microcontrôleur place l’adresse de celle-ci dans le compteur ordinal, un registre de la taille des adresses de la mémoire du code. Lorsque le microcontrôleur effectue une suite d’instructions sans test conditionnel, la valeur du compteur ordinal évolue de façon croissante. Il contient tout d’abord l’adresse de la première instruction à exécuter, notons cette adresse x. Après le traitement de celle-ci, il contient l’adresse de l’instruction suivante, x+1. Ses valeurs successives seront donc x, x+1, x+2, etc.

Lors d’une instruction de branchement, ou lors de certains cas de test conditionnel, le compteur ordinal est directement modifié : les instructions ne sont plus traitées les unes après les autres.

4. Traitement de l’instruction : décomposition, séquençage, pipeline Une instruction, malgré sa simplicité, ne peut souvent pas être traitée en un seul

cycle d’horloge. En effet, il faut dans tous les cas lire l’instruction dans la mémoire du code, l’interpréter, l’exécuter. Un séquenceur se charge donc de la décomposer en instructions élémentaires, qui peuvent êtres exécutées en un seul cycle.

Les microcontrôleurs Microchip PIC de la famille 16F décomposent l’exécution

d’une instruction en quatre phases. Ces quatre cycles expliquent le fait que pour cette famille de microcontrôleur, la fréquence de traitement des instructions correspond au quart de la fréquence d’horloge. Par exemple, si un pic 16F88 est cadencé à 8 MHz, sa capacité sera de 2 Mips (“ Mega Instruction Per Second ”, millions d’instructions par seconde).

Cette opération de décomposition est nommée “ séquençage de l’instruction ”, elle

est effectuée par un séquenceur. Pour mieux expliquer ce fonctionnement, voici le cas de la décomposition de

l’instruction “ ajouter 5 au registre de travail ” sur un PIC 16F. La mnémonique de cette instruction est ADDLW, ajouter une constante à W. En binaire, dans la mémoire programme, on retrouvera le code suivant : 11 111x kkkk kkkk, avec ’x’ correspondant à un bit non significatif et la série de k à l’opérande, ici 5, ce qui donnera soit 11 1111 0000 0101 soit 11 1110 0000 0101. Nous considérerons le premier cas.

Premier cycle : décodage Le code opération de l’instruction est traité. Pour donner une explication simple, on

pourrait dire que dans le CPU, il existe un bit par instruction. Durant ce cycle, le bit correspondant à l’instruction “ ajouter une valeur au registre de travail ” est mis à un, grâce à une logique combinatoire élémentaire câblée à partir de portes logiques : une porte ET ayant cinq entrées correspondant aux cinq bits de poids le plus fort.

- 33 -

Page 34: DORKEL Aymeric CHEVRET Anthony

Second cycle : lecture de la constante La constante, c’est à dire l’opérande, stockée dans les huit bits de poids les plus

faibles de l’instruction, est pris à part et placée dans un registre de l’additionneur, partie de l’ALU (“ Arithmetic and Logic Unit ”, unité de traitement arithmétique et logique, voir annexe A).

Troisième cycle : addition

Ce cycle donne le temps à l’ALU d’effectuer l’addition. En effet, à la fin du cycle précédent, elle a reçu la valeur qu’elle doit ajouter au registre de travail, elle peut maintenant effectuer l’opération.

Quatrième cycle : écriture du résultat dans W

Une fois l’addition effectuée, le résultat est copié dans le registre de travail. En effet, l’ALU utilisait le registre de travail comme entrée durant le troisième cycle, elle ne pouvait donc pas y écrire simultanément, elle a donc stocké le résultat de l’opération dans un registre temporaire, qui est maintenant copié vers le registre de travail.

Pour encore accélérer le traitement, la lecture de l’instruction depuis la mémoire du

code vers un registre d’instruction est effectuée durant le traitement de l’instruction précédente (l’influence des instructions de branchement sera traitée dans le paragraphe III.C.1). C’est ce qu’on appelle un pipeline à deux niveaux : chaque instruction est traitée en deux temps, et deux instructions sont traitées simultanément.

Figure III.B.4.1 : Schéma récapitulatif du traitement des instructions sur un microcontrôleur Microchip PIC 16F OSC1 représente la fréquence d’horloge. Q1 à Q4 représentent les quatre phases de traitement d’une instruction. PC représente la valeur du compteur ordinal. CLKOUT représente la fréquence de traitement des instructions (on peut demander au microcontrôleur de la placer en sortie sur une patte du circuit) En bas de diagramme, on voit le traitement des instructions. “ Fetch INST ” correspond au chargement de l‘instruction et “ Execute INST ” correspond à son exécution.

- 34 -

Page 35: DORKEL Aymeric CHEVRET Anthony

Figure III.B.4.2 : Schéma simplifié du CPU d’un microcontrôleur Microchip PIC 16F

- 35 -

Page 36: DORKEL Aymeric CHEVRET Anthony

- 36 -

Page 37: DORKEL Aymeric CHEVRET Anthony

C. Traitement des instructions complexes

1. Branchements et implications sur le pipeline Comme expliqué précédemment, les instructions sont décomposées par le

séquenceur afin de pouvoir être traitées comme une suite d’opérations des plus simples. Pour gagner du temps, un pipeline à deux niveaux permet de traiter les premières opérations constituant une instruction pendant que les dernières opérations de l’instruction précédentes sont effectuées.

Lors d’un branchement, qui correspond par exemple à l’instruction n, vers l’instruction x, le compteur ordinal est modifié durant le traitement des dernières opérations qui la constitue. Pendant le même temps, les premières opérations de l’instruction suivante, n+1, étaient déjà traitées. La modification du compteur indique que l’instruction n+1 ne sera pas traitée, mais l’instruction x le sera. Le traitement des premières étapes de l’instruction n+1 a été inutile. Le processeur perd donc un cycle durant lequel il traite les premières opérations de l’instruction x. On dit alors qu’un saut ou un branchement « casse » le pipeline.

Dans le cas des branchements conditionnels, deux situations existent : soit la condition est validée, le saut sera donc effectué, le pipeline brisé et on considère donc que le branchement conditionnel nécessite deux cycles (test et saut), soit la condition n’est pas vérifiée et l’instruction ne nécessitera qu’un cycle.

2. Routines et pile Dans les programmes destinés à êtres exécutés par les microcontrôleurs, on trouve

très souvent un grand nombre d’opérations récurrentes. En effet, si par exemple l’utilisation de l’EEPROM est nécessaire, il faudra couramment effectuer la suite d’opérations pour y écrire ou y lire des données. Pour éviter d’avoir à écrire la suite d’instructions correspondant à ces opérations très souvent dans le programme, et donc augmenter considérablement sa taille, on fait appel à des routines, aussi appelées fonctions, ou « sub ».

Ces fonctions reçoivent des paramètres et renvoient une valeur. Ces paramètres et cette valeur de retour sont des variables.

Le code correspondant à une fonction, c’est à dire la suite d’instructions qui la

constitue, est stocké dans une plage de la mémoire programme. Lors d’un appel de cette fonction, le CPU va exécuter le code de la fonction puis revient au code d’appel. Il doit donc sauvegarder la valeur du compteur ordinal lors de l’appel pour pouvoir y revenir après l’exécution de la fonction.

Exemple : à l’instruction n, un code appel une fonction débutant à l’instruction j et se terminant à

l’instruction j+k. Les instructions seront donc effectuées dans l’ordre suivant : …, n-2, n-1, n [saut], j, j+1, …, j+k-1, j+k [retour], n+1, n+2, …

- 37 -

Page 38: DORKEL Aymeric CHEVRET Anthony

Pour les microcontrôleurs Microchip PIC 16F, un appel de fonction correspond à l’instruction CALL et un retour à l’instruction RETURN.

Une fonction peut appeler une autre fonction. Il faudra alors sauvegarder deux

valeurs du compteur ordinal, pour pouvoir exécuter le code dans le bon ordre. Cette autre fonction peut à nouveau appeler une fonction, et ce un grand nombre de fois. Il est donc nécessaire d’enregistrer un grand nombre de valeurs du compteur ordinal, pour pouvoir revenir au code à exécuter à la fin de chaque appel de fonction.

Pour palier ce problème, une pile est utilisée. Il s’agit d’une zone de mémoire dans

laquelle les valeurs du compteur ordinal sont écrites les unes après les autres. Un pointeur de pile permet de trouver la dernière ayant été inscrite. A chaque appel de fonction, la valeur du compteur ordinal est « empilée », c’est à dire copiée à la suite de la pile, et le pointeur de pile incrémenté. A chaque retour (fin de fonction), le compteur ordinal est « dépilé », c’est à dire lu à partir de la pile, et le pointeur de pile est décrémenté.

Il existe différentes méthodes pour implanter une pile. Les microcontrôleurs

Microchip PIC 16F utilisent une pile dite « en hard », c’est à dire une zone de mémoire dédiée à cette activité, et dont la taille est limitée, dans leur cas à huit empilages. Cette zone a la dimension du compteur ordinal, donc treize bits dans leur cas. Les microcontrôleurs ATMEL Atmega utilisent une pile « en soft » : la pile est une partie de la mémoire destinée aux données. La première position pointée par le pointeur de pile est la dernière adresse de la mémoire, et lors des empilements, celui-ci diminue.

Une pile « en hard » est plus sécurisante. En effet, seules les fonctions d’appel et de

retour de fonction y accèdent, et aucune donné ne peut y être écrite. Elle permet aussi d’avoir une dimension optimale, celle du compteur ordinal. Malheureusement, sa taille est limitée, dans le cas des 16F à huit niveaux et dans le cas des 10F à seulement deux niveaux.

Une pile « en soft » permet plus de libertés. En effet, des instructions d’empilement

et de dépilement sont disponibles et le programme peut placer tous types de données sur la pile, comme par exemple les paramètres à transmettre aux fonctions lors de leur appel. Malheureusement elle nécessite plus d’attention pour deux raisons. Si la pile progresse vers le début de la mémoire de données et que les données sont stockées du début vers la fin de cette même mémoire, une collision est possible et un écrasement mutuel peut se produire, ce qui mènera à une instabilité certaine. Si les opérations d’empilement et de dépilement ne sont pas effectuées dans un ordre strict, un décalage peut intervenir et altérer une fois encore les données.

Les compilateurs de langages de plus haut niveau comme le C ou le Basic sont

beaucoup plus à l’aise avec une pile « en soft », qui leur permet d’exploiter pleinement le processeur. Les piles « en hard » sont bien plus contraignantes, que ce soit pour le passage d’arguments lors d’utilisation de la fonction dans le code principal et dans des interruptions ou pour l’utilisation d’appels récursifs.

- 38 -

Page 39: DORKEL Aymeric CHEVRET Anthony

3. Interruptions Les processeurs qui sont au cœur des microcontrôleurs ont besoin d’être très

réactifs par rapport aux évènements des éléments qui les entourent et qui proviennent de leurs périphériques. En effet, ils exécutent souvent une tâche de fond mais doivent effectuer un traitement d’urgence lorsqu’un périphérique déclare un événement, qui peut aussi bien être la fin d’un travail qu’une modification de l’état d’une patte du composant.

Pour répondre à cette situation, les microcontrôleurs disposent d’interruptions, sortes de fonctions appelées dès qu’un événement survient. Un code en train d’être exécuté peut être mis en attente pour laisser place au traitement d’une tâche plus urgente.

Les microcontrôleurs Microchip PIC 16F disposent par exemple d’une interruption liée au

changement d’état de la patte RB0. Lorsque celle-ci est activée, en cas de changement sur la patte en question, un code sera exécuté.

Il existe un endroit du code où sont inscrit les adresses des codes à exécuter en cas

d’interruption. Cette zone est nommée « table des vecteurs d’interruptions ». Sur les microcontrôleurs Microchip PIC 16F, il s’agit des premiers octets de la mémoire programme.

Lors de son exécution, le microcontrôleur utilise plusieurs registres, dont le ou les

registres de travail ainsi que des registres d’état. Vu qu’il peut être interrompu à tout moment, il faut sauvegarder l’état de ces registres au début de l’exécution du code d’interruption et les restaurer à la fin de celle-ci. L’exemple du code du digicode lié à ce dossier le montre clairement.

Une interruption fait « perdre » plusieurs cycles au microcontrôleur, en effet tout

comme un appel de fonction il nécessite d’empiler le compteur ordinal et de briser le pipeline, autant à l’appel qu’au retour.

- 39 -

Page 40: DORKEL Aymeric CHEVRET Anthony

- 40 -

Page 41: DORKEL Aymeric CHEVRET Anthony

D. Compilation

Les microcontrôleurs ne cessent d’êtres améliorés. La complexité et la puissance de

calcul des modèles les plus récents rendent leur programmation en langage assembleur longue et pénible. La compilation est l’étape qui permet de passer d’un code dans un langage de haut niveau au langage machine. Ce chapitre en décrit les fondements et donne de nombreux exemples.

1. Notions de langage Les langages de programmation sont dits “ artificiels ”. En effet, contrairement aux

langues vivantes, ils n’évoluent pas avec leurs utilisateurs, qui les modifient constamment, mais grâce à des normes, qui décrient des versions. Il sont destinés à traduire un fonctionnement précis, dans notre cas un programme, et ne peuvent, contrairement aux langues vivantes, se suffirent à eux-mêmes ; les commentaires dans les codes sources en sont la première preuve.

Le langage machine est l’ensemble du code contenu dans la mémoire programme du

microcontrôleur. Il est quasiment illisible par l’homme. L’assembleur (ASM) est un langage dit de bas niveau. En effet, c’est une traduction

du langage machine, agrémenté d’artifices le rendant plus facilement utilisable par l’homme, comme les définitions (couramment noté EQU). A quasiment chaque instruction en assembleur correspond une instruction en langage machine.

Le C est un langage de plus haut niveau. La lecture du code est plus simple, son

écriture plus rapide et plus efficace, mais il nécessite une étape de compilation avant de pouvoir être traduit en langage machine. Malgré tout, il reste plus proche du système utilisé que les langages de très haut niveau, comme le basic par exemple.

- 41 -

Page 42: DORKEL Aymeric CHEVRET Anthony

2. La compilation Le passage d’un langage de haut niveau comme le C au langage machine se fait en

plusieurs étapes. En général, un compilateur transforme les fichiers sources (*.c) en fichiers objets (*.o). A chaque fichier source correspond un fichier objet. Un linker (éditeur de liens) relie ensuite ces fichiers objets entre eux afin de constituer un fichier final par exemple *.hex) qui pourra être transféré dans le composant.

La compilation transforme entre autre le code constituant les fonctions en code

machine et donne des adresses aux variables dans la pile. Le compilateur doit transformer des instructions complexes, comme la multiplication de grands nombres entiers (supérieurs à 255), en une suite d’instructions pouvant êtres exécutées par le microcontrôleur. Selon le modèle de ce dernier, il disposera de plus ou moins de possibilités.

Le linker relie les fonctions entre elles, adresse toutes les instructions (pour les sauts, les branchements), adresse les variables globales.

3. Exemples Pour expliquer la phase de compilation mais également pour montrer certaines de

ses faiblesses, nous allons étudier le code généré par deux compilateurs pour deux architectures à partir de programmes extrêmement simples écrits en C.

Première situation : Composant : Microchip PIC 16F628 Environnement : MPLAB IDE v7.01 Compilateur C : B Knudsen Data CC5X v3.1K Désassembleur : IC-Prog 1.05D incluant WinDis84 Seconde situation : Composant : ATMEL Atmega128 Environnement : WinAVR v20050214 Compilateur : GCC 3.4.3 avec avr-libc 1.2.3 Désassembleur : objdump (GNU Utils) Malheureusement, les codes utilisés sur les deux composants ne sont pas totalement

compatibles. En effet, celui écrit pour l’Atmega respecte le standard gnu99 (c99, évolution de l’ANSI C, agrémenté d’extensions propres à GCC) et celui écrit pour le PIC est un dérivé du C adapté au compilateur. Le code dépend aussi des registres des composants.

- 42 -

Page 43: DORKEL Aymeric CHEVRET Anthony

Simple addition Ce premier exemple montre l’addition des valeurs de deux ports dans une variable,

et la copie de cette variable sur un port. Sur PIC : Code C :

int c = PORTA + PORTB; PORTA = c ;

Code ASM généré :

BCF 0x03,5 BCF 0x03,6

MOVF 0x06,W ADDWF 0x05,W

MOVWF 0x20 MOVF 0x20,W MOVWF 0x05

Les deux premières instructions permettent de se placer dans la première banque de

mémoire de données, en mettant à 0 les deux bits destinés à la sélection de la banque. La valeur du port B est ensuite chargée dans le registre de travail, auquel est alors ajoutée la valeur du port A. Le registre de travail est copié à l’emplacement mémoire attribué à la variable ‘c’. La variable ‘c’ est à nouveau chargée dans le registre de travail, puis finalement placée sur le port.

Le compilateur a traduit chaque instruction écrite en C, sans tenter d’optimiser le code. On peut dire, en ne tenant pas compte de la sélection de la banque mémoire, qu’il a fallut 5 cycles pour traiter la tâche.

Sur Atmega : Code C :

unsigned char c = PINA + PINB; PORTB = c;

Code ASM généré : in r24,57-0x20

in r25,54-0x20 add r24,r25

out 56-0x20,r24

Les valeurs des deux ports sont copiées dans les registres r24 et r25. L’addition est ensuite effectuée, avec résultat écrit dans r24. Le contenu de r24 est finalement copié sur le port.

On note que le compilateur a optimisé le code écrit en C, il n’a pas utilisé de variable temporaire. Quatre cycles ont suffit pour traiter la tâche.

- 43 -

Page 44: DORKEL Aymeric CHEVRET Anthony

Addition avec retenue Sur PIC : Code C :

long f = d + e; Code ASM généré :

MOVF e+1,W ADDWF d+1,W

MOVWF f+1 MOVF e,W

ADDWF d,W MOVWF f

BTFSC 0x03,Carry INCF f+1,1

‘e’ représente l’adresse de la variable e, ‘d’ celle de la variable ‘d’, ‘f’ celle de la

variable ‘f’, ‘Carry’ le bit de STATUT de retenue. L’addition de deux nombres de 16 bits a été décomposée en additions de nombres

de 8 bits avec retenue. Huit cycles sont nécessaires. Sur Atmega : Code C :

unsigned short f = d + e; Code ASM généré :

in r25,57-0x20 in r24,54-0x20

add r24,r25 mov r25,__zero_reg__ adc r25,__zero_reg__

out 56-0x20,r24 Le cheminement est similaire, mais deux registres de travail sont utilisés. La tâche

est effectuée en six cycles.

- 44 -

Page 45: DORKEL Aymeric CHEVRET Anthony

Multiplication d’entiers de 8 bits Sur PIC : Code C :

int g = PORTA * PORTB;

Code ASM généré : MOVF PORTA,W

MOVWF C2tmp MOVLW .8

MOVWF C1cnt m001 : BCF 0x03,Carry

BCF 0x03,RP0 BCF 0x03,RP1

RLF g,1 RLF C2tmp,1

BTFSS 0x03,Carry GOTO m002

MOVF PORTB,W ADDWF g,1

m002 : BCF 0x03,RP0 BCF 0x03,RP1

DECFSZ C1cnt,1 GOTO m001

‘m001’ et ‘m002’ représentent des labels, utilisés par les sauts. Ils seront traduits en

adresses dans le code machine. On voit que le code est très long et nécessite un grand nombre de cycle, car la

multiplication a été décomposée en opérations très basiques, comme l’addition, le décalage de bits et le test.

Sur Atmega : Code C :

PORTB = PINA * PINB; Code ASM généré :

in r24,57-0x20 in r25,54-0x20

mul r24,r25 mov r24,r0

clr r1 out 56-0x20,r24

Le code généré est nettement plus court, et ne nécessite que 7 cycles. Ceci est

possible car l’Atmega dispose d’un multiplicateur “ en hard ”, c’est à dire d’une instruction permettant de multiplier deux variables (ici ‘mul’, qui multiplie deux variables en deux cycles d’horloge). On voit clairement que les compilateurs doivent s’adapter aux architectures pour lesquelles ils génèrent un code machine.

- 45 -

Page 46: DORKEL Aymeric CHEVRET Anthony

- 46 -

Page 47: DORKEL Aymeric CHEVRET Anthony

Synthèse

Les microcontrôleurs 8-bits permettent d’utiliser la puissance offerte par les

composants programmables, et ce sans avoir à souffrir des contraintes imposées par les microprocesseurs. En effet, leur fort taux d’intégration les rend très souvent quasiment autonomes et capables de s’adapter à tout type de besoin. Leur faible consommation électrique ainsi que leur petite taille en font des composants très adaptés aux systèmes embarqués, leur capacité à être reprogrammé rend les applications dont ils font partie très évolutives.

Le fonctionnement relativement simple de ces composants, aux nombreuses

similitudes avec les premiers microprocesseurs, rend également leur utilisation très accessible, ce qui ne nécessite pas de posséder des connaissances trop pointues en électronique ou informatique pour pouvoir s’en servir.

La démocratisation des microcontrôleurs 8-bits et la multiplication des formats dans

lesquels ils sont disponibles leur a permis de conquérir le marché de l’électronique numérique voir même parfois analogique. En moins de vingt ans, ils ont révolutionné notre façon de concevoir et risquent durant les années à venir de continuer à nous surprendre au travers des diverses applications dans lesquelles ils prendront place.

- 47 -

Page 48: DORKEL Aymeric CHEVRET Anthony

- 48 -

Page 49: DORKEL Aymeric CHEVRET Anthony

Annexes

Annexe A : Bascules, compteurs & registres 51 1. Bascules : fonctions mémoire et outils pour les compteurs 51 2. Compteur 55 3. Registre 56 4. BUS 57 5. ALU 57

Annexe B : Jeu d’instructions, concepts CISC & RISC 59 1. CISC 59 2. RISC 61 3. Evolution et amélioration des concepts RISC et CISC 61

Annexe C : Architectures Von Neumann & Harvard 65 1. Architecture « Von Neumann » 65 2. Architecture « Harvard » 66

Annexe D : Code source de l’exemple 69

- 49 -

Page 50: DORKEL Aymeric CHEVRET Anthony

Annexe A : Bascules, compteurs & registres

1. Bascules : fonctions mémoire et outils pour les compteurs

Rappels Les fonctions NOR et NAND sont les fonctions universelles c’est à dire que l’on

peut câbler toute équation logique uniquement à l’aide de ces fonctions.

Synchrone /Asynchrone Une bascule est dite synchrone lorsque l’état de ses sorties n’évolue que lors d’un

évènement comme par exemple l’état haut d’un signal d’horloge ou un front montant (ou descendant) de celui-ci.

Une bascule est dite asynchrone lorsque ses sorties dépendent continuellement des états de ses entrées.

Bascule RS asynchrone (Reset Set) 2 entrées : Set et Reset (mise à 1, mise à 0) 2 Sorties : Q et /Q complémentaires Figure A.1.1 : représentation d’une

bascule RS Principe Constituées de portes logiques, les bascule RS permettent de créer une fonction

mémoire à deux états. C’est à dire que lorsque aucune information n’est envoyée à la bascule (R et S à l’état

bas ou /R et /S à l’état haut), la valeur de sortie de celle ci reste la même qu’à l’état précédent.

Le « set » commande la mise à un de la sortie de la bascule. A l’opposé le « reset » commande la mise à zéro de la sortie de la bascule.

Câblage avec des portes NOR (NON OU) Table de vérité

R S Q /Q 0 0 Etat précédent 0 1 1 0 1 0 0 1 1 1 Etat interdit

- 51 -Figure A.1.2 : Câblage d’une bascule RS avec des portes NAND

Page 51: DORKEL Aymeric CHEVRET Anthony

Câblage avec des portes NAND (NON ET) Table de vérité

/R /S Q /Q 0 0 Etat interdit 0 1 0 1 1 0 1 0 1 1 Etat précédent

Figure A.1.3 : Câblage d’une bascule RS avec des portes NAND

Un problème se pose alors lorsque les deux entrées set et reset sont toutes les deux dans leurs états haut. On est alors incapable de déterminer la réaction de la bascule en sortie.

Il est possible de lever cette indétermination pour certains types de bascules : Les bascules à enclenchement (« set ») prioritaire où la sortie Q prend la valeur 1

Figure A.1.4 : Câblage d’une bascule RS à enclenchement prioritaire

Les bascules à déclenchement (« reset ») prioritaire où la sortie Q prend la valeur 0

Figure A.1.5 : Câblage d’une bascule RS à enclenchement prioritaire

- 52 -

Page 52: DORKEL Aymeric CHEVRET Anthony

Bascule RSH synchrone 3 entrées : Set, Reset et T (signal d’horloge) 2 sorties : Q et /Q complémentaires Figure A.1.6 : représentation d’une

bascule RSH Principe Cette bascule se comporte comme une bascule RS lorsque le signal d’horloge est à

l’état haut mais lorsqu’il se trouve à l’état bas, la bascule est bloquée : l’état précédent est conservé en sortie quelques soient les valeurs de S et R. Le basculement s’effectue alors au niveau haut de T.

Sur certaines bascules, c’est le front montant ou descendant du signal d’horloge qui influe sur la sortie.

Câblage avec des portes NAND Table de vérité

T S R Q /Q 0 X X Etat précédent 1 0 0 Etat précédent 1 0 1 0 1 1 1 0 1 0 1 1 1 Etat interdit

Figure A.1.7 : Câblage d’une bascule RSH avec des portes NAND

Bascule D synchrone 2 entrées : D et T le signal d’horloge 2 sorties : Q et /Q complémentaires Figure A.1.8 : représentation

d’une bascule D synchrone Principe Fonctionnement identique à celui d’une bascule RSH où l’entrée R serait le

complément de l’entrée S ce qui évite définitivement tout état interdit. Avec ce principe, l’état de D est recopié sur la sortie Q.

- 53 -

Page 53: DORKEL Aymeric CHEVRET Anthony

Câblage avec des portes NAND Table de vérité

T D Q /Q 0 X Etat précédent 1 0 0 1 1 1 1 0

Figure A.1.9 : Câblage d’une bascule D avec des

portes NAND

Bascule JK synchrone 3 entrées : J, K et T le signal d’horloge 2 sorties : Q et /Q complémentaires Figure A.1.10 : représentation d’une

bascule JK synchrone Principe Comportement identique à celui d’une bascule RSH, mise à part la suppression de

l’indétermination : lorsque les deux entrés J et K sont à l’état haut, les sorties Q et /Q changent toutes deux d’état.

Câblage avec des portes NAND Table de vérité

T J K Q /Q

1 0 0 Etat précédent

1 0 1 0 1 1 1 0 1 0

1 1 1 Complément

de l’état précédent

Figure A.1.11 : Câblage d’une bascule JK synchrone

Remarques La sortie reste toujours inchangée lorsque le signal d’horloge est à l’état bas. Une bascule JK avec les entrées J et K à l’état haut est appelée bascule T.

- 54 -

Page 54: DORKEL Aymeric CHEVRET Anthony

2. Compteur Un compteur indique le nombre d’impulsions d’un signal d’entrée sur plusieurs

sorties qui forment un nombre binaire.

Les compteurs asynchrones Les compteurs asynchrones sont constitués de bascules qui ne reçoivent pas toutes

en entrée le signal dont les impulsions sont à compter. Figure A.2.1 : Câblage d’un compteur asynchrone avec des bascules TT

Dans l’exemple ci-dessus, quatre bascules T synchrones sont câblées les unes à la

suite des autres. Le signal dont les impulsions sont à compter arrive sur l’horloge de la première bascule. La sortie Q1 sert alors de signal d’horloge pour la deuxième bascule, de même pour les suivantes. Les états des sorties Q1, Q2, Q3 et Q4 donnent alors le nombre d’impulsions en système binaire avec Q1 le bit de poids faible.

Voici un chronogramme avec le même câblage, utilisant des bascules T synchrones sur front descendant.

Figure A.2.2 : chronogramme aux sorties de chaque porte par rapport au signal d’entrée

- 55 -

Page 55: DORKEL Aymeric CHEVRET Anthony

Dans l’illustration ci-dessus notre compteur indique finalement 1x2 +1x21 2 = 6 impulsions, ce qui correspond bien à notre signal d’entrée.

Si ce principe fonctionne bien en théorie il présente tout de même un défaut, en effet, lorsque l’entrée est modifiée, la sortie doit changer en conséquence mais cette opération n’est pas immédiate car les bascules admettent un temps de propagation. Sur la figure on peut voir les retards provoqués par les bascules une, deux et trois.

Celles-ci étant câblées les unes après les autres, les temps de propagation s’ajoutent et créent un retard encore plus important entre les impulsions du signal d’entrée et les actualisations des dernières bascules. Dans notre cas, la bascule trois reste à l’état haut avant et après la dernière impulsion, son retard n’a donc aucune importance.

Si le résultat est lu trop tôt après la dernière impulsion, le compte sera erroné : certaines bascules auront déjà été mises à jour tandis que les dernières seront toujours dans l’état précédent. Ici, toute valeur lue dans l’intervalle « retards ajoutés » sera fausse : on aura Q3 dans son état haut et Q2 dans son état bas alors que six impulsions auront été effectuées.

Les compteurs synchrones Ils permettent de remédier aux problèmes de temps de propagation des compteurs

asynchrones mais ils sont plus complexes à câbler. En effet, le signal d’entrée est appliqué à chaque bascule mais l’ajout de portes logiques ET est nécessaire comme le montre le schéma ci-dessous.

Figure A.2.3 : Câblage d’un compteur synchrone avec des bascules T

3. Registre Les registres internes au processeur sont eux aussi à base de bascules. Le registre

permet la mémorisation d’un mot binaire. Il est commandé de deux façons, à l’aide d’une fonction écriture et d’une fonction lecture.

Dans l’exemple qui suit, le registre est composé de quatre bascules D. Chacune

d’elle mémorise un bit du mot lorsque l’horloge est à l’état haut : il s’agit de l’écriture du mot. Celui-ci est alors recopié sur les sorties Q0 à Q3 jusqu’à ce qu’une nouvelle écriture soit exécutée. Pour lire le mot mis en mémoire il suffit alors de regarder l’état de chacune de ces sorties.

- 56 -

Page 56: DORKEL Aymeric CHEVRET Anthony

Figure A.3.1 : Registre 4 bits constitué de bascules D

4. Bus En informatique, un bus est un ensemble de liaisons physiques (câbles, pistes de

circuits imprimés, etc.) pouvant être exploitées en commun par plusieurs éléments matériels afin de communiquer.

Pour effectuer une lecture ou une écriture dans le registre précédent (figure A.3.1),

le microprocesseur utilise trois bus : un bus d’adresse pour indiquer de quel registre il s’agit ; un bus de contrôle afin de commander la lecture ou l’écriture ; un bus de données pour acquérir ou stocker une donnée.

La commande de lecture pour un registre précis est donc conditionnée par la présence de son adresse sur le bus d’adresse et par la commande de lecture, un état haut sur le bus de contrôle par exemple, un état bas signifiant alors l’écriture.

5. ALU, “Aritmetic and logic unit” (Unité de traitement) L’unité de traitement des informations est chargée de réaliser tous les calculs

nécessaires à l’exécution du programme. Les portes logiques permettent de réaliser les différents opérateurs présents dans

une ALU, la figure A.5.1 représente un demi additionneur qui fait la somme de deux bits et l’affiche ensuite sur le bit résultat. Le bit report indique, lorsqu’il est à l’état haut, que le résultat dépasse l’affichage maximal du bit résultat. Prenons pour exemple le cas où les deux bits d’entrée sont à l’état haut (1 et 1), on devrait obtenir la valeur binaire 10 comme résultat mais celle-ci est impossible à afficher sur le seul bit résultat, on obtiendra donc un état bas sur le bit résultat (0) et un état haut sur le bit report (1).

Le demi additionneur montre le principe du fonctionnement d’une addition sur

deux bits mais cela se révèle plus complexe lorsque l’on veut effectuer cette opération sur 4 bits comme le montre la figure A.5.2. De plus, cette figure montre un additionneur asynchrone, en effet les états des bits résultat changent les uns après les autres et non tous de manière simultanée. La nécessité d’un additionneur synchrone complique encore le système.

- 57 -

Page 57: DORKEL Aymeric CHEVRET Anthony

Figure A.5.1 : Demi additionneur (2 bits) Figure A.5.2 : Additionneur 4 bits De la même manière, on arrive à créer des soustracteurs et d’autres fonctions

simples. Elles sont organisées entre elles de telle sorte que l’ALU est un mélange complexe de portes logiques comme en témoigne la figure A.5.3 qui représente une ALU 74181 de 4 bits. Notons que celle-ci n’est pas très évoluée et ne permet d’effectuer que seize opérations arithmétiques dont ajouter, soustraire, doubler et seize opérations logiques dont ET, NON ET, OU, NON OU, OU exclusif.

Figure A.5.3 : ALU 74181 de 4 bits

- 58 -

Page 58: DORKEL Aymeric CHEVRET Anthony

Annexe B : Jeu d’instructions, concepts CISC & RISC

Le jeu d'instruction d’un processeur est l'ensemble des instructions que celui ci peut

exécuter. Une instruction peut être simple ou complexe comme dans les exemples suivants. L’instruction commandant d’ajouter un au contenu d’un registre interne au

microprocesseur est une instruction simple. Elle ne fait intervenir qu’un additionneur et tout se passe à l’intérieur du processeur, aucune information extérieure à celui-ci n’intervient. Il suffit généralement d’un seul cycle d’horloge pour exécuter cette opération car l’addition est une des instruction les plus simples, commune à la totalité des processeurs.

L’instruction commandant l’incrémentation du contenu d’une adresse mémoire est

une instruction complexe car elle nécessite plusieurs étapes. Tout d’abord, il faut agir sur un élément externe au microprocesseur : la cellule correspondant à l’adresse mémoire indiquée. Cette manipulation implique le transfert de son contenu dans un registre interne au processeur. Par la suite, l’addition de un au registre, puis l’écriture du résultat à l’adresse initiale doivent être effectuées. Il s’agit là d’un exemple basique d’instruction complexe qui prendra, dans la plupart des cas, plus d’un cycle d’horloge.

1. CISC Complex Instruction Set Computer : le processeur à jeu d'instructions complexes

(ou microprocesseur à jeu étendu d'instructions), désigne un microprocesseur possédant un jeu d'instructions comprenant de nombreuses instructions complexes.

Pourquoi ? Par le passé la mémoire travaillait très lentement par rapport au processeur, on

pensait qu’il était plus intéressant de soumettre au microprocesseur des instructions complexes. Ainsi, plutôt que de coder une opération complexe par plusieurs instructions plus petites (qui demanderaient autant d’accès mémoire très lents), il semblait donc préférable d’ajouter au jeu d’instructions du microprocesseur une instruction complexe qui se chargerait de réaliser cette opération en interne. C’est donc pour cette raison que la conception de machines CISC était la seule envisageable.

- 59 -

Page 59: DORKEL Aymeric CHEVRET Anthony

Principe Les instructions simples peuvent être directement gérées par le processeur car celui-

ci dispose des circuits électroniques nécessaires à leurs exécutions, comme un additionneur. Pour les instructions complexes, le microprocesseur ne peut plus faire appel à des circuits câblés car il faudrait multiplier leur nombre d’une façon conséquente, ce qui est restreint par la limite physique du nombre de composants intégrables dans un microprocesseur. Un grand inconvénient de la multiplication des circuits est la nette augmentation du prix qui en découlerait.

Une autre solution a donc été adoptée. Chaque instruction complexe est fractionnée

en plusieurs séquences minimalistes appelées « micro-instructions ». Lorsque le processeur doit exécuter l’instruction complexe originale, il exécute chacune des micro-instructions grâce aux circuits électroniques disponibles puis reconstitue le résultat attendu en assemblant les différents résultats obtenus avec les micro-instructions. Celles-ci sont rassemblées et enregistrées dans le silicium du processeur sous la forme d’un « microcode » (« firmware »). Autour de ce microcode doivent être installés les circuits logiques nécessaires au déroulement séquentiel des micro-instructions qui doivent tenir compte des ordres transmis par l’unité d’instruction.

Le décodeur d’instructions déchiffre l’instruction qu’il reçoit et l’envoi au microcode

qui la transforme en opérations élémentaires. Le microcode implanté dans le silicium par le fabricant n’est pas modifiable et seul les instructions s’y référant peuvent être prises en compte. Grâce à un nombre réduit de circuits et du microcode, le microprocesseur peut alors reconstituer une grande diversité d’instructions plus ou moins complexes.

Avantages Les instructions complexes microcodées comprennent, pour la plupart, plusieurs

micro-instructions qui sont elles même des instructions basiques. Avec le CISC on a donc un programme plus court qui occupe moins de mémoire.

Inconvénients La longueur des instructions est variable donc la première tache du décodeur

d’instructions consiste à lire le code ramené de la mémoire afin de comprendre si tout est complet ou bien s’il y a une suite. La vitesse d’exécution d’un processeur doit s’aligner sur les temps d’exécution des instructions les plus complexes c’est à dire les plus lentes ; ce qui pénalise alors tous le système d’autant plus que ces instructions complexes sont beaucoup moins utilisées que les instructions simples.

Le prix d’un processeur dépend, entre autre, de la surface de silicium occupée or le microcode en utilise une partie non négligeable ce qui entraîne une hausse du prix.

- 60 -

Page 60: DORKEL Aymeric CHEVRET Anthony

2. RISC Reduced Instruction Set Computer : le processeur à jeu d'instructions réduit désigne

un microprocesseur possédant un jeu d'instructions comprenant uniquement des instructions simples, par définition.

Pourquoi ? Le concept RISC implique de « faire les choses simplement et vite ». Les premiers

travaux sont dus à IBM et remontent à 1975, ils sont menés sous la direction de John Cocke considéré comme le père du RISC.

Il commence par analyser le fonctionnement d’un gros système IBM de l’époque. Après étude, il constate que seul un petit nombre d’instructions simples (LOAD, STORE, ADD, SUBSTRACT) sont massivement exécutées. Les autres instructions, notamment les fonctions bien plus complexes, n’interviennent que rarement.

Ces résultats le mettent sur la voix d’une machine simplifiée avec l’idée de réduire le jeu d’instructions à celles le plus couramment utilisées et d’en améliorer la vitesse de traitement d’autant plus que cela permet de supprimer le microcode qui constitue une surcharge ralentissant la vitesse d’exécution.

Principe Le jeu d’instructions du processeur ne compte plus ou peu d’instruction complexe,

seulement des instructions simples. Un problème se pose alors : comment utiliser les anciennes instructions complexes qui restent indispensables ?

Il suffit de remplacer les instructions complexes par des instructions simples dans le programme. Cette série d’instructions simples devra évidemment réaliser les mêmes fonctions.

Si des instructions complexes ont tout de même besoin d’être conservées alors on n’utilisera pas de microcode mais ces fonctions seront câblées dans le silicium. Certes ce câblage prendra de la place mais bien moins que le microcode, de plus une instruction câblée est plus rapide qu’une instruction microcodée.

- 61 -

Page 61: DORKEL Aymeric CHEVRET Anthony

Extensions afin d’optimiser le concept RISC :

Les instructions doivent rester d’une longueur fixe. Les modes d’adressage doivent se simplifier grâce à une architecture de

registre à registre et une multiplication de leur nombre en interne afin de limiter les accès mémoire. Ces derniers doivent, de plus, être réalisés uniquement par les instructions LOAD et STORE (charger et ranger). C’est un principe où l’on charge les données nécessaires à l’exécution des instructions dans les registres ; par la suite elles sont gardées dans ces registres au lieu d’être replacer en mémoire ce qui impliquerait un temps supplémentaire. Cette suppression de transfert constant avec la mémoire accélère considérablement l’exécution des opérations.

Le format des instructions doit définir trois opérandes. Le code d’instruction peut alors définir trois registres : deux sources et un cible, par exemple.

Avantages :

Le microcode est supprimé avec le RISC ce qui permet un gain de place sur le silicium et une diminution du coût.

La suppression du microcode et le câblage des différentes instructions permettent l’exécution de ces instructions en une seule période d’horloge.

Multiplication des registres, accès mémoire uniquement pour charger et ranger les données, longueurs d’instructions fixes augmentent la vitesse d’exécution des instructions.

Inconvénients : Certes les instructions complexes ont été remplacées par une série d’instructions

simples mais si l’on développe un programme en langage évolué, il faudra avoir à disposition un compilateur efficace. Le compilateur étant chargé de traduire en code machine (binaire) les instructions rédigées dans le langage évolué.

Pour un programme donné il faudra plus d’instructions en RISC qu’en CISC, le programme en sera d’autant plus long.

- 62 -

Page 62: DORKEL Aymeric CHEVRET Anthony

3. Evolution et amélioration des concepts RISC et CISC L'ensemble des améliorations des microprocesseurs vise à diminuer le temps

d'exécution du programme. Une idée évidente, pour arriver à ce but est d’augmenter tout simplement la

fréquence de l’horloge du microprocesseur. Malheureusement, cette hausse provoque une surconsommation ce qui entraîne une élévation de la température. Les processeurs doivent alors être équipés de systèmes de refroidissement ou leur tension d’alimentation doit alors être diminuée.

Une autre possibilité pour augmenter la puissance de traitement d’un microprocesseur est de diminuer le nombre moyen de cycles d’horloge nécessaire à l’exécution d’une instruction. Pour cela il faut choisir le concept approprié, RISC ou CISC, par rapport aux applications qui seront faites du processeur, notamment le nombre d’instructions gérées. Beaucoup de perspectives s’ouvrent à nous car certains processeurs CISC utilisent maintenant les atouts du RISC et inversement.

La meilleure des solutions entre ces deux concepts réside dans le meilleur compromis qui peut en être fait suivant l’utilisation désirée.

- 63 -

Page 63: DORKEL Aymeric CHEVRET Anthony

Annexe C : Architectures Von Neumann & Harvard

Le microcontrôleur a besoin de stocker deux différents types principaux

d’informations. Les instructions à exécuter, c’est ce que l’on appelle « le code », et les variables, c’est ce que l’on appelle « les données ».

Pour les notions de BUS, se reporter à l’annexe A.

1. Architecture « Von Neumann » John Von Neumann Participant activement à la mise au point de la première bombe atomique en 1943,

John Von Neumann perçoit alors l'importance des machines électroniques afin de réaliser des calculs insurmontables à la main. Il est ainsi le premier à avoir l'idée de ranger les instructions et les données dans la même mémoire. Ce modèle dit de Von Neumann est toujours présent dans la conception des ordinateurs modernes, type P.C.

Principe/Caractéristiques : Figure C.2.1 Principe de l’architecture « Von Neumann »

- 65 -

Page 64: DORKEL Aymeric CHEVRET Anthony

L’architecture dite de « Von Neumann » est une organisation des composants telle que le bus qui relie la mémoire programme et la mémoire de donnée au microprocesseur soit le même. En général, il n’existe qu’une mémoire de programme contenant à la fois les instructions et les données placées à la suite les unes des autres.

Ce bus sert alors alternativement à transmettre les instructions et les données. Inconvénients Ce système de bus unique impose aux deux mémoires de se le partager pendant

l’exécution du programme. En effet, pour exécuter une instruction il faut tout d’abord aller chercher le code instruction situé dans la mémoire programme puis les données sur lesquelles elle agit ; celles ci se trouvant dans la mémoire de données.

Une des principales caractéristiques que l’on attend d’un système muni d’un processeur est sa vitesse d’exécution et bien évidemment le partage du bus n’y contribue pas. De plus, dans ce type d’organisation la rapidité d'une machine est limitée par l'élément le plus lent. Cela ne sert donc à rien de fabriquer un processeur très rapide si la mémoire n'est pas capable de fournir assez rapidement les instructions à exécuter, ni les données à traiter.

Cette architecture a comme autre inconvénient d’imposer un seul système d’adressage de la mémoire, aussi bien pour le code que pour les données. La taille des instructions devra donc se conformer à ce système. Si celui-ci est octal (une adresse par octet), la longueur des instructions devra donc être un multiple de 8 bits.

2. Architecture « Harvard » Principe/Caractéristiques :

Figure C.3.1 Principe de l’architecture « Harvard » Cette architecture remédie au problème du bus unique en séparant simplement les

mémoires de programme et de données. Il instaure un bus supplémentaires afin que chaque mémoire soit relié au processeur par un bus distinct.

Dans cette configuration, il est possible au processeur d’accéder à la fois à la mémoire programme et à la mémoire de données. Le code instruction et les données sur lesquelles il agit sont donc amenés au processeur dans le même temps.

- 66 -

Page 65: DORKEL Aymeric CHEVRET Anthony

Avantage par rapport à l’architecture « Von Neumann » : Le flux d’informations traitées par la machine est plus important et la vitesse

d’exécution des programmes est bien sûr améliorée. Les deux mémoires peuvent disposer d’un mode d’adressage indépendant, ce qui

permet d’avoir une longueur d’instruction au choix. Par exemple, les microcontrôleurs Microchip PIC de la famille 16F utilisent des instructions de longueur 14 bits. Chaque instruction a donc son adresse. Dans leur mémoire de donnée, chaque octet dispose de son adresse. Si ces microcontrôleurs disposaient d’une architecture du type « Von Neumann », les instructions auraient du occuper deux octets et deux adresses auraient été utilisées pour chaque instruction.

Inconvénient par rapport à l’architecture « Von Neumann » : Le deuxième bus ajouté prend une place non négligeable et c’est pour cette raison

que l’architecture Harvard génère dans la plupart des cas un circuit plus volumineux. L’architecture type « Von Neumann » simplifie également la modification du code et

des données. En effet, la copie d’une donnée dans le code et vis versa correspond à des transferts internes à l’unique mémoire.

- 67 -

Page 66: DORKEL Aymeric CHEVRET Anthony

Annexe D : Code source de l’exemple

Les pages qui suivent contiennent le code source de l’exemple accompagnant ce dossier. Celui-ci a été placé en annexe pour plusieurs raisons, la première étant qu’il n’apporte pas directement de réponse à la problématique car il ne fait que partie d’un exemple.

Le digicode qui illustre ce dossier n’as pas été conçu pour être optimum mais pour

présenter les avantages d’un microcontrôleur. Il est nécessaire de présenter quelques points qui auraient pu êtres optimisés mais qui ne l’ont pas été pour ne pas compliquer le code. Dans le cadre d’un projet, il aurait largement pu être optimisé « consommation d’énergie », étant donné les possibilités offertes par les microcontrôleurs dans ce domaine. Par exemple, en abaissant la fréquence de l’oscillateur interne à 48kHz, la consommation du composant aurait été réduite. Le mode sommeil de celui-ci aurait également pu être exploité, ainsi que les interruptions de changement d’état pour le clavier.

Ce code a été compilé avec une version d’évaluation du compilateur C CC5X. Les deux

instructions #pragma utilisées sont destinées à la sélection du composant cible ainsi qu’à la configuration des ses fusibles pour la programmation.

Ce compilateur diffère des normes du langage C sur plusieurs points, afin de faciliter la programmation orientée microcontrôleurs. Entre autre, il permet l’adressage d’un bit d’un octet par la syntaxe « [octet].[bit] ». Il possède également un type de variable, « bit », correspondant à un huitième d’octet.

//Configuration du microcontrôleur utilisé #pragma chip PIC16F628A /* Configuration pour la programmation (généré par IC-Prog) source d'horloge : oscillateur interne avec sortie de l'horloge (utile pour débuggage) (intRC CLKOUT) Retardement du lancement (attente de stabilisation de l'alimentation) (PWRT) Activat#pragma config = 0x3F31

ion de la pin de reset (MCLR) */

//Gestio#include "int16CXX.H"

n des interruptions (int_save_registers, int_restore_registers, etc)

//Défin#define VERTE PORTA.7

ition concernant le matériel (pour une plus grande lisibilité du code)

#define VERT VERTE #define JAUNE PORTA.0 #define ROUGE PORTA.1 #define ALLUMER(LED) LED=0 #define ETEINDRE(LED) LED=1 #define ETEINDRE_TOUT PORTA = 255

- 69 -

Page 67: DORKEL Aymeric CHEVRET Anthony

#define LIGNE1 PORTB.2 #define LIGNE2 PORTB.3 #define LIGNE3 PORTB.5 #define COLONNE1 PORTB.0 #define COLONNE2 PORTB.1 #define COLONNE3 PORTB.4 #define ECRITURE_LIGNES TRISB=0b.1101.0011;nop();PORTB=0b.0010.1100 #define ECRITURE_COLONNES TRISB=0b.1110.1100;nop();PORTB=0b.0001.0011 //Activer pour tester le clavier et les LED #define TESTER_CLAVIER 1 //Etats du clavier (pour LireNombre) #define PAS_DE_TOUCHE_ENFONCEE 0 #define ERROR 10 #define LIGNES_ET_COLONNES 11 //Déclaration de nos fonctions unsigned char LireNombre(void); void AfficherNombre(unsigned char Nombre); char lecture_EEPROM(char adresse); void ecriture_EEPROM(char adresse,char octet); //écriture à partir de la ligne 4 (vecteurs d'interruptions présents aux lignes précédentes) #pragma origin 4 //variables dédiées aux LED unsigned char TempoLedRouge, TempoLedJaune, TempoLedVerte; unsigned char ModeLedRouge, ModeLedJaune, ModeLedVerte; bit EcrireEEPROM; //états possibles des LED #define MODE_LED_ETEINTE 0 #define MODE_LED_VIVANTE 1 #define MODE_LED_LENTE 2 #define MODE_LED_RAPIDE 3 #define MODE_LED_ALLUMEE 4 unsigned char val_preced; //longueur du code (4 chiffres dans ce cas) #define LONGUEUR_CODE 4 unsigned char code[LONGUEUR_CODE]; unsigned char nouveau_code[LONGUEUR_CODE*2]; unsigned char currentcodepos; bit attente_relache;

- 70 -

Page 68: DORKEL Aymeric CHEVRET Anthony

unsigned char mode_config; #define CONFIG_NORMAL 0 #define CONFIG_ATTENTECODE 1 #define CONFIG_RECONF_0 8 #define CONFIG_RECONF_1 9 #define CONFIG_RECONF_2 10 #define CONFIG_RECONF_END 0xFF //défin#define TIMEBASE 40 //ms

ition des timings

#define TEMPS_OUVERTURE 125 //5s = 125x40ms #define TEMPS_RECONFIG 60 //5s unsigned char watchdog; //variable dédiée à la sauvegarde du registre d'adressage indirecte durant les interruptions unsigned char FSRsave; //fonction qui gère les interruptions interrupt int_server(void) { //sauvegarde des registres W, STATUS (et PCLATH si requis) int_save_registers; FSRsave = FSR; if (T0IF) //interruption du timer 0 { //watchdog if ( watchdog != 0 ) { if ( watchdog == 1 ) { //initialisation mode_config = CONFIG_NORMAL; ModeLedVerte = MODE_LED_VIVANTE; ModeLedRouge = MODE_LED_ETEINTE; ModeLedJaune = MODE_LED_ETEINTE; currentcodepos = 0; watchdog = 0; } else watchdog--; } //GESTION CLAVIER unsigned char nombre = LireNombre(); if ( nombre != PAS_DE_TOUCHE_ENFONCEE ) ModeLedJaune = MODE_LED_ALLUMEE; else ModeLedJaune = MODE_LED_ETEINTE; //entrée en mode config if ( nombre == LIGNES_ET_COLONNES ) { //Mode config ModeLedRouge = MODE_LED_RAPIDE; mode_config = CONFIG_ATTENTECODE;

- 71 -

Page 69: DORKEL Aymeric CHEVRET Anthony

watchdog = TEMPS_RECONFIG; } //attente de relâche de touche else if ( attente_relache == 1 ) { if ( nombre == PAS_DE_TOUCHE_ENFONCEE ) attente_relache = 0; } else if ( mode_config >= CONFIG_RECONF_0 ) { unsigned char pos = mode_config >> 3; pos -= 1; if ( pos >= (2*LONGUEUR_CODE) ) { //fin de la reconfiguration //comparaison code et ressaisie unsigned char i; for ( i = 0; i < LONGUEUR_CODE; i++ ) { unsigned char temp = nouveau_code[i+LONGUEUR_CODE]; if ( nouveau_code[i] != temp ) i = 250; } if ( i < 250 ) { //copie nouveau code for(i = 0; i < LONGUEUR_CODE; i++ ) { unsigned char temp = nouveau_code[i]; code[i] = temp; } //demande écriture ultérieure dans l'eeprom EcrireEEPROM = 1; currentcodepos = 0; } mode_config = CONFIG_NORMAL; ModeLedRouge = MODE_LED_ETEINTE; } else { if ( pos == LONGUEUR_CODE) { ModeLedJaune = MODE_LED_RAPIDE; ModeLedVerte = MODE_LED_VIVANTE; } if ( nombre != PAS_DE_TOUCHE_ENFONCEE ) { //reconfiguration d'un chiffre nouveau_code[pos] = nombre; attente_relache = 1; mode_config += 8;

- 72 -

Page 70: DORKEL Aymeric CHEVRET Anthony

watchdog = TEMPS_RECONFIG; } } } else { //test code if ( nombre == val_preced ) { if ( nombre != PAS_DE_TOUCHE_ENFONCEE ) { if ( nombre == code[currentcodepos] ) { attente_relache = 1; currentcodepos++; watchdog = TEMPS_RECONFIG; } else currentcodepos = 0; if ( currentcodepos >= LONGUEUR_CODE ) { ModeLedVerte = MODE_LED_RAPIDE; if ( mode_config == CONFIG_NORMAL ) { //Ouverture de la porte :) currentcodepos = 0; watchdog = TEMPS_OUVERTURE; } else { //reconfiguration code mode_config = CONFIG_RECONF_0; watchdog = TEMPS_RECONFIG; } } } } val_preced = nombre; } //MODES LED switch ( ModeLedRouge ) { case MODE_LED_RAPIDE: ROUGE = !ROUGE; break; case MODE_LED_LENTE: if ( TempoLedRouge < 50 ) TempoLedRouge++; else { TempoLedRouge = 0; ROUGE = !ROUGE; } break;

- 73 -

Page 71: DORKEL Aymeric CHEVRET Anthony

case MODE_LED_VIVANTE: TempoLedRouge++; if ( TempoLedRouge == 50 ) { ALLUMER(ROUGE); } else if ( TempoLedRouge >= 52 ) { ETEINDRE(ROUGE); TempoLedRouge = 0; } break; case MODE_LED_ALLUMEE: ALLUMER(ROUGE); break; case MODE_LED_ETEINTE: ETEINDRE(ROUGE); break; } switch ( ModeLedJaune ) { case MODE_LED_RAPIDE: JAUNE = !JAUNE; break; case MODE_LED_LENTE: if ( TempoLedJaune < 50 ) TempoLedJaune++; else { TempoLedJaune = 0; JAUNE = !JAUNE; } break; case MODE_LED_VIVANTE: TempoLedJaune++; if ( TempoLedJaune == 50 ) { ALLUMER(JAUNE); } else if ( TempoLedJaune >= 52 ) { ETEINDRE(JAUNE); TempoLedJaune = 0; } break; case MODE_LED_ALLUMEE: ALLUMER(JAUNE); break; case MODE_LED_ETEINTE: ETEINDRE(JAUNE); break; } switch ( ModeLedVerte ) { case MODE_LED_RAPIDE:

- 74 -

Page 72: DORKEL Aymeric CHEVRET Anthony

VERTE = !VERTE; break; case MODE_LED_LENTE: if ( TempoLedVerte < 50 ) TempoLedVerte++; else { TempoLedVerte = 0; VERTE = !VERTE; } break; case MODE_LED_VIVANTE: TempoLedVerte++; if ( TempoLedVerte == 50 ) { ALLUMER(VERTE); } else if ( TempoLedVerte >= 52 ) { ETEINDRE(VERTE); TempoLedVerte = 0; } break; case MODE_LED_ALLUMEE: ALLUMER(VERTE); break; case MODE_LED_ETEINTE: ETEINDRE(VERTE); break; } //Pour que l'interruption continue a être déclenchée ... T0IF = 0; T0IE = 1; } FSR = FSRsave; int_restore_registers; } void main(void) { //Initialisation //OSCF = 0; //48kHz (on reste à haute fréquence car cela est plus pratique) CMCON = 0b.0000.0111; //Désactiver les analogiques (comparateurs ...) TRISA = 0b.0111.1100; //Les LED en sortie TRISB = 0b.1111.1111; PORTA = 255; PORTB = 0; ModeLedRouge = MODE_LED_ETEINTE; ModeLedJaune = MODE_LED_ETEINTE; ModeLedVerte = MODE_LED_ETEINTE;

- 75 -

Page 73: DORKEL Aymeric CHEVRET Anthony

//initialisation du code code[0] = lecture_EEPROM(0); code[1] = lecture_EEPROM(1); code[2] = lecture_EEPROM(2); code[3] = lecture_EEPROM(3); //Test valeur if ( (code[0] > 10) || (code[1] > 10) || (code[2] > 10) || (code[3] > 10) ) { code[0] = 1; code[1] = 2; code[2] = 3; code[3] = 4; } val_preced = 0; currentcodepos = 0; attente_relache = 0; watchdog = 1; //(réinitialisation à la prochaine interruption) //TIMER0 datasheet p47 //interrupt Timer0 prescaller à 8 => 1/1000000 * 256 * 8 = 0,002048s => 2ms T0CS = 0; //activation du timer0 PSA = 0; //activation du prescaller sur timer0 PS0 = 1; PS1 = 1; PS2 = 1; //valeur prescaller //activation des interruptions GIE = 1; T0IE = 1; EcrireEEPROM = 0; for(;;) { if ( EcrireEEPROM == 1 ) { ecriture_EEPROM(0, code[0]); ecriture_EEPROM(1, code[1]); ecriture_EEPROM(2, code[2]); ecriture_EEPROM(3, code[3]); EcrireEEPROM = 0; } } } unsigned char LireNombre(void) { char valeur = PAS_DE_TOUCHE_ENFONCEE; ECRITURE_LIGNES; //Tests mode reconfig if ( COLONNE1 && COLONNE2 && COLONNE3 ) { ECRITURE_COLONNES; if ( LIGNE1 && LIGNE2 && LIGNE3 ) valeur = LIGNES_ET_COLONNES; else

- 76 -

Page 74: DORKEL Aymeric CHEVRET Anthony

valeur = ERROR; } else { ECRITURE_LIGNES; //Tests nombres simples if ( COLONNE1 ) { ECRITURE_COLONNES; if ( LIGNE1 ) { valeur = 1; } else if ( LIGNE2 ) { valeur = 4; } else if ( LIGNE3 ) { valeur = 7; } } else if ( COLONNE2 ) { ECRITURE_COLONNES; if ( LIGNE2 ) { valeur = 5; } else if ( LIGNE1 ) { valeur = 2; } else if ( LIGNE3 ) { valeur = 8; } } else if ( COLONNE3 ) { ECRITURE_COLONNES; if ( LIGNE3 ) { valeur = 9; } else if ( LIGNE1 ) { valeur = 3; } else if ( LIGNE2 ) { valeur = 6; } }

- 77 -

Page 75: DORKEL Aymeric CHEVRET Anthony

} return valeur; } void AfficherNombre(unsigned char Nombre) { if ( Nombre.0 == 1 ) ALLUMER(VERT); else ETEINDRE(VERT); if ( Nombre.1 == 1 ) ALLUMER(JAUNE); else ETEINDRE(JAUNE); if ( Nombre.2 == 1 ) ALLUMER(ROUGE); else ETEINDRE(ROUGE); } char lecture_EEPROM(char adresse) { EEADR=adresse; // adresse à lire EEDATA=0; // pointe la mémoire data RD=1; // pour la lecture return EEDATA; // valeur lue } void ecriture_EEPROM(char adresse,char octet) { EEADR=adresse; // adresse à écrire EEDATA=octet; // valeur à enregistrer //EEDATA=0; // pointe la mémoire data WREN=1; // active l'écriture GIE=0; // désactive les interruptions #asm // séquence obligatoire MOVLW 0x55 MOVWF EECON2 MOVLW 0xAA MOVWF EECON2 BSF EECON1,WR #endasm GIE=1; // active les interruptions WREN=0; // fin de l'écriture while(WR); // attente de la fin de l'écriture }

- 78 -

Page 76: DORKEL Aymeric CHEVRET Anthony

Bibliographie

Sites Internet Fabricants de microcontrôleurs :

Microchip http://www.microchip.com Atmel http://www.atmel.com Motorola http://www.motorola.com Freescale http://www.freescale.com/ Maxim http://www.maxim-ic.com/ Texas Instruments http://www.ti.com

Sites généralistes :

http://fr.wikipedia.org http://www.commentcamarche.net http://www.bibmath.net/bios http://fribotte.free.fr/ http://www.jelectronique.com/

Sites institutionnels :

http://www.intel.com http://www.ac-nancy-metz.fr http://www.univ-lemans.fr/enseignements/physique http://www.culture.gouv.fr/culture/dglf/terminologie/repertoireJO220900

/A2200003.htm#13 http://www.stielec.ac-aix-marseille.fr/ http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html http://www.techniques-ingenieur.fr/

Livres

« Microprocesseurs : du Cisc au Risc » par Henri Lilen chez DUNOD « les processeurs RISC » par D.Weyand « Comprendre les microprocesseurs » par Marcel Gindre et Denis Roux chez

MCGRAW-HILL (série « électronique numérique ») « Microcontrôleur AVR » par Christian Tavernier chez DUNOD

Norme

IEEE 754

- 79 -

Page 77: DORKEL Aymeric CHEVRET Anthony

- 80 -

Page 78: DORKEL Aymeric CHEVRET Anthony

Index

Adresse .......................................................................................................................................25 ALU (Aritmetic and Logic Unit)............................................................................................57 Banques ......................................................................................................................................25 Bascule........................................................................................................................................51 Bit

Bit est la contraction de binary digit, « chiffre binaire », il permet d'obtenir deux états : 1 ou 0

Branchements............................................................................................................................37 Bus...............................................................................................................................................57 Circuit intégré

Tranche de silicium, sur laquelle est placé un grand nombre de transistors, intégrée dans un boîtier comportant des connecteurs d'entrée - sortie

CISC............................................................................................................................................59 Code opération..........................................................................................................................31 Compilation ...............................................................................................................................42 Compteur ...................................................................................................................................55 Compteur ordinal .....................................................................................................................33 CPU (Central Process Unit)

Voir microprocesseur DEL

Voir LED Harvard.......................................................................................................................................66 Instruction..................................................................................................................................31 Interruption ...............................................................................................................................39 Jeu d’instructions ......................................................................................................................59 Langage.......................................................................................................................................41 LED (Light-Emitting Diode)

La diode électroluminescente est un composant électronique capable d'émettre de la lumière lorsqu'il est parcouru par un courant électrique

Mémoire .....................................................................................................................................25 Microprocesseur........................................................................................................................7, 25 Octet

Ensemble de 8 bits Opérande....................................................................................................................................31 Pile...............................................................................................................................................37 Pipeline .......................................................................................................................................33 Processeur ..................................................................................................................................7 Registre .......................................................................................................................................56 Registre de travail......................................................................................................................32 RISC............................................................................................................................................61 Routines......................................................................................................................................37 Séquenceur.................................................................................................................................33 Transistor

Contraction de "transfer resistor" (résistance de transfert), le transistor est un composant électronique fondamental, il joue le rôle d'interrupteur

Von Neumann...........................................................................................................................65 - 81 -