-1

Board : STM32F4 Discovery

I am having troubles initializing I2C, i think! When the program reaches I2C_write function it hangs! I am trying to communicate with a temp&hum sensor HDC1080 from TI. The hardware is ok, i've been testing it with cubeMX and HAL libraries and it works ok!

I have a saleae logic analyzer hooked up to PB8(SCL) and PB9(SDA) , there's no activity!

I removed the init_usart part thinking that maybe they are interffering because they share the same port (GPIOB).

void init_usart(void)
{
  //enable AHB1 peripheral clock
  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE);
  //Init GPIOB
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStruct);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

  //Enable USART peripheral clock
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  //Init usart
  USART_InitTypeDef USART_InitStruct;
  USART_InitStruct.USART_BaudRate = 57600;
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  USART_InitStruct.USART_StopBits = USART_StopBits_1;
  USART_InitStruct.USART_Parity = USART_Parity_No ;
  USART_InitStruct.USART_Mode = USART_Mode_Tx;
  USART_InitStruct.USART_HardwareFlowControl = 
  USART_HardwareFlowControl_None;
  USART_Init(USART1, &USART_InitStruct);
  USART_Cmd(USART1, ENABLE);
}
void InitializeI2C()
{
  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE);

  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_8 | GPIO_Pin_9; // 8=SCL 9=SDA
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStruct);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);

  /* enable APB1 peripheral clock for I2C1*/
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);

  I2C_InitTypeDef I2C_InitStruct;
  I2C_InitStruct.I2C_ClockSpeed = 100000;
  I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStruct.I2C_OwnAddress1 = 0x01;
  I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_Init(I2C1, &I2C_InitStruct);
  I2C_Cmd(I2C1, ENABLE);
}
void I2C_write( uint8_t HW_address, uint8_t addr, uint8_t data)
{
  I2C_GenerateSTART(I2C1, ENABLE);
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  I2C_Send7bitAddress(I2C1, HW_address, I2C_Direction_Transmitter);
  while (!I2C_CheckEvent(I2C1, 
  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  I2C_SendData(I2C1, addr);
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  I2C_SendData(I2C1, data);
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  I2C_GenerateSTOP(I2C1, ENABLE);
  while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
}
int main(void)
{
  init_usart()
  InitializeI2C();

  while (1)
  {
    delay_div(50);
    I2C_write( 0x40 << 1 , 0x01, 0x00);  //here it stops!!!
  }
Antmar
  • 63
  • 5

2 Answers2

1

One possible problem: You are using uninitialised data.

From your code:

I2C_InitTypeDef I2C_InitStruct;
I2C_InitStruct.I2C_ClockSpeed = 100000;
//I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = 0x01;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStruct);

At least I2C_Mode is not initialised here, and you cannot assume the value to be 0. It will just be whatever is on the stack at that time.

You either want to memset the struct to 0, or implicitly initialise other members to zero when declaring:

I2C_InitTypeDef I2C_InitStruct = {
    .I2C_ClockSpeed = 100000,
    //.I2C_Mode = I2C_Mode_I2C,
    .I2C_DutyCycle = I2C_DutyCycle_2,
    .I2C_OwnAddress1 = 0x01,
    .I2C_Ack = I2C_Ack_Enable,
    .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
};
I2C_Init(I2C1, &I2C_InitStruct);
domen
  • 1,819
  • 12
  • 19
  • Don't know how that line got commented, it's not like that in my text editor, maybe a copy/paste error thing! I will uncomment it now! – Antmar Apr 29 '19 at 08:27
  • Oh, I just assumed you intended to have that as `0`. There might also be other struct members that should not be uninitialised. – domen Apr 29 '19 at 08:34
-1

My temp & hum sensor is dead! I2C init is fine, tried it with an i2c oled display and i can see activity on the bus!

Just a short and final update!!! Bear with me, please!

My temp&hum sensor (HDC1080) was ok! After spending 40 minutes soldering wires to a new sensor (the pins are 0.4mm) i discovered that this was also not working. Nothing changed in terms of hardware from my succesfull initial test that i did using the HAL library, breadboard with 2 x 10k (that's what i had) pull-up resistors, 3V power supply from stm32 discovery board. It seems that for unknown reasons the HAL test was working with those two 10k pull-ups but the SP library wasn't. Since my SSD1306 oled display comes on a pcb with 4.7k resistors already mounted i was able to discover that i can communicate with both the temp&hum sensor and display. Final conclusion , pull-up resistors was my problem in the end!

Antmar
  • 63
  • 5