Problème de communication I2C
Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

Problème de communication I2C



  1. #1
    todd_terry

    Unhappy Problème de communication I2C


    ------

    Bonjour à tous,

    j'essaye de faire fonctionner l'I2C entre un microcontroleur Renesas M16C/29 et une EEPROM 24LC256, tout semble être envoyé correctement mais l'EEPROM ne relache pas SDA à la fin de la 9eme impulsion d'horloge:



    Du coup la condition STOP ne peut pas être envoyée correctement et le microcontroleur bloque.

    Même sans connaître le M16C/29, est-ce que quelqu'un a une idée de ce qui pourrait empècher l'EEPROM de laisser SDA repasser à 1?
    Si j'effectue plusieurs transmissions en déconnectant SDA de l'EEPROM et que je reconnecte ce signal, j'arrive à communiquer par la suite avec l'EEPROM sans problème (jusqu'à la prochaine mise sous tension de mon montage).
    J'ai essayé avec d'autres EEPROMs (24C65, 24C512) et le problème persiste.
    J'ai essayé de réduire le débit I2C mais ça n'arrange rien.

    Au cas ou quelqu'un ici connaîtrait la famille M16C/Tiny, j'utilise le microcontroleur en mode I2C simple. J'aurai pu créer mes fonctions de communication I2C en soft mais comme c'est géré en hard, je ne vois pas pourquoi je devrais tout refaire. Je peux poster le code si ça peut servir à résoudre mon problème.

    -----

  2. #2
    invite03481543

    Re : Problème de communication I2C

    Salut,

    En principe il faut bloquer les interruptions si tu les utilises, avant de commencer à écrire puis il faut les réactiver après.
    Si tu peux poster ton code, ce serait plus facile de voir ce que tu as fais.
    @+
    Dernière modification par HULK28 ; 01/05/2008 à 18h59.

  3. #3
    todd_terry

    Re : Problème de communication I2C

    Voila le code que j'utilise (récupéré sur un site, je débute en C):

    Code:
    void un()
    {	
    	i2c_start();
    	U0_in = EEPROM_send_data(0xA1);
    	i2c_stop();
    		
    	if(!U0_in)
    	{
    		uart_write("EEP ACK\r\n");
    	}
    	else
    	{
    		uart_write("EEP NACK\r\n");
    	}
    }
    
    //--------------------------------------------------------------------------------------
    // Name:		i2c_init
    // Parameters:	None
    // Returns:	None
    // Description: This routine configures UART2 as i2c
    //--------------------------------------------------------------------------------------
    void i2c_init(void)
    {
    	u2brg = 0x7F;					// BRG = FFh minimum value
    	u2mr = 0x02;					// i2c mode, internal clock
    	u2c0 = 0x80;					// clk = f32sio, MSB first
    	u2c1 = 0x05;					// enable reception and transmission
    	u2smr = 0x83;					// i2c mode, arbitration lost by byte
    	u2smr2 = 0x00;					// ack/nack int, with NO clock sinchronization
    	u2smr3 = 0x0A;					// clock delayed, clock out cmos, with no data delay
    	u2smr4 = 0x40;
    	// initializes timer 2 - used to time controls of i2c 
    	ta2mr = 0x80;				// Set mode of timer A2
    								// clk =24MHz/32 = 750kHz -> T = 1,333us
    	ta2 = 0xFFFF;
    	ta2s = 1;					// start counting
    	
    }
    
    //--------------------------------------------------------------------------------------
    // Name:		EEPROM_send_data
    // Parameters:	Byte to be sent
    // Returns:	1 = NACK received, 0 = ACK received
    // Description: Send a byte through the serial line 
    //--------------------------------------------------------------------------------------
    char EEPROM_send_data(unsigned char data)
    {	
    	te_u2c1 = 1;				// transmit data (enable bit)
    	while(!ti_u2c1);			// wait for tx buffer to be empty
    	ir_s2ric = 0;				// reset reception interrupt bit
    	ir_s2tic = 0;				// reset transmission interrupt bit
    	u2tbl = data;				// transmit data
    	//while(!ri_u0c1)				// wait for rx buffer to be full
    	while((!ir_s2ric) && (!ir_s2tic));	// wait until ack or nack
    	te_u2c1 = 0;				// disable transmission
    	if ((u2rbh & 0x01) == 1)
    	{
    		return(1);
    	}
    	else return(0);
    }
    
    //--------------------------------------------------------------------------------------
    // Name:		i2c_start
    // Parameters:	None
    // Returns:	None
    // Description: Generates the start condition in the i2c line
    //--------------------------------------------------------------------------------------
    void i2c_start(void)
    {
    	unsigned int dly_tmr;
    //	dly_tmr = ta2; while((dly_tmr - ta2) < _1ms ); // delay
    	stareq_u2smr4 = 1;			// Start condition generate bit
    	dly_tmr = ta2; while((dly_tmr - ta2) < _1ms ); // delay
    	stspsel_u2smr4	= 1;		// SCL, SDA output select bit - set
    	while(stareq_u2smr4 == 1);
    	dly_tmr = ta2; while((dly_tmr - ta2) < _1ms ); // delay
    	stspsel_u2smr4	= 0;		// SCL, SDA output select bit - reset
    }
    
    //--------------------------------------------------------------------------------------
    // Name:		i2c_stop
    // Parameters:	None
    // Returns:	None
    // Description: Generates the stop condition in the i2c line
    //--------------------------------------------------------------------------------------
    void i2c_stop(void)
    {
    	unsigned int dly_tmr;
    	dly_tmr = ta2; while((dly_tmr - ta2) < _1ms ); // delay
    	stpreq_u2smr4 = 1;			// Stop condition generate bit
    	dly_tmr = ta2; while((dly_tmr - ta2) < _1ms ); // delay
    	stspsel_u2smr4	= 1;		// SCL, SDA output select bit
    	while(stpreq_u2smr4==1);
    	dly_tmr = ta2; while((dly_tmr - ta2) < _1ms ); // delay
    	stspsel_u2smr4	= 0;		// SCL, SDA output select bit
    }
    Voila comment ça fonctionne:

    Si j'envoie le caractère 1 par l'UART, ça appele un().
    Ca n'a aucun interêt pour l'instant, je fais juste des bouts de code pour pouvoir utiliser chaque fonction du microcontroleur.

    Je suis d'accord pour ce qui concerne la désactivation des interruptions, mais pour l'instant le programme est tellement simple qu'aucune interruption ne devrait gèner son fonctionnement, surtout que dans ce cas c'est l'EEPROM qui semble poser problème.

  4. #4
    jiherve

    Re : Problème de communication I2C

    Bonsoir
    question bête sans doute mais il y a bien une résistance de pull up sur le fil SDA ?
    JR

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

    Re : Problème de communication I2C

    En fait le M16C/29 ne semble pas permettre d'utiliser sa sortie SDA en "drain ouvert". C'est pourquoi on voit que l'ACK de l'EEPROM n'est pas à 0V, en fait elle force la tension fournie par la broche du microcontroleur tant bien que mal à 0V.
    Que la liaison I2C fonctionne correctement ou non, l'ACK n'est jamais vraiment à 0V.
    J'ai quand-même testé avec des pull-up mais ça ne change rien au problème.

  7. #6
    Jack
    Modérateur

    Re : Problème de communication I2C

    En fait le M16C/29 ne semble pas permettre d'utiliser sa sortie SDA en "drain ouvert"
    On contourne le problème en mettant la pin en entrée pour générer un '1', grâce à la pull up. Pour générer un '0', on remet la pin en sortie en mettant le port à '0'.

    A+

  8. #7
    todd_terry

    Re : Problème de communication I2C

    J'ai finalement trouvé où configurer les broches en drain ouvert, mais ça ne résoud rien...

  9. #8
    todd_terry

    Re : Problème de communication I2C

    Fin du casse tête (qui dure depuis quelques weekends pour moi):
    la donnée de test que j'envoyais sur le bus I2C était fausse car le bit R/W était à 1, ce qui n'est pas possible en début de communication avec un périphérique I2C.

    Petite mise à jour de l'init I2C pour ceux que ça intéresse, pour avoir SDA et SCL en drain ouvert:

    Code:
    u2c0 = 0xA0;
    NCH est mis à 1.

Discussions similaires

  1. Communication I2C entre 3 pic 16f876
    Par invitee092e9a2 dans le forum Électronique
    Réponses: 0
    Dernier message: 07/04/2008, 19h40
  2. Communication USART avec PIC et stockage dans I2c
    Par invitead8d66d4 dans le forum Électronique
    Réponses: 0
    Dernier message: 23/12/2007, 16h51
  3. communication i2c entre deux pics
    Par invite45c27900 dans le forum Électronique
    Réponses: 2
    Dernier message: 02/11/2007, 23h56
  4. Probleme I2C
    Par invite47dfc8ff dans le forum Électronique
    Réponses: 4
    Dernier message: 14/05/2006, 02h24
  5. Communication I2C entre PIC et ordinateur / Problème d'interruption
    Par invite68d5b092 dans le forum Électronique
    Réponses: 3
    Dernier message: 01/11/2005, 23h45
Découvrez nos comparatifs produits sur l'informatique et les technologies.