examen 1 - université lavalwcours.gel.ulaval.ca/2018/a/gif3002/default/8fichiers/gif3002_exa… ·...

8
GIF-3002, 23 octobre 2018 Nom/Matricule : _______Solution__________ Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées sur un total de 30 points. La valeur de chaque question est indiquée avec la question. Une calculatrice scientifique peut être utilisée. Cependant, aucune documentation n’est permise. Vous pouvez répondre aux questions directement sur ce questionnaire et/ou dans le cahier bleu mis à votre disposition. Q1 (1 points): Dites pourquoi la mémoire DRAM est plus lente que la mémoire SRAM, mais moins dispendieuse. Un bit de mémoire DRAM est constituée d’un condensateur et d’un transistor alors qu’un bit de mémoire SRAM est constitué de 6 transistors. Comme il faut plus de composantes la mémoire SRAM est plus dispendieuse. La mémoire DRAM est plus lente parce qu’il faut la rafraichir, parce qu’elle est lue par rangée/colonne (il faut deux coups d’horloge pour indiquer l’adresse) et parce que le matériel pour lire un condensateur est un peu plus lent que la lecture à la sortie d’un inverseur (SRAM). Q2 (3 points): Un étudiant programme un timer pour générer une interruption périodique à toutes les millisecondes. Le timer compte de 0 à 9, incrémente son compte à toutes les 100 microsecondes, puis il recommence. Ce même étudiant implémente aussi du code pour recevoir des messages par UART à 115200bps. Une interruption est générée à chaque fois qu’un octet est reçu. Dans son programme principal, l’étudiant écrit une fonction d’attente, “Wait” comme ci-dessous. Si on retrouve Wait(1000) dans le Main, est-ce que la fonction attendra exactement 1000 millisecondes? Si non, quelles sont les causes d’erreur? Si oui, pourquoi? Main Interruption de timer Interruption de UART void main (void){ InitTimer(); InitUART(); InitNVIC(); while (1){ Wait(1000); …}; void Wait(uint Xms){ uint timestamp; timestamp = msctr; while(msctr – timestamp < Xms){}; } volatile uint msctr; //Interruption toutes les ms void Timer_ISR(void) { msctr++ } //Interruption quand Réception void UART_ISR(void) { char OctetRx; OctetRx = REG_UART_RX; MetOctetDansBuffer(OctetRx); }

Upload: others

Post on 11-Aug-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

GIF-3002, 23 octobre 2018 Nom/Matricule : _______Solution__________

Examen 1

Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées sur un total de 30 points. La valeur

de chaque question est indiquée avec la question. Une calculatrice scientifique peut être utilisée. Cependant, aucune

documentation n’est permise. Vous pouvez répondre aux questions directement sur ce questionnaire et/ou dans le

cahier bleu mis à votre disposition.

Q1 (1 points): Dites pourquoi la mémoire DRAM est plus lente que la mémoire SRAM, mais moins

dispendieuse.

Un bit de mémoire DRAM est constituée d’un condensateur et d’un transistor alors qu’un bit de mémoire

SRAM est constitué de 6 transistors. Comme il faut plus de composantes la mémoire SRAM est plus

dispendieuse.

La mémoire DRAM est plus lente parce qu’il faut la rafraichir, parce qu’elle est lue par rangée/colonne (il

faut deux coups d’horloge pour indiquer l’adresse) et parce que le matériel pour lire un condensateur est

un peu plus lent que la lecture à la sortie d’un inverseur (SRAM).

Q2 (3 points): Un étudiant programme un timer pour générer une interruption périodique à toutes les

millisecondes. Le timer compte de 0 à 9, incrémente son compte à toutes les 100 microsecondes, puis il

recommence. Ce même étudiant implémente aussi du code pour recevoir des messages par UART à

115200bps. Une interruption est générée à chaque fois qu’un octet est reçu. Dans son programme

principal, l’étudiant écrit une fonction d’attente, “Wait” comme ci-dessous. Si on retrouve Wait(1000)

dans le Main, est-ce que la fonction attendra exactement 1000 millisecondes? Si non, quelles sont les

causes d’erreur? Si oui, pourquoi?

Main Interruption de timer Interruption de UART

void main (void){ InitTimer(); InitUART(); InitNVIC(); while (1){ … Wait(1000); …}; void Wait(uint Xms){ uint timestamp; timestamp = msctr; while(msctr – timestamp < Xms){}; }

volatile uint msctr; //Interruption toutes les ms void Timer_ISR(void) { msctr++ }

//Interruption quand Réception void UART_ISR(void) { char OctetRx; OctetRx = REG_UART_RX; MetOctetDansBuffer(OctetRx); }

Page 2: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

Les causes d’erreur seront :

- L’erreur sur la fréquence d’horloge du timer

- Si une interruption de timer survient juste après timestamp = msctr; cela peut fausser l’attente

de presque 1 milliseconde

- Si l’interruption de UART survient juste avant la 1000e interruption de timer, elle peut retarder

l’exécution de la millième interruption

o Les autres interruptions de UART ne devrait pas fausser le temps d’attente : même si

elles retardent une interruption de timer, l’interruption de timer surviendra plus tôt. Le

timer compte indépendamment du traitement de ses interruptions…

- Si le traitement de l’interruption du UART ou de celle du timer prend plus que 1ms, celle peut

fausser le temps.

Q3 (2 points): Dans la question précédente, décrivez le contenu des fonctions InitTimer, InitUART et

InitNVIC. Quelles instructions et quel code devrait-on retrouver dans ces fonctions?

Inventez des noms clairs et explicites pour les variables et fonctions que vous utiliserez. Par exemple,

REG_UART_RX pourrait être le registre de réception du UART, contenant le dernier octet reçu.

Les registres d’horloges du timer sont configurés (REG_PRESCALE, REG_CLOCK_SEL,

REG_AUTO_RELOAD_VALUE)

Les registres d’horloges de mode du timer sont configurés pour que le timer génère une interruption

périodique (REG_TIMER_CTRL)

Les registres d’horloge du UART seront configurés (REG_UART_BAUDRATE)

Les registres des broches du UART seront configurés pour être reliées au UART (REG_GPIO_MODE)

Les registres de contrôle du UART seront configurés pour générer une interruption lors de la réception

(REG_UART_CTRL)

Les registres du NVIC seront configurés pour activer les interruptions de timer et UART et leur donner une

priorité

Q4 (1 points): Un étudiant relie directement un bouton à son microcontrôleur afin de contrôler une

machine à café qui ajoute un lait à toute les fois que l’on appuie sur le bouton : appuyer sur le bouton

génère une interruption dans laquelle on augmente la quantité de lait à mettre. Ce bouton n’opère pas

toujours comme désiré. Expliquez pourquoi et dites comment améliorer l’interface.

Microcontrôleur

On assume que la pull-up interne de la broche de microcontrôleur est activée. Sinon, ça ne marcherait

pas.

Le problème principal vient des rebonds. Quand on appuie sur le bouton, le contact mécanique rebondit

et cela génèrera une séquence très rapide de 0-1-0-1-0-1… pendant quelques millisecondes. Pour régler

Page 3: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

le problème on peut faire une machine d’état logicielle qui attendra que les rebonds soient finis avant de

déclarer que le bouton est appuyé ou relâché.

Le bouton est aussi susceptible aux décharges électrostatiques tel qu’implémenté.

Q5 (1 points): Décrivez ce qu’est un registre, d’un point de vue matériel et d’un point de vue logiciel.

D’un point de vue matériel, un registre est une petite mémoire (un ensemble de bascules D par exemple)

très rapide qui joue un rôle particulier dans un circuit-intégré.

D’un point de vue logiciel, un registre est une variable de petite taille qui peut avoir un effet sur le

matériel lorsqu’on la lit ou l’écrit.

Les registres du microprocesseur servent pour faire des calculs ou pour l’exécution des instructions. Les

registres des périphériques servent à fournir une interface entre les instructions/bus

système/microprocesseur et le matériel du périphérique.

Q6 (5 points): Les énoncés qui suivent sont totalement ou partiellement faux. Dites pourquoi l’énoncé

est faux et indiquez comment le corriger en gardant l’esprit de l’énoncé.

# Énoncé

A Toutes les mémoires ont une broche “Enable” qui permet d’activer ou de désactiver la mémoire. Le rôle principal de cette broche est de réduire la consommation énergétique de la mémoire. Pour désactiver une mémoire, comme un périphérique, on coupe habituellement son horloge.

Le rôle principal de la broche Enable est de permettre de relier plusieurs mémoires au même bus.

B Ajouter une instruction complexe au jeu d’instruction du microcontrôleur permet de réduire le nombre d’instructions utilisées par le compilateur. Cela réduit la taille des programmes et permet une exécution plus rapide de ceux-ci parce qu’ils sont plus petits.

L’instruction complexe est… complexe et plus longue à exécuter. Cela nuit à l’exécution en parallèle des instructions qui devraient avoir la même longueur pour un pipeline efficace. Cela cause aussi des problèmes de performances comme le retard du traitement d’une interruption quand il faut finir une instruction complexe avant d’entrer dans l’interruption.

C Pour toutes les broches du microcontrôleur, sauf pour les broches d’alimentation, il y a un contrôleur individuel qui permet de déterminer le rôle de la broche. En effet, chaque broche peut avoir plusieurs rôles comme Digital Input/Ouput, Analog Input/Output ou Périphérique. Dans le cas Périphérique, la broche peut être contrôlée par n’importe quel périphérique du système.

Il y a un contrôleur de GPIO qui gère plusieurs broches du microcontôleur ensemble. Ces broches peuvent être contrôlée en entrée, en sortie, en analogique ou gérée par un périphérique (alternate function)

D Le microprocesseur sait comment gérer les signaux de contrôle, d’adresses et de données pour accéder à la mémoire. Il n’a pas besoin d’instructions pour lui dire comment accéder aux données. Le microprocesseur sait aussi comment gérer les signaux de contrôle, d’adresses et de données pour manipuler chaque périphérique du système. Il n’a pas besoin d’instructions pour lui dire comment accéder aux périphériques.

Le microprocesseur sait comment accéder aux mémoires pour lire et exécuter des instructions. C’est par le biais d’instructions load/store qu’il accède aux registres des contrôleurs de périphériques.

Page 4: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

E Le microprocesseur sait lorsqu’une interruption se termine. Lorsque vous finissez une routine traitant une interruption par “}”, le microprocesseur repère ce symbole dans le code et sait, de ce fait, quand revenir de l’interruption.

Le compilateur met l’instruction appropriée à la fin d’une routine traitant une interruption pour que le microprocesseur, exécutant cette instruction, retourne de l’interruption.

Q7 (2 points): Certaines mémoires ont des mots de 16 bits. Ces mémoires opèrent parfois dans un

système microprocesseur où une adresse désigne un mot de 8 bits. Pour que les mémoires 16-bits

soient compatibles avec les systèmes 8-bit, ces mémoires ont une broche qui permet de désigner les

premiers 8-bits du mot ou les derniers 8-bits du mot de 16 bits : la broche HB/𝐿𝐵̅̅̅̅ . Quand la broche vaut

1, c’est la partie supérieure du mot de 8-bits qui est choisie. À quelle broche d’un microcontrôleur 32-

bits relie-t-on la broche HB/𝐿𝐵̅̅̅̅ habituellement?

A) B) C) D) E) F)

