Exercices I2C ************* 'Programme N°1 : '--------------- 'Réaliser un Chenillard 16 voies à l'aide des deux PCF8574A du K8000. 'Le K8000 est commuté en position 0 (OFF-OFF) ' Circuit Type Adresse du circuit '________________________________________________Fixe_A3_A2_A1_A0__Déc._ ' IC17 : PCF8574A n°0 IO-chip no: 0 0111 0 0 0 X = 112+X ' IC18 : PCF8574A n°1 IO-chip no: 1 0111 0 0 1 X = 114+X 'Pour nous faciliter le travail, il est possible d'écrire une petite 'liste de description des tâches à éffectuer. 'Ce n'est pas vraiment de la struturée, mais plutôt un travail 'préparatoire qui nous permetra de définir les tâches. 'Début de la boucle "infinie" ' Mise à zéro du compteur d'affichage ' Début de la boucle d'affichage ' allumage de la led définie au compteur ' pause ' extinction de la led définie au compteur ' incrémentation du compteur ' Fin de la boucle d'affichage 'Fin de la boucle infinie 'Une fois cette liste écrite, nous pouvons nous lancer dans l'écriture 'du programme en structurée 'Liste des routines I2C utilisées dans le programme '-------------------------------------------------- 'I2CSTART : Mise du bus I2C dans la condition "START" 'I2CSTOP : Mise du bus I2C dans la condition "STOP" 'I2CTX : Emission d'un octet sur le bus I2C 'ACKRX : Reception d'un "ACK" sur le bus I2C 'Liste des routines utilisées dans le programme '---------------------------------------------- 'WRITEBYTE : Ecriture d'un octet sur le bus ******************************************************************************* Structure du programme BEGIN 'Début du programme ' Définition des variables utilisées ' ********************************** DECLARE I2cadr AS BYTE 'Adresse du circuit I2C DECLARE I2cio AS BYTE 'Valeur de travail a envoyer sur le bus I2C DECLARE I2cdata AS BYTE 'Octet de la valeur lue ou écrite sur le bus DECLARE I2cack AS BIT 'Bit "ACK" du bus I2C DECLARE I2csda AS NIBBLE 'Pin du circuit qui sert de "I2C DATA" DECLARE I2cscl AS NIBBLE 'Pin du circuit qui sert de "I2C CLOCK" DECLARE I2cad1WR AS BYTE 'Adresse d'écriture du premier PCF8574A DECLARE I2cad2WR AS BYTE 'Adresse d'écriture du deuxième PCF8574A DECLARE Temps AS WORD 'Temps de pause en milisecondes DECLARE I AS BYTE 'Variable de travail DECLARE J AS BYTE 'Variable de travail DECLARE K AS BYTE 'Variable de travail DECLARE L AS BYTE 'Variable de travail ' Définition des constantes ' ************************* LET I2csda = 12 'Liaison "SDA" du STAMP LET I2cscl = 13 'Liaison "CLK" du STAMP LET I2cad1WR = 112 'Adresse du 1er PCF pour K8000 avec adresse $00 LET I2cad2WR = 114 'Adresse du 2eme PCF pour K8000 avec adresse $00 LET Temps = 900 '"Vitesse" du chenillard ' Programme Principal ' ******************* DO WHILE k=k 'Début de la boucle "infinie" L = 0 'Reset de la boucle de chenillard DO WHILE L < 16 'Boucle de chenillard sur 16 pas IF L < 8 'Test pour envoi vers le 1er PCF8574 LET i2cio = 2 ^ L 'Valeur pour allumer une led LET i2cadr = i2cad1WR 'Adresse du premier PCF8574 GOSUB WRITEBYTE 'Envoi vers le bus I2C PAUSE temps 'Pause avant d'éteindre la led LET i2cio = 0 'Valeur pour éteindre la led LET i2cadr = i2cad1WR 'Adresse du premier PCF8574 GOSUB WRITEBYTE 'Envoi vers le bus I2C ELSE 'Sinon envoi vers le 2eme PCF8574 LET i2cio = 2 ^ (L - 8)'Valeur pour allumer une led LET i2cadr = i2cad2WR 'Adresse du premier PCF8574 GOSUB WRITEBYTE 'Envoi vers le bus I2C PAUSE temps 'Pause avant d'éteindre la led LET i2cio = 0 'Valeur pour éteindre la led LET i2cadr = i2cad2WR 'Adresse du premier PCF8574 GOSUB WRITEBYTE 'Envoi vers le bus I2C ENDIF LET L = L + 1 'Comptage pour le chenillard ENDDO 'Fin de la boucle de chenillard ENDDO 'Fin ?? de la boucle "infinie" ' Routine d'écriture de i2cio à l'adresse i2cadr sur le bus I2C SUB WRITEBYTE GOSUB i2cstart 'Mise du bus en condition "START" LET i2cdata = i2cadr 'Valeur de l'adresse à écrire GOSUB i2ctx 'Ecriture de l'adresse I2C GOSUB ackrx 'Attente de l'ACK LET i2cdata = i2cio 'valeur de la donnée à écrire GOSUB i2ctx 'Ecriture de la donnée I2C GOSUB ackrx 'Attente de l'ACK GOSUB i2cstop 'Mise du bus en condition "STOP" ENDSUB 'Définitions des subroutines I2C ******************************** ' I2CSTART : Mise du bus I2C dans la condition "START" SUB I2CSTART Mise à 1 de la pin définie par i2csda 'I2C data line Mise à 1 de la pin définie par i2cscl 'I2C clock line Mise à 0 de la pin définie par i2csda 'I2C data line Mise à 0 de la pin définie par i2cscl 'I2C clock line ENDSUB ' I2CSTOP : Mise du bus I2C dans la condition "STOP" SUB I2CSTOP Mise à 0 de la pin définie par i2csda 'I2C data line Mise à 1 de la pin définie par i2cscl 'I2C clock line Mise à 1 de la pin définie par i2csda 'I2C data line ENDSUB ' I2CTX : Emission d'un octet sur le bus I2C SUB I2CTX LET i = 0 DO WHILE i < 8 LET j = (i)ème bit de i2cdata Mise à la valeur j de la pin définie par i2csda Mise à 1 de la pin définie par i2cscl PAUSE 1ms Mise à 0 de la pin définie par i2cscl Mise à 0 de la pin définie par i2csda ENDDO ENDSUB ' ACKRX : Réception d'un "ACK" sur le bus I2C SUB ACKRX Mise à 1 de la pin définie par i2cscl Mise "haute-impédance" de la pin définie par i2csda PAUSE 1ms Attente d'un 0 sur la pin définie par i2csda PAUSE 1ms Mise à 0 de la pin définie par i2cscl ENDSUB END 'Fin du programme ***************************************************************************** 'Listing du programme pour le STAMP2 'Utilisation de la carte Micro-Info et le K8000 'La ligne SDA est connectée en P12 'La ligne SCL est connectée en P13 'Notez que la carte MI est allimentée par le K8000 'Description du K8000 'Circuit Type Adresse du circuit '_________________________________________Fixe_A3_A2_A1_A0__Décimal_ 'IC17 : PCF8574A n°0 IO-chip no: 0 0111 0 0 0 X = 112+X 'IC18 : PCF8574A n°1 IO-chip no: 1 0111 0 0 1 X = 114+X 'Dans l'utilsation des PCF8574A, nous constatons rapidement que 'tout est inversé (255 = Toutes leds éteintes et 0 = Toutes leds 'allumées). Ceci est du au fait que dans le K8000, les leds sont 'branchées à l'inverse de la carte MI. Ceci ne posera pas de 'problèmes lors de l'écriture du programme, il faudra simplement 'utiliser la relation "255-octet" à la place de "octet" dans 'l'écriture de notre programme. 'Pour faciliter l'écriture de notre programme, nous utiliserons 'les routines "ECR17" et "ECR18", qui en fait seront la routine '"WRITEBYTE" de la structurée, mais avec les paramètres d'adresse 'respectivement de IC17 et IC18 du K8000. 'Lors de l'écriture du programme, nous considérons que chaque 'écriture dans IC17 et IC18 éfface la précédente, donc dans 'l'écriture réelle dans le stamp, nous ne devrons pas éffacer 'à chaque fois la led, mais seulement à la fin de chaque cycle 'd'écriture dans IC17 et IC18 'Liste des routines I2C '---------------------- 'I2CSTART : Mise du bus I2C dans la condition "START" 'I2CSTOP : Mise du bus I2C dans la condition "STOP" 'I2CTX : Emission d'un octet sur le bus I2C 'I2CRX : Reception d'un octet sur le bus I2C 'ACKTX : Emission d'un "ACK" sur le bus I2C 'ACKRX : Reception d'un "ACK" sur le bus I2C 'Définition des entrées-sorties OUTPUT 0 OUTPUT 1 OUTPUT 2 OUTPUT 3 OUTPUT 4 OUTPUT 5 OUTPUT 6 OUTPUT 7 OUTPUT 8 OUTPUT 9 INPUT 10 OUTPUT 11 INPUT 12 INPUT 13 INPUT 14 INPUT 15 'Initialisation du système INS = 0 OUTS = 0 'Définition des variables de travail I VAR BYTE J VAR BYTE K VAR BYTE L VAR BYTE 'Definition des variables I2C i2caddr var byte 'Mot de l'adresse du composant I2C i2cdata var byte 'Octet de valeur lue ou ecrite sur le bus I2C i2cack var bit 'Bit "ACK" du bus I2C i2csda con 12 'Pin I2C data du Stamp2 i2cscl con 13 'Pin I2C clock du Stamp2 i2cad1WR con %01110000 'Adresse d'ecriture du 1er PCF8574A i2cad2WR con %01110010 'Adresse d'ecriture du 2eme PCF8574A i2cio var byte 'Valeur lue ou ecrite dans le composant i2c 'Definition des autres variables Temps con 100 'Temps de pause pour le chenillard 'Debut du programme principal '**************************** 'initialisation de IC17 et IC18 i2cio = 255 'Valeur pour "éteindre" les leds de IC17 et IC18 GOSUB ecr17 'Extinction des leds de IC17 GOSUB ecr18 'Extinction des leds de IC18 deb: FOR I=0 TO 15 'Comptage en boucle de 0 à 15 IF I > 7 THEN s1 'Test inversé pour l'écriture dans IC17 i2cio=255-(1< 8 THEN s2 'Test de la première valeur de IC18 pour i2cio = 255 'éteindre IC17 GOSUB ecr17 'Extinction de IC17 s2: i2cio=255-(1<<(I-8)) 'Calcul de l'octet à écrire dans IC18 GOSUB ecr18 'Ecriture de l'octet dans IC18 s3: PAUSE temps 'Pause pour la "vitesse" du chenillard NEXT 'Bouclage pour les 16 pas i2cio = 255 'Valeur à écrire GOSUB ecr18 'pour éteindre les leds de IC18 GOTO deb: 'Bouclage "infini" STOP 'ECR17 : Ecriture de la valeur contenue dans i2cio dans IC17 '*********************************************************** ecr17: GOSUB i2cstart 'Mise du bus en condition "START" i2cdata=i2cad1WR 'Valeur a envoyer = ecriture 1er PCF8574A GOSUB i2ctx 'Envoi de i2cdata sur le bus i2c GOSUB ackrx 'Attente de l'ACK i2cdata=i2cio 'Valeur a envoyer = i2cio GOSUB i2ctx 'Envoi de i2cdata sur le bus i2c GOSUB ackrx 'Attente de l'ACK GOSUB i2cstop 'Mise du bus en condition "STOP" RETURN 'ECR18 : Ecriture de la valeur contenue dans i2cio dans IC18 '*********************************************************** ecr18: GOSUB i2cstart 'Mise du bus en condition "START" i2cdata=i2cad2WR 'Valeur a envoyer = ecriture 2eme PCF8574A GOSUB i2ctx 'Envoi de i2cdata sur le bus i2c GOSUB ackrx 'Attente de l'ACK i2cdata=i2cio 'Valeur a envoyer = i2cio GOSUB i2ctx 'Envoi de i2cdata sur le bus i2c GOSUB ackrx 'Attente de l'ACK GOSUB i2cstop 'Mise du bus en condition "STOP" RETURN '************************************************************************** 'Liste des routines I2C '********************** 'I2CSTART : Mise du bus I2C dans la condition "START" '**************************************************** i2cstart: HIGH i2csda 'Mise a 1 de I2C data HIGH i2cscl 'Mise a 1 de I2C clock LOW i2csda 'Mise a 0 de I2C data RETURN 'I2CSTOP : Mise du bus I2C dans la condition "STOP" '************************************************** i2cstop: LOW i2csda 'Mise a 0 de I2C data line HIGH i2cscl 'Mise a 1 de I2C clock line HIGH i2csda 'Mise a 1 de I2C data line RETURN 'I2CTX : Emission d'un octet sur le bus I2C '****************************************** i2ctx: SHIFTOUT i2csda,i2cscl,1,[i2cdata] RETURN 'I2CRX : Reception d'un octet sur le bus I2C '******************************************* i2crx: SHIFTIN i2csda,i2cscl,0,[i2cdata] RETURN 'ACKTX : Emission d'un "ACK" sur le bus I2C '****************************************** acktx: SHIFTOUT i2csda,i2cscl,1,[%0\1] RETURN 'ACKRX : Reception d'un "ACK" sur le bus I2C '******************************************* ackrx: SHIFTIN i2csda,i2cscl,0,[i2cack\1] RETURN 'FIN DES ROUTINES I2C '**************************************************************************