Z80 - Echanges I/O et application au RC2014 avec la carte Digital I/O
Bonjour à tous,
Wah! quel long titre!!! C'est normal, nous allons combiner deux matières.
Comme promis dans l'article de test, maintenant que nous savons utiliser OUT et INP pour contrôler la carte Digital I/O nous allons maintenant nous pencher sur son électronique pour comprendre comment elle fonctionne... cela nous aidera à créer nos propres solutions.
Module Digital I/O pour RC2014 |
Mais juste avant, nous allons devoir faire un petit détour par l'accès mémoire du Z80. En effet adresse la mémoire et les I/O sont assez similaires.
Adressage mémoire sur le Z80
Pour commencer, le Z80 dispose de 16 lignes d'adresses, ce qui permet d'adresser 64 Kio de mémoire pour la RAM et ROM confondu.
Les lignes d'adresses sont en sortie uniquement.
Le but de données est constitué de 8 bits (D0 à D7) bidirectionnels. Cela signifie que ces broches peuvent être configurée en entrée ou en sortie par le microcontrôleur. Ce sont les seules broches qui en sont capable.
La RAM stocke les données générée par le programme tandis que la ROM contient le programme à exécuter. La ROM débutant généralement à l'adresse 0.
Avec 16 bits d'adresses, il est possible d'accéder à n'importe quelle adresse entre 0 et 65535 (entre 0x0000 et 0xFFFF en hexadécimal car c'est plus facile à lire et à mémoriser).
Organisation mémoire avec une ROM 8Ko (Basic) |
Le signal /MREQ (memory request) passe au niveau bas durant un accès mémoire.
La différence entre lecture et écriture se fait via les signaux /RD (read=lecture) et /WR (write=écrire) qui passe au niveau bas.
Enfin, il ne faut pas négliger un autre signal important, c'est /M1 qui passe au niveau bas lorsque le CPU lit la prochaine instruction du programme (celle à exécuter par le CPU au cycle suivant).
Adressage des I/O sur le Z80
Le Z80 dispose d'un mécanisme d'adressage similaire à la mémoire MAIS séparé pour les périphériques (les entrées/sorties). Sur un Z80, il y a deux espaces d'adressages différents (Mémoire et I/O).
L'adressage des entrées/sorties se fait uniquement sur 8 bits (et non 16 bits comme la mémoire). Comme pour la mémoire, il est possible de lire (/RD) sur l'adresse du port I/O ou écrire (/WR) sur le port I/O.Enfin, la broche /IORQ passe au niveau bas durant un accès I/O (à la place de /MREQ pour un accès mémoire).
Une petite note concernant le signal /M1 qui intervient aussi dans le cadre des accès I/O mais uniquement dans le cadre du traitement des interruptions (il faut juste s'assurer qu'il reste bien au niveau haut durant le traitement de l'IORQ pour être certain de ne pas être dans un traitement d'interruption ;-) ).
Le module Digital I/O
Nous allons commencer par les grands blocs du module avant de rentrer dans les détails.
Blocs du module Digital I/O |
En vert la partie lecture, en rouge la partie écriture.
Le connecteur reprend également les couleurs utilisée sur le brochage CPU si avant.
Ecriture sur le bus
En écrivant des données sur le bus alors il est possible de contrôler les LEDs du module.
Ecriture sur le bus --> LED. |
Le 74LS374 est un flip-flop 8 bits à 3 états. Il est capable de mémoriser l'état de 8 bits un flan montant.
A gauche du 74LS374 on retrouve le bus de donnée. A droite les LED. So une sortie Qx est à 5V alors la LED est allumée.
La broche Cp (clock pulse) transfère les données du bus Dx --vers--> Qx (vers les sorties correspondantes) lorsqu'il y a un flan montant sur la broche d'horloge.
Comme c'est aussi un Latch, les données restent "mémorisée" même si les données disparaissent sur le bus de données.
La broche /OE (Output Enable) est maintenue au niveau bas (à la masse) pour que l'information stockée soit présentée en permanence sur les sorties... ce qui est peu le but recherché vue qu'on veut voir les LEDs.
Lecture sur le bus
En pressant les boutons du module Digital I/O, il est possible de modifier les données qui seront lue sur le bus part une opération de lecture.
Cette opération de lecture se fait par l'intermédiaire d'un 74LS245 qui est un bus transceiver. Cela signifie qu'il peu passer les données d'un bus A vers un bus B (soit dans un sens A-->B, soit dans l'autre sens A<--B ) OU isoler les deux bus l'un de l'autre (A -->| |<-- B).
Boutons --> Lecture sur le bus |
Alors comme la lecture ne se fait que dans un seul sens la broche /DIR reste au niveau bas parce que le sens sera toujours A<---B. Donc signal de sortie côté A (faible impédance) et entrée côté B (donc forte impédance).
Fonctionnement des boutons: derrière chaque entrée B, il y a un montage bouton et résistance. La résistance de rappel tire le potentiel de la broche vers 0V (la masse) par défaut. Cette résistance est dite pull-down.
Si un bouton est pressé alors une ligne Bx alors cette si est branchée directement sur le +5V via le bouton (donc au niveau haut). Note: dans ce dernier cas, la résistance pull-down évite un court-circuit direct entre la masse et le +5V
Enfin, le signal /CE passe au niveau bas uniquement lors d'une lecture sur le bus (pour passer de la situation bloquante A -->| |<-- B vers à la situation injection des valeurs sur le bus A<--B ).
Le démultiplexeur
Le démultiplexeur est le coordinateur central de cette carte. Il a été utilisé avec une certaine ingénuité (mais nous vairons cela plus tard). Nous allons commencer par détailler sont fonctionnement.
Démultiplexeur 3 bits vers 8 lignes |
3 bit d'adresse en entrée A0 à A2 permettant le codage binaire des valeurs de 0 à 7. Ex: valeur 6 se code 0b110 en binaire (soit A2=1,A1=1,A0=0).
8 lignes de sorties /Y0 à /Y7 qui son activée en fonction de la valeur binaire présentée en entrée sur A0-A2. Comme ce sont des sorties inversées, la sortie activée passe au niveau BAS (les autres restent au niveau haut). Dans le cas de l'exemple ci-dessus (0b110), c'est /Y6 qui passe au niveau bas.
Cela tombe bien que les sorties soient inversées... car les autres composants utilisent des signaux /OE (output enable) ou /EN (enable) en logique inversée.
Le bloc Enable est composé des signaux G1, /G2B, /G2A. Pour que la sortie /Yx soit activée (passe au niveau bas) en fonction des bits A0-A2 en entrée, il faut que les conditions suivantes soient toutes rencontrées: G1=HAUT et /G2B=BAS et /G2A=BAS . C'est a croire que l'ingénieur était sous LSD en créant le composant... c'est pourtant super pratique.
Le démultiplexeur en action
C'est maintenant que l'on va inspecter le fonctionnement du démultiplexeur.
Le démultiplexeur au coeur du module Digital I/O |
Pour commencer, la carte doit uniquement être active lors d'un IORQ (IORequest), donc lorsque IORQ est LOW. IORQ est donc branché sur /G2B
Ensuite, il ne faut pas interférer avec le processus d'interruption. Le module digital I/O ne peut pas être actif en même temps que /M1. Donc si /M1 est Low (/M1 = actif), cela signifie qu'il ne faut pas dialoguer avec le module Digital I/O.
C'est pour cela que /M1 est connecté sur G1. Note: /M1 est mal noté sur le connecteur.
Enfin, seules les adresses A0 et A1 du bus sont utilisées avec le module Digital I/O mais il faut empêcher le module de fonctionner si d'autres bits d'adresses A2 à A7 sont utilisées. C'est le but des diodes... si l'une de ces lignes adresses est au niveau haut, cela signifie que le signal /G2A est au niveau haut et donc que le multiplexeur est désactivé. Utiliser des diodes évite aux lignes d'adresse de se déverser les unes dans les autres (intelligent!). Enfin la résistance pull-down R17 permet de maintenir le signal /G2A au niveau bas toutes des lignes d'adresses A2 à A7 sont inactive... et active donc le multiplexeur.
Un petit coup de génie avec le signal /WR :
Jusque là le multiplexeur et la carte Digital I/O sont actifs dans les bonnes conditions (c'est IMPORTANT).
Il faut maintenant faire en sorte que:
- La partie /RD (read) soit active sur le bus de données lors d'opération /RD (= not /WR).
- La partie /WR (write) soit active sur le bus de données lors d'une opération /WR.
/WR est connecté sur la ligne A2 du multiplexeur.
Donc si /WR est HIGH... c'est que l'on fait une lecture puisque /RD est LOW (souvenez-vous, c'est mutuellement exclusif!). Dans pareil cas, A2=HIGH sur le multiplexeur pour une adresse entre 0b100 et 0b111 (entre 4 et 7) suivant A0 et A1. C'est donc la partie supérieure du montage qui est actif (activant ainsi le 74LS245 qui présente ses données sur le bus).
A l'opposé, si /WR est LOW, c'est que l'on fait vraiment une opération d'écriture sur le bus. Dans ce cas, A2=LOW et les seules valeurs possibles sont 0b011 à 0b000 (entre 0 et 3). Et c'est la partie inférieure du montage qui s'active (activant ainsi le 74LS374... attention, uniquement lorsque le signal /Yx repassera au niveau haut à la désactivation de l'écriture).
Les bit d'adresses A0 et A1 :
les lignes d'adresses A0 et A1 permettent d'indiquer le "port" utilisé en entrée ou sortie entre 0..3 sur la carte Digital I/O. Il est donc possible de placer jusque 4 cartes digital I/O.
Si l'on veut utiliser le port 3 sur le module Digital I/O, il faudra A0=HIGH et A1=HIGH (et placer les deux cavaliers sur le port 3 de la carte).
Il sera ensuite possible d'utiliser les instructions
- OUT 3, 255 pour allumer toutes les LEDs sur le port 3 (adresse 0x03).
- INP(3) pour obtenir l'état des entrées sur le port 3 (adresse 0x03).
Hacker le module Digital I/O
Hacker c'est un grand mot mais si vous n'utiliserez qu'une seule carte Digital IO alors vous pouvez envisager libérer les adresses 0x01, 0x02 et 0x03 (pour n'utiliser que l'adresse 0x00 pour contrôler le module).
On utilise deux diodes complémentaires sur les lignes d'adresse A0 et A1 du connecteur.
Ensuite les lignes A0 et A1 du 74LS138 sont maintenues à la masse (pour toujours utiliser l'adresse 0x00).
Voici une petite modification du schéma pour l'utiliser que l'adresse 0x00 (il est possible de le mettre en oeuvre depuis les cavaliers A0 et A1.
N'hésitez à communiquer vos commentaires ou questions.
Dominique
Écrire un commentaire