A0 (adresse 0) A31 (adr. 31) D0 (donnée 0) D31 (donnée 31) Lecture Contrôle MSB

Expliquez votre réponse.

C’est toujours l’adresse qui désigne un octet de mémoire ou un registre du système. Si on met A0 du

microprocesseur sur HB/LB et si on met A1-A31 du microprocesseur sur les adresses A0-A30 de la

mémoire, les mots 16 bits de la mémoire seront lus en mots de 8bits par le microprocesseur.

Q8 (2 points): Énumérez et décrivez brièvement toutes les étapes de production d’un petit appareil

électronique.

- Inspection préliminaire des pièces et des PCBs au besoin

- Préparation des pièces et des PCBs au besoin : certains circuits intégrés doivent être préchauffés

pour évacuer l’humidité.

- Préparation en vue de la soudure : de la pâte d’étain est mise sur le PCB et les pièces sont placées

sur la pâte.

- Soudure des pièces surface-mount (reflow soldering)

- Soudure manuelle des grosses pièces

- Tests et inspection des PCBs individuels, peut se faire sur des échantillons

- Calibration des PCBs individuels au besoin

- Assemblage des PCBs constituant le produit

- Test du produit assemblé, peut se faire sur des échantillons

- Calibration du produit individuel au besoin

- Mise en boîtier du produit

