Aller au contenu


Photo
- - - - -

I2C sur STM32


  • Veuillez vous connecter pour répondre
8 réponses à ce sujet

#1 Leplouc

Leplouc

    Nouveau membre

  • Membres
  • 8 messages

Posté 13 novembre 2017 - 06:26

Bonjour,
J'ai beau rechercher un peu partout je n'ai rien trouvé de probant sur la mise en oeuvre des interfaces I2C sur la carte STM32 ou l'Ardino DUE.
Contrairement aux UNO et MEGA, il y a 2 x I2C SDA1/SCL1 et SDA2/SCL2.
SDA1 et SCL1 ne posent aucun problème, par contre je n'ai pas encore trouvé le moyen d'activer SDA2/SCL2..
 



#2 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 13 novembre 2017 - 08:06

J ai pas vu non plus dans la doc de référence arduino. Mais de ce coté là : https://github.com/e...s/Wire/Wire.cpp

On y voit des méthodes begin qui prennent des pin sda et scl. Je n ai pas essayé. Ça me parait une bonne piste.

#3 Leplouc

Leplouc

    Nouveau membre

  • Membres
  • 8 messages

Posté 13 novembre 2017 - 10:20

Merci pour le lien.
C'est une bibliothèque différente de Wire.h/.cpp installée d'office avec l'IDE Arduino.
Je vais creuser la chose..!



#4 joel14

joel14

    Nouveau membre

  • Membres
  • 4 messages

Posté 04 février 2018 - 11:37

Bonjour,

 

J'ai le même problème. j'ai acquis un Nucleo STM32F302R8 et je galère depuis 3 semaines à faire fonctionner les drivers que j'ai récupérer dans le patch  "I2C_OneBoard_Communication_PollingAndIT" qui est basé sur les bibliothèques HAL et  LL de de Cube.

 

j'arrive et je vois bien des trames I2C passées sur l'exemple fourni mais dès que je remplace les datas par un exemple simple qui est d'écrire 0xFF sur un  expendeur de port de type PCF8574 je me retrouve directement blocqué sur un NACK en fin de trame  d'adressage.  je suis sur que le composant fonctionne et que son adresse est bien cablé car le bout de carte clavier fonctionne très bien sur un STM8S .

void     I2C1_Master_write(uint8_t*); // uint8_t*  transmet l'adresse de ma structure du peripherique

--------------------

//PCF8574 (clavier avec des sur toutes les sorties)
	  write_PCF8574.adresse 	=0x78; 		// 8 bit adress
	  write_PCF8574.nbbytes 	=0x1;
	  write_PCF8574.data    	=0xFF;   	// mettre tout à 1 pour le clavier

--------------------
// la boucle infinie du main. je ne fais qu'envoyer un 255 sur le port

  while (1) 
  {
	I2C1_Master_write(&write_PCF8574.adresse); /* Handle I2C1 events (Master) */
	//  calcul_temp_master();
	//  detect_clavier();
	//  delay (50);

  }

--------------------
// la routine proposée par ST qui fonctionne avec leur exemple.


/*******************************************************************************
  * @brief  This Function handle Master events to perform a transmission process
  * @note  This function is composed in different steps :
  *        -1- Initiate a Start condition to the Slave device
  *        -2- Loop until end of transfer received (STOP flag raised)
  *             -2.1- Transmit data (TXIS flag raised)
  *        -3- Clear pending flags, Data consistency are checking into Slave process
  * @param  None
  * @retval None
  */
void I2C1_Master_write(uint8_t *adresse)
{

	  /******************************************************************************
	    * @brief  cette fonction vérifie
	    * @note   This function is used to :
	    *         -1- vérifie si une touche clavier est enfoncée
	    *         -2- récupére la valeur du clavier
	    * @note   Peripheral configuration is minimal configuration from reset values.
	    *         Thus, some useless LL unitary functions calls below are provided as
	    *         commented examples - setting is default configuration from reset.
	    * @param  None
	    * @retval None
	    */

	  	uint8_t i =0;
	  	for (i=1; i<= 16 ; i++)
	  	{
	  		I2Cbuffer[i] = 0; // initialise le buffer
	  	}

	  	SlaveOwnAdress = *adresse;
	  	adresse ++ ;
	  	ubNbDataToTransmit = *adresse ; // récupération de la taille du buffer
	  	adresse ++ ;
	  	adresse ++ ;

	  	for (i=0; i<= ubNbDataToTransmit ; i++)
	  	{
	  		I2Cbuffer[i] = *adresse; // remplit le buffer
	  		adresse = adresse + 1 ;
	  	}
	  	pTransmitBuffer    	= (uint8_t*)I2Cbuffer;

	/* (1) Initiate a Start condition to the Slave device ***********************/

  /* Master Generate Start condition for a write request :              */
  /*    - to the Slave with a 7-Bit SLAVE_OWN_ADDRESS                   */
  /*    - with a auto stop condition generation when transmit all bytes */
  LL_I2C_HandleTransfer(I2C1, SlaveOwnAdress, LL_I2C_ADDRSLAVE_7BIT, ubNbDataToTransmit,
		  LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);

  /* (2) Loop until end of transfer received (STOP flag raised) ***************/
#if (USE_TIMEOUT == 1)
  Timeout = I2C_SEND_TIMEOUT_TXIS_MS;
#endif /* USE_TIMEOUT */

  /* Loop until STOP flag is raised  */
  while(!LL_I2C_IsActiveFlag_STOP(I2C1))
  {
    /* (2.1) Transmit data (TXIS flag raised) *********************************/
    /*  Check TXIS flag value in ISR register */
	if(LL_I2C_IsActiveFlag_TXIS(I2C1))
    {
      /* Write data in Transmit Data register.
      TXIS flag is cleared by writing data in TXDR register */
	  vari = *pTransmitBuffer++;
      LL_I2C_TransmitData8(I2C1, (vari));

		#if (USE_TIMEOUT == 1)
      	  Timeout = I2C_SEND_TIMEOUT_TXIS_MS;
		#endif /* USE_TIMEOUT */
    }

	#if (USE_TIMEOUT == 1)
    /* Check Systick counter flag to decrement the time-out value */
    if (LL_SYSTICK_IsActiveCounterFlag())
    {
      if(Timeout-- == 0)
      {
        /* Time-out occurred. Set LED2 to blinking mode */
        LED_Blinking(LED_BLINK_SLOW);
      }
    }
	#endif /* USE_TIMEOUT */


  }
  /* (3) Clear pending flags, Data consistency are checking into Slave process */

  /* End of I2C_SlaveReceiver_MasterTransmitter Process */
  LL_I2C_ClearFlag_STOP(I2C1);
}



