AnsweredAssumed Answered

STM32L151 + TMP100 temp sensor ==> I2C always busy

Question asked by David Rodenas on Jul 15, 2017
Latest reply on Jul 15, 2017 by David Rodenas

Hello everyone, 


I have looked up this issue but I am afraid I have been unable to find a solution. 


I have a TI TMP100 temperature sensor connected to a stm32l151 MCU by way of I2C1. The initialisation code of the I2C bus is fairly standard (I am using the STM32 standard library), as seen below:


I2C_InitTypeDef I2C_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;


/* Enable GPIOB (SDA and SCL) clocks */


/* Configure I2C clock and GPIO */


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


/* Configure I2C1 SCL and SDA pins */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);


/* Connect I2C1 pins to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1); // SCL
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); // SDA


/* I2C1 Reset */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);


/* Configure I2C */

I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);



After executing the above code, I try to test the i2c bus by way of the following code:

/* Test on BUSY Flag */
Timed(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));


/* Enable the I2C peripheral */
I2C_GenerateSTART(I2C1, ENABLE);


/* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */


/* Send device address for write */
I2C_Send7bitAddress(I2C1, slaveAddress, I2C_Direction_Transmitter);

/* Test on EV6 and clear it */


#define Timed(x)                          \
   Timeout = 0xFFFF;                   \
   while ( x )                                   \
   {                                                 \
      if (Timeout-- == 0) return 1;    \

and slaveAddress is any of the following tmp100 addresses (0x48, 0x49, ..., 0x4F). At this point I am trying all of them, though it should be 0x4A.


Anyhow, as you might suspect, it is not working.


At the beginning, I wasn't able to generate the START condition, I2C_FLAG_BUSY seemed to be always set to RESET. Checking the datasheet, it turned out that pull-up resistors were necessary on SCL and SDA lines. I added two 4.7KOhm resistors, one connected to SCL and another to SDA, and both to VCC. Apparently, the problem was solved, However, 


always returns error ("fires" Timed).


My guess... perhaps I am trying to communicate with the device using the wrong address. But I am following the tmp100 datasheet, so I don't understand why it doesn't work.


I have tried this with two different TMP100 devices, and I always get the same result.


Any advice would be very welcome. Many thanks


Best wishes,