- Test du produit mis en boîtier au besoin, peut se faire sur des échantillons

- Ajouts de protections contre l’humidité au produit : vernissage, epoxy, autres

- Test du produit protégé, peut se faire sur des échantillons

- Préparation du produit pour la vente : étiquettes, programmation finale, etc.

- Test du produit fini, peut se faire sur des échantillons

- Tests de longévité sur le produit fini avec des échantillons.

Page 5: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

Q9 (3 points): La fonction sin(float x) est appelée dans une interruption périodique de timer et dans le

programme principal. Elle calcule le sinus de x en développant une série de Taylor :

Main Interruption de timer Fonction sin

void Main(void){ InitSystick(); while(1){ … Y = sin(X); … }

void SystickHandler(void) { … A = sin(B); … }

float sin(float Valeur){ int i; float SommeTaylor; float Terme; SommeTaylor = Valeur; Terme = Valeur; /////// Interruption arrive ICI for(i =1; i < 32; i++) { Terme = Terme*-1*Valeur*Valeur/(2*i)/(2*i+1); SommeTaylor = SommeTaylor + Terme; }};

Supposons que l’on appelle d’abord la fonction sin à partir du Main (Y= sin(X)). Puis, supposons qu’une

interruption de timer survienne juste après que Terme = Valeur; soit exécuté (Terme = X). Enfin,

supposons que la fonction A = sin(B) soit exécutée dans l’interruption. Cet appel de la fonction sin à

partir de deux contextes différents peut-elle causer une erreur d’intégrité de données? Par exemple,

est-ce qu’on pourrait obtenir Y = sin(B)? Si oui, expliquez pourquoi et dites comment corriger le

problème. Si non, détaillez ce que fait le compilateur pour gérer la situation.

La situation sera gérée correctement. Dans le main, X sera passé sur la pile ou dans un registre. Puis,

dans la fonction sin, SommeTaylor et Terme, seront soit des registres, soit de l’espace réservé sur la pile.

Quand l’interruption survient, les registres sont empilés et donc sauvegardés. Lorsqu’on appelle A=sin(B),

de nouvelles adresses de mémoires sont utilisées sur la pile.

Q10 (2 points): Un petit microprocesseur a seulement 16 broches. Ce microprocesseur était branché par

RS232 à un ordinateur, mais il a fallu utiliser du RS485 pour augmenter la portée du lien de

communication. Malheureusement, il faut gérer une broche “Output Enable” pour que le

microprocesseur puisse transmettre des données sur le bus RS485. Il faut aussi gérer une broche

“Receive Enable” pour que le microprocesseur puisse recevoir. Or, le microprocesseur n’a que 2 broches

(UART_TX et UART_RX) pour la communication. Toutes les autres broches sont utilisées. Heureusement,

Serge Mac Ingliss, un ingénieur électrique expérimenté lui a proposé la solution suivante trouvée sur

Google :

A+

B-

C

D R OE

RE

UART_RX

UART_TX

Microprocesseur

Bus RS485

MAX485

IGND

Page 6: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

Sachant que UART_TX est à “1” ou 3.3V quand on ne transmet pas (“idle” high) et sachant qu’on veut

recevoir quand on ne transmet pas, expliquez quels sont les rôles des composantes du design de SMI

(Condensateur, Résistance, Diode et Inverseur) pour que ça fonctionne.

Par défaut, UART_TX est à “1” implique que le condensateur C se chargera tranquillement (à travers R).

Au bout d’un certain temps, C sera suffisament chargé pour que l’Inverseur mette 0 sur RE/OE et active la

réception : on écoute quand on ne transmet pas.

Lors du début de la transmission, UART_TX devient “0” (start bit). La diode D se met à conduire et

décharge très rapidement (presque instantané) le condensateur. Ainsi, le “0” initial sera transmis sur la

ligne.

Après le 0 initial, on peut transmettre jusqu’à 8 “1” de suite et un stop bit. Le RC est calculé pour que la

transmission dure au moins un octet, même si on transmet uniquement des “1” après le start bit…

Q11 (5 points): Le groupe de recherche Solar Measurement Instrument a créé une antenne spéciale

pour mesurer le rayonnement solaire. Cette antenne est reliée à un appareil, le SMI_A, avec un ADC 12

bits ayant plusieurs canaux multiplexés comme illustré ci-dessous. Afin de mesurer le rayonnement

solaire, le programme gérant le SMI_A doit sélectionner le canal de l’antenne, puis il doit prendre 1024

échantillons. En parallèle, le SMI_A est branché sur un ordinateur distant par un lien RS485. Cet

ordinateur envoie des commandes périodiquement pour lire les mesures de rayonnement solaire.

L’ordinateur envoie également des commandes pour lire des paramètres météos sur d’autres canaux de

l’ADC, afin de corriger les mesures de rayonnement solaire en fonction de la température :

Ordinateur

UART

Antenne

PressionHumidité

Température

Filtre

FiltreFiltreFiltre

ch1

ch4

ch5

ch6

ADCin

REG_CH_SEL

3.3V

out

Vref

REG_ADC_VAL

REG_ADC_CTRL

MAX485

MicroprocesseurMémoire

Autres Périphériques

USB-RS

485

Très long câble

Timer

Un étudiant en physique a implémenté le programme comme suit :

Main Routine traitant int. du UART Routine traitant int. du timer void Main(void){ int Ret; InitUART(); InitADC(); InitNVIC(); while(1){ if(CommandeRecue){ CommandeRecue = 0; if(Commande == LIS_TEMP){ Ret = Lecture_ADC(6); RepondUART(Ret); } if(Commande == LIS_PRES){ Ret = Lecture_ADC(4);

volatile char CommandeRecue; char Message[64]; void UART_Handler(void){ char OctetRecu; OctetRecu = REG_UART_RX; If(DecodeMessage(OctetRecu)) { CommandeRecue = Message[3]; }} int Lecture_ADC(char Canal){ static PrevCanal;

volatile int Sol; int ADCBuffer[1024]; void Timer_Handler(void){ int i; int ADCBuffer[1024]; for(i = 0; i < 1024; i++){ ADCBuffer[i] += Lecture_ADC(1); } Sol = CalculeRayonne(ADCBuffer); }

Page 7: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

RepondUART(Ret); } if(Commande == LIS_HUMI){ Ret = Lecture _ADC(5); RepondUART(Ret); } if(Commande == LIS_SOLEIL){ Ret = Sol; RepondUART(Ret); } }}}

if(Canal != PrevCanal){ REG_CH_SEL = Canal; PrevCanal = Canal; } /// *** INT ICI *** /// REG_ADC_CTRL = SAMPLE; while(REG_ADC_STATUS != FINI){}; return REG_ADC_VAL; }

A) Malheureusement, le programme de ce futur physicien retourne parfois des données erronées.

Les données sont habituellement valides, mais des valeurs aberrantes apparaissent de temps en

temps Pourquoi? Comment faire pour corriger la situation?

Le programme plante parce que le Canal d’ADC choisi est changé dans deux contextes différents.

Supposons qu’on reçoive une commande pour lire l’humidité par exemple. Dans le main, on choisira alors

le canal 5. Or, si une interruption de timer arrive juste après le choix du canal 5, mais avant la lecture de

l’ADC dans le main (voir INT ICI plus haut), on changera le canal à échantillonner dans l’interruption.

Celui-ci ne sera plus correct au retour de l’interruption.

Correction : désactiver les interruptions qui peuvent couper la sélection de canal et la lecture de l’ADC.

B) Si l’ADC 12 bits retourne une valeur de 2304, quelles sont les valeurs possibles de la

température, sachant que le voltage à l’entrée de l’ADC est de 1V par 10 degrés Celcius (la

lecture fonctionne de 0oC à 33oC)?

L’entrée de l’ADC sera entre :

[2304

212∗ 3.3 ∗ 10 𝑒𝑡

2305

212∗ 3.3 ∗ 10[

C) Pour quelle(s) raison le RS485 permet-il de communiquer l’information sur de grandes

distances?

La transmission se fait en différentiel sur deux fils.

D) Si on suppose que prendre 1024 échantillons d’ADC est trop long et que l’interruption de timer

dure beaucoup trop longtemps, comment pourrait-on améliorer le système?

En utilisant le DMA

Q12 (1 points): Quelles sont les principales différences entre le timer Systick et les autres timers de

votre système?

Le systick est implémenté par le concepteur du cœur ARM. On retrouve ce timer dans tous les

microcontrôleurs ARM. Les timers, quant à eux, sont implémentés par le manufacturier du

microcontrôleur.

Le systick est simple et se programme en mode auto-reload seulement pour générer des interruptions

périodiques. Les autres timers sont plus complexes et flexibles. Ils permettent de faire des captures, de

Page 8: Examen 1 - Université Lavalwcours.gel.ulaval.ca/2018/a/GIF3002/default/8fichiers/GIF3002_Exa… · Examen 1 Cet examen vaut 30% de la note totale du cours. Les questions seront corrigées

faire des comparaisons pour générer des PWMs, de compter des pulses ou de mesurer leur durée, de

combiner plusieurs timers, de mesurer un temps fixe puis d’arrêter, et plus…

Q13 (2 points): Le premier élément de la datasheet du STM32F407 se décompose en trois items :

A) Core: ARM® 32-bit Cortex®-M4 CPU with FPU

