L'I2C est un bus conçu par Philips pour l'interconnection entre circuits intégrés.
Pour la petite histoire Philips Semi-conducteurs s'appelle maintenant NXP.
L'I2C est une vrai norme elle a ses règles.
Un seul maître peut diriger le bus, les autres composants I2C étant des esclaves.
Chaque esclave I2C possède une adresse propre sur 1 octet (8bits).
L'adresse est composé d'une mnémonique correspond à une "famille" suivi d'une adresse "personnelle". Le total des deux faisant 7 bits, le 8eme bit composant l'adresse est là pour dire si le maître veut écrire dans l'esclave ou lire dans l'esclave.
Les familles sont gérées par NXP maintenant. Par exemple le PCF8574 appartient à la famille "0100" et il possède 3 bits A0,A1,A2 configurables ce qui fait que l'on peut avoir jusqu'à 7 PCF8574 sur le même bus.
Le DS1307 est particulier dans le sens où se serait ridicule d'avoir plusieurs DS1307 sur le même bus : il n'a pas de bits d'adresse configurable.
Donc voilà pour les adresses.
Parlons de Wire !
Pour commencer la bibliothèque Wire n'existe pas c'est un abus de langage.
Ce qui existe c'est la bibliothèque TwoWire. Les auteurs de la bibliothèque TwoWire ont instancié eux même un objet Wire: dans la dernière ligne du fichier Wire.cpp on peut lire la ligne suivante :
TwoWire Wire = TwoWire() ;
qui est bien une instanciation de l'objet Wire. Ceci pour vous simplifier la vie, mais aussi ajouter de la confusion.
La gestion de l'I2C est assez complexe, la bibliothèque "Wire" le fait très bien cela ne vaut pas le coup de réinventer la roue, par contre je n'en dirait pas autant des bibliothèques DS1307 qui a mon avis sont complètement inutile : il est préférable de passer le temps nécessaire à leur compréhension à comprendre le fonctionnement de Wire et de lire la datasheet du composant à piloter. Au moins quand cela ne se passe pas comme prévu tu ne reste pas le bec dans l'eau à ne rien comprendre, enfin c'est ma manière de procéder.
Pour trouver l'adresse du DS1307 tu peut utiliser un scanner de bus I2C (celui de fdunews est le plus ergonomique que j'ai vu, je recommande chaudement) mais c'est entièrement passif et si tu as plusieurs esclaves I2C c'est foutu. Beaucoup plus efficace est la lecture de la datasheet où tu trouvera la "famille", le nombre de bits d'adresse configurables et la signification de tous les registres.
Pour signifier à un esclave que le maître veut lui parler il faut écrire
Wire.beginTransmission(adresse_composant); // (Famille plus adresse configurable), le dernier bit Read/Write c'est Wire qui le gère
Ensuite il faut indiquer à quelle adresse INTERNE de l'esclave le maître veut intervenir
Wire.write(adresse_du_registre_de_l_esclave) ;
Ensuite il faut soit lire
octet_lu = Wire.read();
soit écrire :
Wire.write(donnee) ;
Revenons au DS1307.
Pour écrire dans un registre il suffit de faire , aprés un Wire.begin() dans le setup() bien sûr qui configurera l'ATMega.
void ecrit_ds1307(uint8_t registre, uint8_t donnee)
{
Wire.beginTransmission(0x68); // indique au DS1307 d'adresse hexadecimale 0x68 que le maître veut lui parler
Wire.write(registre); // Le maître indique à l'esclave qu'il veut intervenir sur le registre indiqué
Wire.write(donnee); // Le mâitre écrit l'octet "donnee"
Wire.endTransmission(0x68); // le maître libère l'esclave
}
Pour lire un registre
uint8_t lit_ds1307(uint8_t registre)
{
uint8_t lecture ;
//Positionnement sur l'octet à lire
Wire.beginTransmission(0x68); // indique au DS1307 d'adresse hexadecimale 0x68 que le maître veut lui parler
Wire.write(registre); // Le maître indique à l'esclave qu'il veut intervenir sur le registre indiqué
Wire.endTransmission(0x68); // le maître libère l'esclave
//lecture
Wire.requestFrom(0x68, 1) ; // Le maître réclame à l'esclave 1 octet à partir du registre précédement activé
lecture = Wire.read(); // Le maître lit l'octet.
return lecture; // la fonction est de type uint8_t elle renvoie un octet.
}
Si tu as des difficultés avec les représentations décimale, hexadécimale ou binaire d'un même nombre : une seule adresse le site du zéro !
Bon courage