cancel
Showing results for 
Search instead for 
Did you mean: 

hello. i am working on a project using two stm32g431rb nucleo boards. i need to make a connection between these mcu's so i choose I2C as the connection protocol.

sabd.1
Associate II

the problem is when the master micro wants to tell the slave to send some data, after a random time the i2c connection disrupts and i will get HAL_ERROR Message. i wrote the below codes for master and slave:

Master code:

 while (1)

 {

  /* USER CODE END WHILE */

 if(i==0)

 {

 data=202;

   HAL_I2C_Master_Transmit(&hi2c3,(0x02<<1),&data,8,10);

 HAL_Delay(1);

 data=1;

   HAL_I2C_Master_Transmit(&hi2c3,(0x02<<1),&data,8,10);

 HAL_Delay(1);

   a=HAL_I2C_Master_Receive(&hi2c3,(0x02<<1),&data2,8,10);

   i=1;

 }

 HAL_Delay(1);

 i=0;

 /*   if(data2==1)

   {

    b=1;

   }*/

slave code:

 while (1)

 {

  /* USER CODE END WHILE */

 a=HAL_I2C_Slave_Receive(&hi2c3,&data,8,10);

 if(a==HAL_OK)

 {

 switch(program_setting)

 {

 case 0:

  {

  if(data==202)

  {

  program_setting=4;

  }

  }

 break;

 case 4:

  {  pin=data;

  if(pin==1)

  { HAL_Delay(1);

  b=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);

  HAL_I2C_Slave_Transmit(&hi2c3,&b,8,10);

  program_setting=0;

  }

  }

 break;

 }

 }

 }

  /* USER CODE BEGIN 3 */

 }

6 REPLIES 6
MM..1
Chief III

How type is data data2 ???

 data=202;
   HAL_I2C_Master_Transmit(&hi2c3,(0x02<<1),&data,8,10);

Your code send 8 bytes from start adr data in 10ms timeout. Bigger issue is receive you write to memory not reserved for data2...

TDK
Guru

UART might be a simpler protocol choice.

If you feel a post has answered your question, please click "Accept as Solution".
Piranha
Chief II

Making an I2C slave device indeed is not a task for beginners, especially with ST's useless "drivers". TDK is right - UART is simpler. One should first implement and completely understand a decent UART implementation with continuous reception. A good explanation and an example is here:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

data and data2 are uint8_t variables.

what do you mean by "the memory not reserved for data2"?

I think the code itself assigns a register to data2 and keeps received value in data2.

sabd.1
Associate II

thanks for your suggestion. I will consider it as a plan B.

But let's assume that the decision is made and I have to work with the I2C protocol.

The master wants to know the state of GPIO pins of the slave microcontroller.

so first of all, it must tell the slave read a GPIO pin or Toggle it.

then the master must tell the slave which pins to read.

and after it, the slave must send the GPIO Pin state to the Master.

I debugged the code and realized that the Master reads the state of 10 or 12 pins of the slave correctly, but after it, suddenly, I got HAL_ERROR or HAL_BUSY for no reason.

what is the main reason? is it the HAL_I2C library? or it is polling i2c?

can using interrupt i2c instead of polling i2c fix the problem?

what about low-level APIs instead of HAL functions?

uint8 is one byte not eight. Right code is

data=202;
   HAL_I2C_Master_Transmit(&hi2c3,(0x02<<1),&data,1,10);

same for receive.