Solution de TD I2C
Sujet sur tdethindus2distanciel
1.1: Sur le bus, les niveaux electriques possibles sont 0V et VCC, imposé par la resistance de Pull-up. Vcc peut être de 5V,3.3V,3V,1.8V ou autre.
1.2: Sur une broche d'un composant I2C, de type collecteur ouvert, on trouve soit l'état bas (0V) soit l'état haute impédance.
1.3: Il faut utiliser des resistances de Pull-up pour mettre les lignes à l'état Recessif (VCC)
1.4: Théoriquement, il y a 7 bits d'adresse donc on pourrait adresser 2^7=128 composants. Mais en pratique, certaines adresses sont reservées et les impédances d'entrée non infinies des composants font que la tension electrique imposée par le Pull-up serait vu affaiblie sur les entrées des composants au point qu'ils risqueront de voir un état bas.
1.5: I2C est Half-duplex, car il y a un seul canal de donnée pour les 2 sens de communication, il faut donc alterner.
1.6:
- begin() configuration du périphérique USART en mode I2C
- requestFrom() génère une transaction en lecture d'un certain nombre d'octets et met les octets lu dans la fifo de reception
- available() retourne le nombre d'octets disponibles en lecture dans la fifo de reception
- read() lit le premier octet de la fifo de reception
- beginTransmission() prépare une transaction en écriture
- write() écrit des octets dans la fifo d'émission vers le bus I2C
- endTransmission() déclenche l'envoi effectif des données de la fifo d'emission vers le bus
- SetClock() configure la fréquence d'horloge du bus I2C
2.1: Ajouter un port d'entrées/sorties 8 bits
2.2: Les broches d'adresses permettent d'attribuer une adresse différente à différents composants sur le bus, par exemple pour pouvoir utiliser plusieurs fois le même composant sur un même bus.
2.3: Les PCF8574 et PCF8574A ont une combinaisons de 4 bits différents pour les bits de poids fort d'adresse. Ceci permet de choisir une adresse parmi 16. Pour le PCF8574A, les adresses 7birs s'étendent de 0x38 à 0x3F
2.4 et 2.5: Voir exercice 2 sur tdcom2
2.6: voir TP I2C. L'adresse 0x2 n'est pas valide donc le composant PCF8574A ne génèrera pas d'acquitement et la transaction comportera uniquement une phase d'adressage. La fonction retournera -1 pour indiquer que la lecture n'a pas été possible.
2.7: voir TP I2C. L'adresse 0x38 est valide pour le composant PCF8574A avec les bits d'adresses connectés tel qu'indiqué, donc le composant PCF8574A génèrera l'acquitement et la transaction comportera une phase d'adressage et une phase d'échange des données avec la donnée 0x27 envoyé par le PCF8574A. La fonction retournera 0 pour indiquer que la lecture a été possible.
2.8 et 2.9: Voir exercice 2 sur tdcom2
2.10 L'adresse 0x39 est valide pour le composant PCF8574A avec les bits d'adresses connectés tel qu'indiqué, donc le composant PCF8574A génèrera l'acquitement et la transaction comportera une phase d'adressage et une phase d'échange des données avec la donnée 0x82 envoyée par l'Arduino. La fonction retournera 0 pour indiquer que l'écriture a été possible.
2.11
- recopie.ino
void setup(){ Wire.begin(); // joindre le bus i2c en tant que maître writePort8574( SLAVE_ADDR_8574_B , 0xff); //configure le composant B en entrée } void loop(){ char val; if (readPort8574(0x38,&val)==0) writePort8574(0x38+3, val); }
3.1 Le composant DS13072 est une horloge temps réel. Comme une montre à quartz sauf qu'au lieu d'utiliser des boutons pour régler l'heure et la date et un écran pour l'afficher, il utilise le bus I2C pour échanger les informations.
3.2 Le PCF8574 était vu comme un unique registre accessible en lecture/écriture. Le DS13072 comporte 64 cases d'adresses différentes, il faut donc pouvoir selectionner quelle case parmis les 64 est lue ou écrite.
3.3: Compteur modulo 10 pour les unités de seconde, sa remise à zéro incrémente les dizaines de seconde qui sont aussi modulo 6 etc… jusqu'au numéro de l'année. L'intérêt d'utiliser le BCD est que les différents compteurs fournissent les valeurs sous une forme directement utilisable pour affichage en base 10, ce qui évite la conversion de binaire vers décimal.
3.4,3.5,3.7 et 3.8:
- dssoluce.ino
////////////////////////////////////////// char readRegI2C(char I2Caddr, byte Regaddr, byte * ptr_value) /*I2Caddr, l'adresse du composant sur le bus Regaddr, l'adresse du registre à lire ptr_value, pointeur pour renvoyer la valeur lue dans le registre retourne -1 si échec 0 sinon */ { Wire.beginTransmission(I2Caddr);//démarre la transmission avec l'adresse du pérpiphérique Wire.write((byte)Regaddr); //envoie l'adresse de la case if (Wire.endTransmission()!=0) //stoppe la transmission return -1; Wire.requestFrom((byte)I2Caddr,(byte) 1);// demande la lecture d'1 octet depuis l'adresse du pérpiphérique if (Wire.available()==1) //si l'octet est disponible { (* ptr_value) = Wire.read(); // lire l'octet return 0; } else return -1; } ////////////////////////////////////////// char writeRegI2C(char I2Caddr, byte Regaddr, byte value) /* I2Caddr, l'adresse du composant sur le bus Regaddr, l'adresse du registre à écrire value,la valeur à écrire dans le registre retourne -1 si échec 0 sinon */ { Wire.beginTransmission(I2Caddr);//démarre la transmission avec l'adresse du pérpiphérique Wire.write((byte)Regaddr); //envoie l'adresse de la case Wire.write((byte)value); //envoie la donnée if (Wire.endTransmission()==0) //stoppe la transmission return 0; else return -1; }
3.6: Une seule transaction: phase d'adressage en écriture pour l'adresse 0x68 avec un acquitement, puis phase d'échange de donnée 0x02, puis phase d'échange de donnée 0x52 . La fonction retourne 0 car l'écriture est possible.
3.9:
- Première transaction:phase d'adressage en écriture pour l'adresse 0x68 avec un acquitement, puis phase d'échange de donnée 0x01 pour sélectionner le registre dans le DS13072
- Seconde transaction:phase d'adressage en lecture pour l'adresse 0x68 avec un acquitement, puis phase d'échange de donnée 0x21 pour récupérer la donnée lue depuis le registre dans le DS13072
3.10: Il s'agit du schéma de tdcom2 lorsque le module additionnel RTC est connecté.