I2C communication with multiple slaves
Hi guys may I ask for your inputs on the I2C communication. I am using STM32F103C8 MCU with 2 slaves on the I2C bus. 1st slave is PCF8574 IO expander and 2nd slave is MCP4725 DAC. I'm using CubeMX to generate my codes.
What I wanted to do is use 2 buttons. The first button is connected to STM32 and when toggled this enables/disables one of the PCF8574 IO. The second button connected to the STM32 is used to enable/disable the MCP4725 DAC. Both slaves are connected to the same I2C line.
Basically if I put both slaves together and place them in the while(1) loop everything works fine. However when I use the callback the 2 slaves tend to work intermittently and sometimes hang.
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
HAL_I2C_Master_Transmit_IT(&hi2c1, 0xC0, buffer_I2C, 3);
HAL_I2C_Master_Transmit_IT(&hi2c1, 0x40, buffer_PCF8574Write, 1);
/* USER CODE END 2 */
//call Master transfer complete callback
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
//define the pin combinations for the 2 buttons
{
if((HAL_GPIO_ReadPin(BUTTON1_LED_GPIO_Port, BUTTON1_LED_Pin)) && (!HAL_GPIO_ReadPin(BUTTON2_LED_GPIO_Port, BUTTON2_LED_Pin)))
{
buttonstate = 0xFF; //PCF8574 out only
}
else if((!HAL_GPIO_ReadPin(BUTTON1_LED_GPIO_Port, BUTTON1_LED_Pin)) && (HAL_GPIO_ReadPin(BUTTON2_LED_GPIO_Port, BUTTON2_LED_Pin)))
{
buttonstate = 0xF0; //MCP4725 out only
}
else if((HAL_GPIO_ReadPin(BUTTON1_LED_GPIO_Port, BUTTON1_LED_Pin)) && (HAL_GPIO_ReadPin(BUTTON2_LED_GPIO_Port, BUTTON2_LED_Pin)))
{
buttonstate = 0x0F; //PCF8574 and MCP4725 out
}
else if((!HAL_GPIO_ReadPin(BUTTON1_LED_GPIO_Port, BUTTON1_LED_Pin)) && (!HAL_GPIO_ReadPin(BUTTON2_LED_GPIO_Port, BUTTON2_LED_Pin)))
{
buttonstate = 0x00; //no PCF8574 and MCP4725 out
}
}
{
switch(buttonstate)
{
//write to slave address 0x40 of PCF8574. Configured active low.
case 0xFF:
buffer_PCF8574Write[0] = 0xFE;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0x40, buffer_PCF8574Write, 1);
//write to slave address 0xC0 of MCP4725
buffer_I2C[0] = 0x40;
buffer_I2C[1] = 0x00;
buffer_I2C[2] = 0x00;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0xC0, buffer_I2C, 3);
break;
//write to slave address 0xC0 of MCP4725
case 0xF0:
buffer_I2C[0] = 0x40;
buffer_I2C[1] = 0xFF;
buffer_I2C[2] = 0xF0;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0xC0, buffer_I2C, 3);
//write to slave address 0x40 of PCF8574. Configured active low.
buffer_PCF8574Write[0] = 0xFF;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0x40, buffer_PCF8574Write, 1);
break;
//write to slave address 0x40 of PCF8574. Configured active low.
case 0x0F:
buffer_PCF8574Write[0] = 0xFE;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0x40, buffer_PCF8574Write, 1);
//write to slave address 0xC0 of MCP4725
buffer_I2C[0] = 0x40;
buffer_I2C[1] = 0xFF;
buffer_I2C[2] = 0xF0;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0xC0, buffer_I2C, 3);
break;
//write to slave address 0x40 of PCF8574. Configured active low.
case 0x00:
buffer_PCF8574Write[0] = 0xFF;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0x40, buffer_PCF8574Write, 1);
//write to slave address 0xC0 of MCP4725
buffer_I2C[0] = 0x40;
buffer_I2C[1] = 0x00;
buffer_I2C[2] = 0x00;
HAL_I2C_Master_Transmit_IT(&hi2c1, 0xC0, buffer_I2C, 3);
break;
default:
break;
}
}
}