tutoriel I2C
Utilisation de l'I2C Bus
La valeur des résistances est pas critique. Je l'ai vu quelque chose de 1k8 (1800 ohms) à 47K (47000 ohms) utilisés. 1k8, 4k7 et 10k sont des valeurs communes, mais rien dans cette gamme devrait fonctionner OK. Je recommande 1k8 que cela vous donne les meilleures performances. Si les résistances sont manquantes, les lignes SCL et SDA sera toujours faible - près de 0 volts - et le bus I2C ne fonctionnera pas.
Maîtres et esclaves
Les dispositifs sur le bus I2C sont des maîtres ou esclaves. Le maître est toujours le dispositif qui commande la ligne d'horloge SCL. Les esclaves sont les dispositifs qui répondent au maître. Un esclave ne peut initier un transfert sur le bus I2C, seul un maître peut le faire. Il peut y avoir, et sont généralement, plusieurs esclaves sur le bus I2C, mais il est normalement qu'un seul maître. Il est possible d'avoir plusieurs maîtres, mais il est rare et ne sont pas couverts ici. Sur votre robot, le maître sera votre contrôleur et les esclaves seront nos modules tels que le SRF08 ou CMPS03. Les esclaves ne seront jamais initier un transfert. Maître et esclave peuvent transférer des données sur le bus I2C, mais que le transfert est toujours contrôlé par le maître.
Les données sont transférées dans des séquences de 8 bits. Les bits sont placés sur la ligne SDA en commençant par le MSB (Most Significant Bit). La ligne SCL est alors pulsée élevée, faible. Rappelez-vous que la puce ne peut pas vraiment conduire la ligne haute, il suffit de « lâche » et de la résistance tire réellement élevée. Pour toutes les 8 bits transférés, le dispositif de réception de données renvoie un accusé de réception bit, donc il y a effectivement 9 impulsions d'horloge SCL pour transférer chaque octet de données de 8 bits. Si le dispositif de réception renvoie un peu faible ACK, il a reçu les données et est prêt à accepter un autre octet. Si elle renvoie un haut alors il est indique qu'il ne peut pas accepter les autres données et le capitaine devrait mettre fin au transfert en envoyant une séquence d'arrêt.
À quelle vitesse?
La vitesse d'horloge standard (SCL) pour I2C jusqu'à 100KHz. Philips ne définissent des vitesses plus rapides: le mode rapide, qui est jusqu'à 400KHz et le mode haute vitesse qui est à 3.4MHz. Tous nos modules sont conçus pour fonctionner jusqu'à 100KHz. Nous avons testé nos modules jusqu'à 1MHz, mais cela a besoin d'un petit retard de quelques uS entre chaque octet transféré. Dans des robots pratiques, nous avons jamais eu besoin d'utiliser des vitesses élevées SCL. Gardez SCL à ou en dessous 100KHz puis oublier.
Dispositif d'adressage I2C
Toutes les adresses I2C sont soit 7 bits ou 10 bits. L'utilisation de 10 adresses de bits est rare et ne sont pas couverts ici. Tous nos modules et les puces courantes que vous utiliserez auront 7 adresses de bits. Cela signifie que vous pouvez avoir jusqu'à 128 périphériques sur le bus I2C, car un certain nombre de 7 bits peut être de 0 à 127. Lors de l'envoi de l'adresse 7 bits, nous envoyons toujours toujours 8 bits. Le bit supplémentaire est utilisé pour informer l'esclave si le maître est en train d'écrire à la lecture ou de celui-ci. Si le bit est égal à zéro le maître est en train d'écrire à l'esclave. Si le bit est 1 le maître est en train de lire l'esclave. Le 7 adresse de bit est placé dans les 7 bits de poids fort de l'octet et la lecture / écriture (R / W) se trouve dans le bit LSB (Least Significant Bit).
Le placement de l'adresse à 7 bits dans les 7 bits de poids fort de l'octet est une source de confusion pour le nouveau venu. Cela signifie que d'écrire pour répondre 21, vous devez effectivement envoyer 42 qui est 21 déplacé sur 1 bit. Il est probablement plus facile de penser des adresses de bus I2C que 8 adresses bits, avec des adresses même comme écrire uniquement, et les adresses impaires comme l'adresse de lecture pour le même appareil. Pour prendre notre CMPS03 par exemple, c'est à l'adresse 0xC0 ($ C0). Vous utilise 0xC0 pour écrire au CMPS03 et 0xC1 à lire. Ainsi, la lecture / bit d'écriture juste fait un impair / pair adresse.
Le protocole du logiciel I2C
La première chose qui va arriver est que le maître envoie une séquence de démarrage. Cela alertera tous les dispositifs esclaves sur le bus qu'une transaction commence et ils devraient écouter Incase il est pour eux. Ensuite, le maître envoie l'adresse de l'appareil. L'esclave qui correspond à cette adresse se poursuivra avec la transaction, les autres ignorera le reste de cette opération et attendre la prochaine. Après avoir adressé le dispositif esclave le maître doit maintenant envoyer l'emplacement interne ou numéro de registre à l'intérieur de l'esclave qu'il souhaite écrire ou lire. Ce nombre est évidemment dépendant de ce que l'esclave est en fait et combien de registres internes dont il dispose. Certains appareils très simples n'ont pas, mais la plupart le font, y compris tous nos modules. Notre CMPS03 dispose de 16 emplacements numérotés 0-15. Le SRF08 a 36. Après avoir envoyé l'adresse I2C et l'adresse du registre interne du maître peut maintenant envoyer l'octet de données (ou octets, il ne doit pas être un seul). Le maître peut continuer à envoyer des octets de données à l'esclave et ceux-ci seront placés normalement dans les registres suivants, car l'esclave incrémente automatiquement l'adresse du registre interne après chaque octet. Lorsque le maître a fini d'écrire toutes les données à l'esclave, il envoie un ordre d'arrêt qui achève la transaction. Donc, pour écrire à un dispositif esclave:
1. Envoyer une séquence de démarrage
2. Envoyer l'adresse I2C de l'esclave avec le bit R / W faible (adresse paire)
3. Envoyez le numéro de registre interne que vous voulez écrire
4. Envoyer l'octet de données
5. [En option, envoyer des octets de données supplémentaires]
6. Envoyer la séquence d'arrêt.
À titre d'exemple, vous avez un SRF08 à l'adresse par défaut de 0xE0. Pour commencer le SRF08 allant vous écririez 0x51 au registre de commande à 0x00 comme ceci:
1. Envoyer une séquence de démarrage
2. Envoyer 0xE0 (adresse I2C du SRF08 avec le bit R / W faible (même adresse)
3. Envoyer 0x00 (adresse interne du registre de commande)
4. Envoyer 0x51 (la commande pour démarrer la SRF08 ranging)
5. Envoyez la séquence d'arrêt.
La lecture de l'esclave
Ceci est un peu plus compliqué - mais pas trop plus. Avant la lecture des données de l'appareil esclave, vous devez lui indiquer ses adresses internes que vous voulez lire. Ainsi, une lecture de l'esclave commence réellement hors en lui écrivant. Ceci est le même que lorsque vous voulez y écrire: Vous envoyez la séquence de démarrage, l'adresse I2C de l'esclave avec le bit R / W faible (même adresse) et le numéro de registre interne que vous voulez écrire. Maintenant, vous envoyez une autre séquence de démarrage (parfois appelé un redémarrage) et l'adresse I2C à nouveau - cette fois avec le bit de lecture. Vous avez lu alors que le nombre d'octets de données que vous le souhaitez et mettre fin à la transaction avec une séquence d'arrêt. Donc, pour lire le palier de compas comme un octet à partir du module de CMPS03:
1. Envoyer une séquence de démarrage
2. Envoyer 0xC0 (adresse I2C du CMPS03 avec le bit R / W faible (même adresse)
3. Envoyer 0x01 (adresse interne du registre de roulement)
4. Envoyez une séquence de démarrage à nouveau (début répété)
5. Envoyer 0xC1 (adresse I2C du CMPS03 avec le bit R / W haute (adresse impaire)
6. Lire octet de données à partir CMPS03
7. Envoyer la séquence d'arrêt.
La séquence de bits ressemblera à ceci:
Attendez un moment
C'est presque pour les communications I2C simples, mais il y a une plus complication. Quand le maître est en train de lire l'esclave, son esclave qui place les données sur la ligne SDA, mais son maître qui contrôle l'horloge. Que faire si l'esclave est pas prêt à envoyer les données! Avec des appareils tels que ce n'est pas EEPROMs un problème, mais lorsque le dispositif esclave est en fait un microprocesseur avec d'autres choses à faire, il peut être un problème. Le microprocesseur du dispositif esclave devra aller à une routine d'interruption, sauf ses registres de travail, savoir quelle adresse le maître veut lire, obtenir les données et le placer dans son registre de transmission. Cela peut prendre beaucoup uS arriver, quant à lui le maître envoie béatement des impulsions d'horloge sur la ligne SCL que l'esclave ne peut pas répondre. Le protocole I2C fournit une solution à ceci: l'esclave est autorisé à maintenir la ligne basse SCL! Ceci est appelé étirement horloge. Lorsque l'esclave reçoit la commande de lecture du maître, il tient la ligne d'horloge basse. Le microprocesseur obtient alors les données demandées, il place dans le registre de transmission et libère la ligne d'horloge permettant la résistance de pull-up pour finalement tirer haut. Du point de vue des maîtres, il émettra la première impulsion d'horloge de la lecture en faisant SCL haute et vérifiez si elle est vraiment allé élevé. S'il est encore faible, son esclave que sa tenue basse et le maître doit attendre jusqu'à ce qu'il va vers le haut avant de continuer. Heureusement, les ports I2C matériels sur la plupart des microprocesseurs se chargeront automatiquement.
Parfois, cependant, le I2C maître est juste une collection de sous-routines et il y a quelques implémentations là-bas qui ne tiennent pas compte complètement étirement horloge. Ils travaillent avec des choses comme de l'EEPROM, mais pas avec des esclaves à microprocesseur qui utilisent étirement horloge. Le résultat est que des données erronées sont lues à partir de l'esclave. Il faut se méfier!
Exemple de code maître
Cet exemple montre comment implémenter un maître I2C logiciel, y compris l'étirement horloge. Il est écrit en C pour le processeur PIC, mais devrait être applicable à la plupart des processeurs avec des modifications mineures aux définitions des broches d'E / S. Il convient pour contrôler tous nos modules de robots à base I2C. Étant donné que les lignes SCL et SDA sont de type drain ouvert, nous utilisons le registre de commande à trois états pour contrôler la sortie, la tenue du registre de sortie faible. Les broches du port doivent encore être lu, donc ils sont définis comme SCL_IN et SDA_IN. Cette définition et l'initialisation est probablement tout ce que vous aurez besoin de changer pour un autre processeur.
#define SCL TRISB4 // bus I2C
#define SDA TRISB1 //
#define SCL_IN RB4 //
#define SDA_IN RB1 //
Pour initialiser les ports définis résistants à la sortie à 0 et les registres à trois états à 1, qui désactive les sorties et leur permet d'être tiré haut par les résistances.
SDA = SCL = 1;
SCL_IN = SDA_IN = 0;
Nous utilisons une petite routine de délai entre les changements SDA et SCL pour donner une séquence claire sur le bus I2C. Ceci est rien de plus qu'un appel et de retour sous-programme.
annuler i2c_dly (void)
>
Les 4 fonctions suivantes fournissent le début primitive, arrêter, lire et écrire des séquences. Toutes les transactions I2C peuvent être construites à partir de ces derniers.
i2c_start vide (void)
SDA = 1; // i2c séquence de bits de démarrage
i2c_dly ();
SCL = 1;
i2c_dly ();
SDA = 0;
i2c_dly ();
SCL = 0;
i2c_dly ();
>
i2c_stop vide (void)
SDA = 0; // I2C séquence de bits d'arrêt
i2c_dly ();
SCL = 1;
i2c_dly ();
SDA = 1;
i2c_dly ();
>
unsigned char i2c_rx (char ack)
carbonisation x, d = 0;
SDA = 1;
for (x = 0; x<8; x++) d <<= 1;
faire SCL = 1;
>
tandis que (SCL_IN == 0); // attendre une horloge SCL étirement
i2c_dly ();
if (SDA_IN) d | = 1;
SCL = 0;
>
if (ack) SDA = 0;
d'autre SDA = 1;
SCL = 1;
i2c_dly (); // envoyer (N) bit ACK
SCL = 0;
SDA = 1;
retour d;
>
bit i2c_tx (unsigned char d)
x carbonisation;
bit statique b;
pour (x = 8; x; X-) si (d-0x80) SDA = 1;
autre SDA = 0;
SCL = 1;
ré <<= 1;
SCL = 0;
>
SDA = 1;
SCL = 1;
i2c_dly ();
b = SDA_IN; // bit possible ACK
SCL = 0;
retourner b;
>
Les 4 fonctions primitives ci-dessus peuvent facilement être mis en place pour former les transactions I2C complètes. Voici et exemple pour démarrer une SRF08 allant en cm:
i2c_start (); // envoyer la séquence de démarrage
i2c_tx (0xE0); // SRF08 adresse I2C avec le bit R / W clair
i2c_tx (0x00); // commande SRF08 adresse de registre
i2c_tx (0x51); // commande de démarrage allant en cm
i2c_stop (); // envoyer la séquence d'arrêt
Maintenant, après avoir attendu 65ms pour le allant de terminer (je l'ai quitté que pour vous) l'exemple suivant montre comment lire la valeur du capteur de lumière du registre 1 et le résultat de la plage de registres 2 - 3.
i2c_start (); // envoyer la séquence de démarrage
i2c_tx (0xE0); // SRF08 adresse I2C avec le bit R / W clair
i2c_tx (0x01); // SRF08 adresse de registre de capteur de lumière
i2c_start (); // envoyer une séquence de redémarrage
i2c_tx (0xE1); // SRF08 adresse I2C avec bit R / W
LightSensor = i2c_rx (1); // obtenir capteur de lumière et d'envoyer d'accusé de réception. Adresse de registre interne incrémente automatiquement.
PlageHaute = i2c_rx (1); // obtenir l'octet haut de gamme et d'envoyer d'accusé de réception.
PlageBasse = i2c_rx (0); // obtenir octet bas de gamme - noter que nous ne reconnaissons pas le dernier octet.
i2c_stop (); // envoyer la séquence d'arrêt