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

Eeprom I²c



  1. #1
    Olfox

    Eeprom I²c


    ------

    Bonjour à tous,
    Je travaille actuellement sur la carte picdem2 de chez microship et je rencontre quelque difficulté avec l'EEPROM I²C 24LC256. Je programme en C, et j'ai réalisé deux fonction: une d'ecriture l'autre de lectrure. Mon programme principale enregistre une valeur dans l'eeprom, la lit et l'affiche sur ecran LCD. Le programme s'execute normalement dans un premier temps , le lcd affiche bien la valeur stocké à l'adresse 0 de l'eeprom. Le souci arrive lorsqu'il s'agit de réenregistrer au même endroit mémoire ( car ma fonction d'ecriture n'ecrit qu'à l'adresse 0). En effet, lors de la deuxieme emission, l'EEPROM n'envoi pas le ACK et mon pic est donc sans cesse en attente. Je sais que le pointeur interne de l'eeprom est automatiquement incrémenté mais alors comment faire pour ecrire au debut a l'@ 0 puis ensuite à la suite comme il est normal de faire. je suis un peu perdu, merci beaucoup pour vos informations. voici mon code :
    Code:
    void emis_I2C(int composant,int donnee)
    {
    
    SEN=1;					// Start condition
    while(SEN==1){;}		// attente fin d'opération Start
    
    SSPBUF= ( EEPROM1 | 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= ( EEPROM1 | 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=0;				// initialisation poids fort du pointeur de l'EEPROM
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse MSB
    
    while(ACKSTAT==1){;}	// attente du ACK de l'EEPROM
    
    SSPBUF=0;				// initialisation 2 des poids faibles du pointeur de l'EEPROM
    while(STAT_RW==1){;}	// attente fin d'émission de l'adresse LSB
    
    while(ACKSTAT==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é
    }
    
    
    int lect_I2C(int composant)
    {
    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
    
    SSPBUF=0;				// initialisation poids fort du pointeur de l'EEPROM
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse MSB
    
    while(ACKSTAT==1){;}	// attente du ACK de l'EEPROM
    
    SSPBUF=0;				// initialisation 2 des poids faibles du pointeur de l'EEPROM
    while(STAT_BF==1){;}	// attente fin d'émission de l'adresse LSB
    
    while(ACKSTAT==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(ACKSTAT==1){;}	// attente du ACK de l'EEPROM
    tempo10us (1);
    RCEN=1;					// On valide la reception
    tempo10us (1);
    while(STAT_BF==0){;}	// attente la fin de la reception, si BF=1, on a la donnnée dans SSPBUF
    b=SSPBUF;
    ACKEN=1;				// on valide l'emission du ACK en mode reception
    ACKDT=1;				// on envoi un NOACK pour dire, qu'on a bien recu l'octet
    
    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
    }
    
    // le programme principale:
    
    main()
    {
    init_lcd();
    init_I2C();
    TRISB0=0;	//pour les led de PICDEM
    TRISB1=0;
    TRISB2=0;
    TRISB3=0;
    PORTB=0;
    
    while(1)
    {
    	for(i=5;i<100;i++)
    	{
    	emis_I2C(EEPROM1,i);
    	tempo1ms(100);
    
    	a=lect_I2C(EEPROM1);
    	sprintf(texte,"r=%d",a);
    	puts_lcd(texte,0);
    	tempo1ms(400);
    	}	
    }
    }

    -----

  2. Publicité
  3. #2
    umfred

    Re : Eeprom I²c

    Je soupçonne un problème de reconnaissance d'adresse I2C.
    En toute logique pour mettre le bit R/W de l'adresse I2C à 0, il faudrait que tu fasses plutôt EEPROM1 & 0xFE.

    Autre remarque: dans ta fonction emis_I2C, tu utilise "EEPROM1" au lieu de "composant" (ce qui peux poser problème si tu utilise plusieurs périphériques I2C.)

    Sait-tu à quel endroit exactement il bloque ?

  4. #3
    Olfox

    Re : Eeprom I²c

    tout d'abord merci umfred pour ta reponse.
    Je viens d'effectuer un test unitaire pour voir si mon OU fonctione, et il fonctionne. Je n'est pas précisé que j'ai défini EEPROM 1 comme valeur : 0b 1010 0000 donc lorsque j'effectue l'opération : a = EEPROM1 OU 0 = EEPROM1 | 0 = 1010 0000 . De même lorsque je fait : EEPROM1 | 1 = 1010 0001 . donc l'erreur ne provient pas de l'opération. Pour ce qui est du parametre "composant" c'est un parametre qui remplace dans la fonction emis_I2C , composant par EEPROM1, car c'est de cette maniere que je l'ai apelé dans mon programma principale (main). C'est justement l'avantage de cette fonction, si un jour j'ai un programme avec plusieur esclave je n'aurais que appelé ma fonction en changeant le parametre. Pour revenir au blocage, je tiens a rapeler que le programme fonctionne bien mais une seule fois et il bloque au moment ou il envoi le START condition de la deuxieme émission ( une fois que j'ai incrementé la donné i a envoyer ) , il bloque au tests du ACK de l'eeprom c'est à dire qu'elle ne reponds pas, ou du moin qu'apparement elle ne reponds pas car si le programme c'est bien executé une fois, il n'y apparement pas de raison qu'il ne fonctionne pas. Le probleme ne viendrait il plutot pas de ma facon de programmer car dans cette fonction je ne peut quécrire qu'à l'adresse 0 et je réécrit toujours au dessus...

  5. #4
    Olfox

    Re : Eeprom I²c

    Bon j'ai fait queslque test supplémentaire: avec cette fonction emis_I2C j'ai enregistrer la valeur 5 à l'adresse 0 de mon eeprom. Avec lect_I2C , jei sais lire la valeur en 0 . de même afin de tester ma fonction lect_I2C , j'ai essayer de lire ce qu'il y avait dans plusieur adresse ex: 1111 0011 , et je trouve toujours la valeur 255, donc je pence que c'est normal , ca doit etre la valeur d'origine lorsque l'on a jamais écrit a cet endroit. DONC, pour synthetiser, je pence que la liaison I2C et le protocole fonctionne ! Cependant, et on en revient à la source du probleme, je n'arrive pas à écrire une seconde fois à la même adresse. Le seul changement entre la premiere emission et la seconde et l'incrémentation de la donnée à envoyer , c'est tout . J'espere vous avoir un peu plus éclairer a propos de mon probleme et j'attends vos lumières. Merciii

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

    Re : Eeprom I²c

    refais un essai en mettant un init_i2c() avant l'écriture (ou après la lecture). Je soupçonne des bits d'états (genre WCOL ou autres) d'empêcher de refaire une écriture.

  8. #6
    Olfox

    Re : Eeprom I²c

    OK j'essai, sinon j'ai ameliorer mes fonction en ajoutant comme parametre l'adresse ou je veut ecrire ou l'adresse que je lire, c'est plus logique. une fois c'est petit detail resolu je m'attaquerai a la fonction d'écriture et de lecture séquentielle car je pence que c'est cette méthode qui est le plus souvent utilisé ( quoique ca depends de l'utilisation ...)

  9. Publicité
  10. #7
    Olfox

    Re : Eeprom I²c

    bon ok ya du nouveau apparement maintenant ca bloque juste apres que j'ai encoyer le poids fort de l'adresse du pointeur, l'eeprom ne renvoi pas d'ack, j'ai vérifié, le drapeau WCOL reste à 0 donc il ne se produit pas de collision , je vais tenter de surveiler les autres drapeau

  11. #8
    Olfox

    Re : Eeprom I²c

    J'ai remarquer quelque chose. le bit P ( stop bit ) se met spontanement à 1 indiquant ainsi qu'un bit de stop a été détecté en dernier alors que je viens juste d'envoyé le bit se start, et l'@ de l'eeprom... avez vous des suggestions, je suis prenneur parce que ca commence a faire pas mal de temps que je suis coincé la dessus.Merci !

  12. #9
    umfred

    Re : Eeprom I²c

    Est-ce que tu as mis les résistances de pull-up sur les lignes SDA et SCL? Quelle valeur?

  13. #10
    Olfox

    Re : Eeprom I²c

    Je travaille en fait sur la carte de developpement PICDEM 2plus ( la verte ,derniere version) donc la reéalisation est ok. il y bien deux resistance de pull up de 4,7k chaqu'une. Par contre c'est tres etonnant les fonctions emis et lecture fonctionne lorsque je debug en pas a pas. Des que je lance le programme, la fonction lecture revele que l'ack n'est plus detecté ...tres etrange. j'ai simplifié mes fonction et je l'ai est remanié je vous les réinscrit de maniere a etre en phase avec mes propos:

    //***** fonction d'EMISSION
    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

    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é
    }

    //************* RECEPTION *************

    unsigned char lect2_I2C(unsigned char composant,int adresse)
    {
    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

    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){;} // attente du ACK de l'EEPROM

    SSPBUF=LSB; // initialisation 2 des poids faibles du pointeur de l'EEPROM
    while(STAT_BF==1){;} // attente fin d'émission de l'adresse LSB

    while(ACKSTAT==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(ACKSTAT==1){;} // attente du ACK de l'EEPROM

    RCEN=1; // On valide la reception

    while(STAT_BF==1){;} // attente la fin de la reception, si BF=1, on a la donnnée dans SSPBUF
    ACKEN=1; // on valide l'emission du ACK en mode reception
    ACKDT=1; // on envoi un NOACK pour dire, qu'on a bien recu l'octet
    RCEN=0; // On valide la 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
    }


    // ************ P.P ********************

    main()
    {
    init_lcd();
    init_I2C();

    while(1)
    {
    emis2_I2C(EEPROM1,i,z);
    tempo1ms(10);
    a=lect2_I2C(EEPROM1,i);
    sprintf(texte,"valeur=%d",a);
    puts_lcd(texte,0);
    i++;
    z++;
    efface_lcd();
    tempo1ms(400);
    }
    }
    voila ce code est celui que j'utilise bien actuellement. Merci pour ton aide umfred.

  14. #11
    umfred

    Re : Eeprom I²c

    Si cela marche avec le debugger, je soupconne un problème de temps. Essaie de mettre un léger temps à la fin du sous programme de lecture entre l'envoi de l'ACK et le PSTOP (éventuellement utilise le SSPIF pour t'aider).

  15. #12
    RISC

    Re : Eeprom I²c

    Olfox,

    Quel PIC utilises-tu sur ta carte PICDEM 2 PLUS : un PIC18F4520 ou un PIC16F877A ?

    Tu peux trouver des routines en C pour cette carte (ou l'ancienne version très proche ici) :
    http://www.microchipc.com/sourcecode/#i2c

    a+

  16. Publicité
  17. #13
    Olfox

    Re : Eeprom I²c

    Oui effectivement RISC j'ai observé ces routines sur le site et je les ai telecharger, je les etudiré plus profondement demain car je ne suis plus trè frais mentalement je pence pour aujourdui. Merci beaucoup pour tes renseignements!

Discussions similaires

  1. [Blanc] programme eeprom
    Par tournenrond dans le forum Dépannage
    Réponses: 8
    Dernier message: 15/02/2007, 21h02
  2. Eeprom 24lc256
    Par thomasalbert1993 dans le forum Électronique
    Réponses: 5
    Dernier message: 28/12/2006, 13h15
  3. Eeprom du PIC16F84
    Par clinon dans le forum Électronique
    Réponses: 8
    Dernier message: 30/11/2006, 19h45
  4. memoires EEPROM
    Par julienM dans le forum Électronique
    Réponses: 11
    Dernier message: 11/05/2006, 09h55
  5. Eeprom
    Par sronin1 dans le forum Électronique
    Réponses: 2
    Dernier message: 24/05/2003, 18h22
Découvrez nos comparatifs produits sur l'informatique et les technologies.