STM32F103C8T6 - Comunicación I2C con TI FuelGauge BQ78350

0

Estoy tratando de establecer comunicación entre TI BQ78350 FuelGauge y STM32F103C8T6 usando I2C / SMBus. La siguiente es la configuración I2C utilizada para la biblioteca HAL I2C estándar.

static void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

Cuando trato de transmitir algo a FuelGauge, usando el siguiente código no hay un reconocimiento y respuesta adecuados. Solo se transmite el byte de dirección.

 HAL_I2C_Master_Transmit(&hi2c1,11<<1,0x09, 1, 100);

Así es como se ve la forma de onda en un osciloscopio.

En el lado del hardware, estoy usando Mosfet BSS138 para nivelar el cambio entre el indicador de combustible de 5V y 3.3V STM32F103. El valor de la resistencia de pull-up es 3.3k.

Cualquier puntero a la causa de este problema sería útil. Gracias.

    

4 respuestas

0

Aparte de los problemas de conversión de voltaje y nivel ya mencionados; No hay problema en la transacción en sí.

La MCU realiza exactamente lo que el código le dice que haga. Aunque puede que no sea lo que quieres.

Transfiere un byte de la memoria MCU a la dirección I2C del chip.

Los datos se envían desde el puntero que está configurado para apuntar a la dirección MCU 0x09. Esta dirección aparentemente contiene un byte 0x00 que se envía a través del bus. Lo más probable es que quieras apuntar a un búfer o variable que contiene los datos que se enviarán, en este caso lo más probable es que quieras enviar 0x09, que es un comando para leer el voltaje.

    
respondido por el Justme
1

Su señal no se ve limpia y es probablemente la razón por la que tiene un problema.

Probablemente esté relacionado con su unidad mosfet, y tal vez con alguna capacitancia en la línea.

Para I2C, no necesitas cambio de nivel.

En cuanto a un chip de 5V, el umbral para un "1" lógico será más bajo que el de 3.3V, por lo que simplemente necesita poner su resistencia pull-up a 3V3, ya que ambos circuitos integrados que controlan las líneas I2C deben estar abiertos. control, su línea SDA / SCK nunca superará los 3V3.

Así que elimine todo el mosfet de cambio de nivel y conecte su pullup a 3V3. También puedes disminuir el pullup a 1k para tener un borde más rápido.

    
respondido por el Damien
1

Muchos de los pines STM32 son tolerantes a 5V. Por lo tanto, es probable que pueda omitir la parte de cambio de nivel, especialmente para una arquitectura de drenaje abierto como I²C, donde el nivel de salida está determinado por el voltaje que levanta.

Los pines no pueden generar 5V, pero toleran una entrada de hasta 5V. Eche un vistazo en la hoja de datos donde se indica el nivel de E / S. Un "FT" denota un pin que es tolerante a 5 V.

    
respondido por el Arsenal
0

No veo el problema del que estás hablando. El esclavo ACKed ambos bytes. Puede saber cuándo el esclavo está controlando el bus porque, convenientemente, su tierra se desplaza un poco desde la tierra del maestro. Aquí está mi desglose de tu disparo de alcance:

  • Supongo que hay un inicio que no se muestra en su seguimiento de O-scope.
  • Al comienzo de la traza del o-scope, el esclavo es el estiramiento del reloj por alguna razón.
  • El primer byte entra y es reconocido por el esclavo.
  • El segundo byte entra y el reloj esclavo se estira de nuevo, al final del segundo byte pero antes del ACK.
  • El esclavo libera el reloj, y luego ACKs.
  • Detente.

Es posible que desee averiguar de qué se trata todo el alargamiento del reloj.

    
respondido por el Annie

Lea otras preguntas en las etiquetas