STM32L151 + TMP100 temp sensor ==> I2C always busy
Hello everyone,
I have looked up this issue but I am afraid I have been unable to find a solution.
I have a TI
http://www.ti.com/lit/ds/sbos231i/sbos231i.pdf
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*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);/*
Configure I2C clock and GPIO */ GPIO_StructInit(&GPIO_InitStructure);/* 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_StructInit(&I2C_InitStructure);
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) */
Timed(!I2C_CheckEvent(I2C1
, I2C_EVENT_MASTER_MODE_SELECT));/* Send device address for write */
I2C_Send7bitAddress(I2C1
, slaveAddress, I2C_Direction_Transmitter); /* Test on EV6 and clear it */Timed(!I2C_CheckEvent(I2C1
, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));where:
#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,Timed(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
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,
David