en pièce jointe le résultat   la première trame a été envoyé par l'exemple donné par ST  et  suit tout de suite l'envoi de l'adresse 78 à l'expendeur de port qui ne  répond pas par un ACK

 

 

avez déjà utilisé les drivers LL de ST et si oui comment avez vous opérez?

 

Merci pour votre réponse.

 

Cordialement.

 

Joël

Fichier(s) joint(s)



#5 Leplouc

Leplouc

    Nouveau membre

  • Membres
  • 8 messages

Posté 04 février 2018 - 03:52

Bonjour Joël,

j'ai laissé de côté le STM32 pour le moment au profit d'un Arduino DUE et je n'ai pas creusé davantage le pb de l'I2C.
Par contre, êtes vous sûr de l'adresse du PCF8574 car de mon côté je l'utilise avec l'adresse 0x38 (A2, A1, A0=0) ?
Par ailleurs je ne sais plus s'il faut ou non des résistances de P/U mais je crains que vous ayez déjà fait le tour de ces 2 questions..!
Cordialement,
G
 



#6 joel14

joel14

    Nouveau membre

  • Membres
  • 4 messages

Posté 04 février 2018 - 11:26

Bonsoir,

 

j'ai la pin A2 à +3.3v  par conséquent, je suis conforme  avec une adresse à 0x78.  d'ailleurs le même clavier sur ma carte stm8s répond à cette adresse. 

 

bien entendu j'ai des pull up de 2,2k sur ICL et SDA.

 

Bon je vais essayer de refaire le driver le WE prochain en allant encore plus bas dans le code. 

 

d'ici là, il y aura peut être quelqu’un qui a réussi a faire fonctionner l'I2C avec les drivers LL. 

en pieces jointes avec extension .txt  à supprimer

 

 

cordialement.

 

Joël

Fichier(s) joint(s)



#7 Leplouc

Leplouc

    Nouveau membre

  • Membres
  • 8 messages

Posté 05 février 2018 - 07:29

Bonjour,

Je reviens sur l'adressage du 8574 que j'ai relevé il y quelques temps en utilisant Scan I2C et j'ai trouvé des résultats  différents à ceux de la datasheet; en fait il est fait abstraction des bits 6 et 7 dans l'adressage.
La table ci-dessus en Slave devient donc :
38, 38, 3A, 3B, 3C (pour votre configuration).....3F

C'est pour ça que j'ai un doute sur votre configuration, surtout si le 8574 ne réponds pas, mais je peux me tromper.
A suivre..
Cordialement,
G
 



#8 joel14

joel14

    Nouveau membre

  • Membres
  • 4 messages

Posté 06 février 2018 - 01:17

Bonjour,

 

Je confirme que c'est bien 78  puisque j'ai réussi à faire fonctionner l'I2C avec les drivers LL de ST.   le problème venait principalement de la fréquence de l'I2C  qui était à 667kz pour 400kHz max.  je suis descendu à de l'I2C 100kHz et là il a fonctionné.

 

ci dessous le résultat

 

écriture de FF sur le PCF8574 (adrr 78)

écriture de la configuration du TMP100 de chez Texas (adrr 94) = sonde de température via I2C

écriture du start conversion du TMP100 de chez Texas (adrr94)

lecture du registre de la conversion du TMP  (read adrr 95)

 

je vais maintenant finir mon template projet avec  I2C fonctionnel.

 

je le mettrai à disposition si cela intéresse ?

 

cordialement.

 

Joël

Fichier(s) joint(s)



#9 T0T0R

T0T0R

    Nouveau membre

  • Membres
  • 1 messages

Posté 26 décembre 2020 - 06:26

Bonjour,
J'ai beau rechercher un peu partout je n'ai rien trouvé de probant sur la mise en oeuvre des interfaces I2C sur la carte STM32 ou l'Ardino DUE.
Contrairement aux UNO et MEGA, il y a 2 x I2C SDA1/SCL1 et SDA2/SCL2.
SDA1 et SCL1 ne posent aucun problème, par contre je n'ai pas encore trouvé le moyen d'activer SDA2/SCL2..
 

Bonjour,

Je sais que le message est un peu ancien, mais je n'ai trouvé cette information nulle part ailleurs.

Après quelques essais, begin(sda,scl) ne fonctionne pas sur mon STM32F1038.
En revanche, le fichier Wire.h présente deux fonctions setSDA() et setSCL().
Et après avoir effectué

Wire.setSCL(PB10);
Wire.setSDA(PB11);
Wire.begin();

le signal I2C apparaissait bien sur les nouvelles pins PB10 et PB11.

Cordialement
 






0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users