I2C habilitado LCD poco fiable

0

Estoy tratando de controlar un Pantalla LCD I2C habilitada utilizando el STM32F0. Tengo un montón de tableros construidos con las pantallas LCD y un par de ellos trabajan todo el tiempo, algunos trabajan de forma intermitente y algunos rara vez funcionan y no estoy seguro de dónde viene el problema.

He intentado analizar las líneas I2C y algunas veces veo la pantalla NACKing mientras que otras veces lo veo ACK pero el I2C simplemente se detiene. A veces incluso veo un montón de datos inesperados que se envían.

Para empezar, estoy tratando de averiguar si se trata de un problema de hardware, un problema de la pantalla LCD o un problema de FW. Desde la perspectiva del hardware, he seguido el circuito recomendado en la hoja de datos y he usado ~ 6k pull-ups. Solo puedo asumir que el LCD en sí funciona, ya que a veces puedo hacer que se muestre correctamente. Esto me lleva a creer que es un problema de FW. Me he dado cuenta de que si juego con los retrasos entre los mensajes, a veces puedo hacer que funcione y ciertamente puedo romperlo. ¿Hay alguna otra comprobación de errores o algo similar que debería hacer en la unidad de usuario para mejorar la confiabilidad?

voidI2C_LowLevel_Init(void){GPIO_InitTypeDefGPIO_InitStructure;/*ConfiguretheI2Cclocksource.TheclockisderivedfromtheHSI(8MHzdefault)*/RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);/*LCD_I2C_SCL_GPIO_CLKandLCD_I2C_SDA_GPIO_CLKPeriphclockenable*/RCC_AHBPeriphClockCmd(LCD_I2C_SCL_GPIO_CLK|LCD_I2C_SDA_GPIO_CLK,ENABLE);/*LCD_I2CPeriphclockenable*/RCC_APB1PeriphClockCmd(LCD_I2C_CLK,ENABLE);/*ConnectPXxtoI2C_SCL*/GPIO_PinAFConfig(LCD_I2C_SCL_GPIO_PORT,LCD_I2C_SCL_SOURCE,LCD_I2C_SCL_AF);/*ConnectPXxtoI2C_SDA*/GPIO_PinAFConfig(LCD_I2C_SDA_GPIO_PORT,LCD_I2C_SDA_SOURCE,LCD_I2C_SDA_AF);/*GPIOconfiguration*//*ConfigureLCD_I2Cpins:SCL*/GPIO_InitStructure.GPIO_Pin=LCD_I2C_SCL_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;GPIO_Init(LCD_I2C_SCL_GPIO_PORT,&GPIO_InitStructure);/*ConfigureLCD_I2Cpins:SDA*/GPIO_InitStructure.GPIO_Pin=LCD_I2C_SDA_PIN;GPIO_Init(LCD_I2C_SDA_GPIO_PORT,&GPIO_InitStructure);}voidI2C_Initialize(void){I2C_InitTypeDefI2C_InitStructure;I2C_LowLevel_Init();/*I2Cconfiguration*//*LCD_I2Cconfiguration*/I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;I2C_InitStructure.I2C_AnalogFilter=I2C_AnalogFilter_Enable;I2C_InitStructure.I2C_DigitalFilter=0x00;I2C_InitStructure.I2C_OwnAddress1=0x00;I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_Timing=I2C_TIMING;/*ApplyLCD_I2Cconfigurationafterenablingit*/I2C_Init(LCD_I2C,&I2C_InitStructure);/*LCD_I2CPeripheralEnable*/I2C_Cmd(LCD_I2C,ENABLE);/*SelecttheLCDdeviceaddress*/I2C_Address=I2C_HW_ADDRESS;Delay(10);}uint32_tLCD_Initialize(void){staticintinitBuffer[8]={0x14,LCD_CONTRAST_RESET,0x5E,0x6D,LCD_DISPLAY_ON,LCD_CLEAR,0x06};staticcharwelcomeMessage1[LCD_MAX_LINE_SIZE+1]="HELLO WORLD";
  int n = 0;

  /* Send Start Bit and I2C Device Address */
  I2C_TransferHandling(LCD_I2C, (LCD_DEVICE_ADDRESS << 1), 10, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);

  /* Wait for TXIS to be set */
  //lcdTimeout = LCD_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(LCD_I2C, I2C_ISR_TXIS) == RESET)
  {
    //if((lcdTimeout--) == 0) return LCD_INITIALIZE_FAIL;
  }

  I2C_SendData(LCD_I2C, 0x00);          /* CMD Byte- Only Data to Follow */
  Delay(1);
  I2C_SendData(LCD_I2C, LCD_BASIC_CONFIG);
  Delay(10);
  I2C_SendData(LCD_I2C, LCD_EXTENDED_CONFIG);
  Delay(10);

  /* Send Remaining Initialization Buffer Data */
  for (n=0; n<7; n++)
  {
    I2C_SendData(LCD_I2C, initBuffer[n]);
    Delay(1);
  }

  Delay(10);


  /* Display welcome message to confirm LCD initialization */
  LCD_Display(LCD_LINE1_START, welcomeMessage1);
  Delay(1000);
  LCD_Clear();
  return LCD_INITIALIZE_PASS;
}
    
pregunta spizzak

2 respuestas

1

6K parece un poco débil para las resistencias pullup; Normalmente, usted quiere que pasen 2-3 mA cuando la línea está baja. 2700 Ω es un valor de uso común en sistemas de 5V.

    
respondido por el Dave Tweed
1

¿Dónde estás configurando la velocidad de tu reloj I2C? Consulte enlace

Intenta establecer explícitamente I2C_InitStructure.I2C_ClockSpeed en algo razonable.

    
respondido por el Scott Seidman

Lea otras preguntas en las etiquetas