Répondre à la discussion
Affichage des résultats 1 à 17 sur 17

I2c



  1. #1
    Olfox

    I2c


    ------

    Bonjour!

    Que faire lorsqu'une EEPROM I2C n'envoie pas l'ack après avoir envoyer son adresse. Connaissait vous les sources de conflits qui peuvent faire survenir ce problème?

    PS juste avant j'avais su écrire et lire dedans .

    Merci à tous

    -----

  2. Publicité
  3. #2
    DavidDB

    Re : I2c

    Salut,

    Essaye de provoquer un RESET du bus, et ensuite tu communiques à nouveau avec l'EEPROM...

    Ce reset, n'est pas la solution, mais cela te permettra de savoir si ton code est buggé.

    David.

  4. #3
    Olfox

    Re : I2c

    OK merci david mais je ne comprends plus trop ce qu'il se passe. Lorsque que j'execute le programme il bloque apres avoir écrit et lu une premiere fois alors que lorsque j'execute le programme en mode mode pas à pas tout fonctionne correctement . J'ai pourtant bien mis des temporisations entre chaque evenement ( 100ms).

  5. #4
    Jack
    Modérateur

    Re : I2c

    Quel est le type d'eeprom et quels sont les octets que tu envoies pour écrire un byte par exemple?

    On peut voir ton schéma également pour des éventuels problèmes hard?

    A+

  6. A voir en vidéo sur Futura
  7. #5
    Olfox

    Re : I2c

    tout d'abord merci Jack pour ta réponse, je travaille sur la carte PICDEM2 de chez microship donc niveau hard je pense que tout est ok il y a bien les résistance de pull up et tout ce qu'il faut. Je pense plutôt que cela doit provenir d'un soucis de pointeur interne à l'eeprom qui s'incrémente automatiquement. De plus je ne comprends pas que lorsque que je fait en pas à pas tout fonctionne alors qu'en fonctionnement normal apres un cycle d'écriture et de lecture l'eeprom ne semble plus accessible. veux tu voir mes fonctions d'écriture est de lecture pour plus de clarté elles sont lisibles et bien commentées... Merci encore pour on aide elle m'est précieuse après quelque mois de déboire et de désillusion.

  8. #6
    Jack
    Modérateur

    Re : I2c

    N'étant pas familier de l'assembleur PIC, je ne t'aiderai efficacement que si tu écris en C.

    D'après ce que tu me dis, je pense que ton problème se situe au niveau du test "registre d'émission vide". Il est probable que tu balances tous tes octets plus vite que le registre à décalage ne les envoie sur l'I2C.

    A+

  9. Publicité
  10. #7
    Olfox

    Re : I2c

    Très bien ca tombe plutot bien je code en C avec le compilateur HITEC PIC TOOLSUITE et l'eeprom est une 24LC256 de chez microship. Voici ma fonction de lecture, si quelque chose te semble suspect, fait mois signe. Merci encore pour ton aide.

    Fonction d'écriture et fonction de lecture :

    Code:
    void emis2_I2C(unsigned char composant,int adresse,unsigned char donnee)
    {
    unsigned char LSB=0;
    unsigned char MSB=0;
    LSB= adresse & 0xFF;	// Pour init du poids faible de pointeur
    MSB= ( adresse & 0xFF00)>>8;	// Pour init du poids fort de pointeur
    
    SEN=1;					// Start condition
    while(SEN==1){;}		// attente fin d'opération Start
    
    SSPBUF= ( composant | 0 );// charge adresse de l'EEPROM pour qu'elle se reconnaisse avec RW=0 écriture
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse de l'EEPROM
    
    while(ACKSTAT==1)		// attente du ACK de l'EEPROM	
    {
    SEN=1;					// Start condition
    while(SEN==1){;}		// attente fin d'opération Start
    SSPBUF= ( composant | 0 );// charge adresse de l'EEPROM pour qu'elle se reconnaisse avec RW=0 écriture
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse de l'EEPROM
    }
    
    SSPBUF=MSB;				// initialisation poids fort du pointeur de l'EEPROM
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse MSB
    
    while(ACKSTAT==1)
    {
    SSPBUF=MSB;
    while(STAT_BF==1){;}
    }	// attente du ACK de l'EEPROM
    
    SSPBUF=LSB;				// initialisation des poids faibles du pointeur de l'EEPROM
    while(STAT_RW==1){;}	// attente fin d'émission de l'adresse LSB
    
    while(ACKSTAT==1)
    {
    SSPBUF=LSB;
    while(STAT_RW==1){;}
    }	// attente du ACK de l'EEPROM
    
    SSPBUF=donnee;			// on charge la donnée à enregistrer dans l'EEPROM
    while(STAT_RW==1){;}	// on attends la fin d'émission de la donnée
    
    PEN=1;					// envoi le stop condition
    while(PEN==1){;}		// on attends la fin du stop condition, evoi terminé
    }
    et la fonction de lecture :

    Code:
    unsigned char lect2_I2C(unsigned char composant,int adresse)
    {
    extern unsigned char a;
    unsigned char LSB=0;
    unsigned char MSB=0;
    LSB= adresse & 0xFF;	// Pour init du poids faible de pointeur
    MSB= ( adresse & 0xFF00)>>8;	// Pour init du poids fort de pointeur
    
    SEN=1;					// Start condition
    while(SEN==1){;}		// attente fin d'opération Start
    
    SSPBUF= (composant |0 );	// charge adresse de l'EEPROM pour qu'elle se reconnaisse avec RW=0 écriture
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse de l'EEPROM
    
    while(ACKSTAT==1)
    {
    SSPBUF= (composant |0 );	// charge adresse de l'EEPROM pour qu'elle se reconnaisse avec RW=0 écriture
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse de l'EEPROM
    }	// attente du ACK de l'EEPROM
    
    SSPBUF=MSB;				// initialisation poids fort du pointeur de l'EEPROM
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse MSB
    
    while(ACKSTAT==1)
    {
    SSPBUF=MSB;
    while(STAT_BF==1){;}
    }	// attente du ACK de l'EEPROM
    
    SSPBUF=LSB;				// initialisation des poids faibles du pointeur de l'EEPROM
    while(STAT_RW==1){;}	// attente fin d'émission de l'adresse LSB
    
    while(ACKSTAT==1)
    {
    SSPBUF=LSB;
    while(STAT_RW==1){;}
    }	// attente du ACK de l'EEPROM
    
    RSEN=1;					// envoi RE-start condition
    while(STAT_BF==1){;}	// attente fin d'émission du repete startcondition
    
    SSPBUF= ( composant | 1 );	// charge adresse de l'EEPROM pour qu'elle se reconnaisse avec RW=1 lecture
    while(STAT_RW==1){;}
    
    while(ACKSTAT==1){;}	// attente du ACK de l'EEPROM
    
    RCEN=1;					// On valide la reception, clear automatiquement
    
    while(STAT_BF==1){;}	// attente la fin de la reception, si BF=1, on a la donnnée dans SSPBUF
    
    ACKDT=1;				// on envoi un NOACK pour dire, qu'on a bien recu l'octet
    ACKEN=1;				// on valide l'emission du ACK en mode reception
    PEN=1;					// envoi le stop condition
    while(PEN==1){;}		// on attends la fin du stop condition, evoi terminé
    
    return(SSPBUF);			// on renvoi la donnée lue
    }
    Merci encore

  11. #8
    Jack
    Modérateur

    Re : I2c

    Quelle est la référence du pic?

  12. #9
    Olfox

    Re : I2c

    C'est un 16F877. Je travaille avec un quartz 4MHZ, voici la fonction d'initialisation j'ai un petit doute concernant la valeur du SSPAD car en effectuant le calcul je devrais inscrire 1,5 pour sa valeur mais ne pouvant pas mettre de flottant j'ai mis la valeur 1 . En vérifiant à l'osscilloscope je ne suis vraiment pas à 400KHz... Mais bon, si le programme s'execute bien une fois pourquoi pas deux sachant qu'après la fonction de lecture les registres sont dans le même état qu'au départ, et aucun drapeau mis à part le NOACK envoyé par l'eeprom juste après avoir envoyé son adresse pour qu'elle se reconnaisse.

    Code:
    void init_I2C(void)
    {
    TRISC3=1;
    TRISC4=1;
    
    STAT_SMP=0; 			// SCL cadencé à 400kHz
    STAT_CKE=0; 			// mode I2C et non SMBUS
    
    SSPADD=1;			// SSPAD=2 pour le cadencement de SCL avec Fclk=4MhZ
    
    SSPEN=1; 			// module en service valid SCA et SCL
    SSPCON= (SSPCON | 0b00001000);	// I2C Mode Master
    }

  13. #10
    Jack
    Modérateur

    Re : I2c

    Je viens de regarder la doc.

    Le fait que ça fonctionne en pas à pas prouve que la config est bonne et qu'il s'agit d'une problème de timing.

    Je pensais à une mauvaise gestion du bit BF, mais non, ton code semble correct. Tu a vérifié à l'oscillo si tes trames sont correctes?

    A+

  14. #11
    Olfox

    Re : I2c

    Oui. J'ai fait pour tester la fonction d'écriture un programme qui apele juste la fonction avec une tempo de 100ms le tout dans un while 1 . A l'osccilloscope tout est correct le programme ne plante pas et les trames sont bonnes, l'eeprom est toujours pretes à être réécrites. Par contre j'ai essayer la même chose MAIS avec la fonction de lecture et la le programme ne s'execute qu'une seule fois. Pourtant la ligne SDA se remet bien un position de repos ( 1 ), et le dernier bit détecté est bien le bit de Stop.

  15. #12
    Jack
    Modérateur

    Re : I2c

    Où le programme bloque-t-il à la seconde écriture?

  16. Publicité
  17. #13
    Olfox

    Re : I2c

    Juste après avoir envoyé l'adresse de l'eeprom , au lieu d'envoyer son aqcuitement comme elle le faisait pendant l'écriture et la lecture précédente elle envoi un NOACK comme pour dire qu'elle n'est pas prête à recevoir des donnée.

  18. #14
    DavidDB

    Re : I2c

    Salut,

    La vitesse de ton BUS est bien trop loin des 400Khz, et il est fort possible que l'EEPROM plante.

    Essaye déjà avec SSPAD à deux, tu n'auras plus qu'une erreur de 67khz à la place de l'erreur actuelle de 100Khz.
    P.S. je ne connais pas l'erreur maximale en fréquence que supporte l'EEPROM, mais 25% d'erreur me paraît bien trop pour ce genre de composant.

    Si cela ne fonctionne pas mieux, il faut changer de quartz pour ton PIC afin de se caler au plus prêt des 400Khz.

    David.

  19. #15
    Jack
    Modérateur

    Re : I2c

    Pourquoi voulez-vous viser le 400kHz qui est la fréquence de bus maxi de la mémoire?

  20. #16
    DavidDB

    Re : I2c

    Salut,

    Avec sa config, il est à 500Khz et donc hors plage de fonctionnement de l'EEPROM, d'où un fonctionnement aléatoire du composant...

    En repassant à 333Khz (SSPAD=2) il rentre à nouveau dans la plage d'utilisation de l'EEPROM.

    Il faudra se caler sur 400Khz, si il s'agit de vrai composant I2C, par contre vu qu'ici c'est compatible I2C, la fréquence du BUS est libre à la condition de ne pas dépasser 400Khz, mais la config empêchera l'utilisation de composant I2C si on ne se cale pas sur le 400Khz.
    Donc pour repsecter la norme I2C, il faut se caler sur 400Khz (ou 100Khz)...

    David.
    Dernière modification par DavidDB ; 03/08/2007 à 17h51.

  21. #17
    Olfox

    Re : I2c

    Très bien merci david pour ces renseignements suplémentaires. Je vasi voir tout ca demain mais il me semble que lorsque je faisait mes mesures à l'oscilloscope avec SSPAD à 1, j'avais une fréquence d'à peine 170KHz. De plus, tu as surement raison, si je ne suis pas calibrer dans la plage des 400KHz la valeur du bit STAT SMP vas devoir changer... Je test tout ca au plus vite et vous remercie encore pour vos suggerstions.

    Florian

Discussions similaires

  1. comparaison CAN I2C
    Par popoye dans le forum Électronique
    Réponses: 4
    Dernier message: 02/05/2007, 23h41
  2. I2c => Sck à 0
    Par Toufinet dans le forum Électronique
    Réponses: 13
    Dernier message: 09/02/2007, 21h50
  3. i2c
    Par khalid76 dans le forum Électronique
    Réponses: 15
    Dernier message: 23/01/2007, 14h32
  4. Interruption I2C
    Par Pitch21 dans le forum Électronique
    Réponses: 4
    Dernier message: 19/01/2007, 11h20
  5. I2c
    Par annece dans le forum Électronique
    Réponses: 5
    Dernier message: 17/06/2005, 15h03
Découvrez nos comparatifs produits sur l'informatique et les technologies.