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:


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:

  1. 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
  2. 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é.