B) Adaptive real-time accelerator (ART Accelerator™) allowing 0-wait state execution from Flash memory

C) Frequency up to 168 MHz, memory protection unit, 210 DMIPS/ 1.25 DMIPS/MHz (Dhrystone 2.1), and

DSP instructions

En trois courts paragraphes, expliquez ce que signifie chacun des items de la datasheet. Dites également quels sont

les impacts de ces caractéristiques sur le programmeur.

A1) Le microprocesseur a un bus d’adresse 32 bits, un bus de données 32 bits, des registres 32 bits…

A2) Le microprocesseur est conçu par Keil (les gens de Arm) qui octroie une licence à STM pour l’utiliser

A3) Le microprocesseur ARM M4 est un microprocesseur pour petites applications

A4) FPU signifie que le microprocesseur contient des circuits logiques pour manipuler des fractions

B1) Le microcontrôleur a une cache qui permet de lire les instructions à la même vitesse que le cœur.

C1) Lorsqu’exécuter sur un benchmark avec les programme énuméré par Dhrystone, le microprocesseur peut

exécuter 210 Millions d’Instructions Par Seconde.

C2) Le microprocesseur a un MPU qui permet de protéger la mémoire lorsque plusieurs processus s’exécute avec un

système d’exploitation préemptif.

Question Bonus (3 points): Lorsqu’un programmeur veut communiquer avec une mémoire externe, il

configure l’interface parallèle de son STM32F407. Ce faisant, il attribue une plage d’adresse à la

mémoire externe. Par exemple, les adresses 0x60000000 à 0x6000FFFF permettront de lire une

mémoire externe DRAM de 64 KiloOctets. Décrivez ou dessinez le circuit logique nécessaire pour

implémenter l’interface parallèle lorsque celle-ci est faite pour gérer une mémoire DRAM ou une

mémoire SRAM.