0
\$\begingroup\$

I'm trying to use 3 TCA9539PWR and a TCA6408A on an I2C bus.

Here's the schematic diagram:

enter image description here

However, when I try to send the TCA9539PWR's addresses , none of them responds (no ACK) and when I try to send the address of TCA6408A (0x40,) the wave shows that it can't pull down the bus fully.

enter image description here

I use 10k pull-up resistors, and I think it's the resistor is strong enough;I can't change the res on the pcb easily, so it's hard for me to test that.

That's a part of the code I use to control the SDA and SCL:


void SDA_OUT(void) //init SDA to send Data
{
   GPIO_InitTypeDef GPIO_InitStruct;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Pin = I2C_SDA_Pin;
   HAL_GPIO_Init(I2C_PORT, &GPIO_InitStruct );
}

//...

void SDA_IN(void)    //release the SDA wire
{
   GPIO_InitTypeDef GPIO_InitStruct = {0};
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Pin = I2C_SDA_Pin;
   HAL_GPIO_Init(I2C_PORT, &GPIO_InitStruct );
}

//The SCL wire was initialized by STM32CUBEMX;
  GPIO_InitStruct.Pin = I2C_SDA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
\$\endgroup\$
4
  • \$\begingroup\$ Would you show the code where the SDA and SCL pins are initialized? \$\endgroup\$
    – Justme
    Nov 9, 2019 at 8:11
  • \$\begingroup\$ @Justme Sure,I've edited my question.Thanks. \$\endgroup\$
    – Farthing
    Nov 9, 2019 at 8:22
  • 1
    \$\begingroup\$ Shouldn't the GPIO mode be at an open-drain mode? You are using push-pull mode GPIO. I think that might be the issue. \$\endgroup\$ Nov 9, 2019 at 8:37
  • 1
    \$\begingroup\$ I don't understand why bitbanging the I2C in software as the STM32 contains a I2C peripheral so you don't have to bitbang. \$\endgroup\$
    – Justme
    Nov 9, 2019 at 8:41

2 Answers 2

2
\$\begingroup\$

I2C pins must not be set to output high. You are using push-pull outputs. STM32 can configure them as open-drain outputs. In that case it is not even necessary to change it to input for reading. In reality you would not bit-bang the protocol yourself as the STM32 contains an i2C peripheral.

\$\endgroup\$
1
  • \$\begingroup\$ The other way to bit-bang I2C without using open-collector mode is to pre-set the output register bit to zero and switch to mode register for the output value: input for high (actually high-Z) or output for drive low. \$\endgroup\$
    – DoxyLover
    Nov 9, 2019 at 10:56
1
\$\begingroup\$

SDA line should be configured as open drain, not as push-pull. With push-pull the slave is pulling low, while your master is pulling high.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.