2017-12-21 04:32 AM
Hi,
For few days I am trying to send some data over I2C2 interface. I am working with stm32f072-nucleo board.
Unfortunately something goes wrong because stm32 send only address with no data which should be transfered.
My configuration:
static void
MX_I2C2_Init(void
){LL_I2C_InitTypeDef
I2C_InitStruct;
LL_GPIO_InitTypeDef
GPIO_InitStruct;
/**I2C2 GPIO Configuration
PB10 ------> I2C2_SCL
PB11 ------> I2C2_SDA
*/
GPIO_InitStruct.
Pin
=LL_GPIO_PIN_10
;
GPIO_InitStruct.
Mode
=LL_GPIO_MODE_ALTERNATE
;
GPIO_InitStruct.
Speed
=LL_GPIO_SPEED_FREQ_HIGH
;
GPIO_InitStruct.
OutputType
=LL_GPIO_OUTPUT_OPENDRAIN
;
GPIO_InitStruct.
Pull
=LL_GPIO_PULL_UP
;
GPIO_InitStruct.
Alternate
=LL_GPIO_AF_1
;
LL_GPIO_Init(
GPIOB
,
&GPIO_InitStruct);
GPIO_InitStruct.
Pin
=LL_GPIO_PIN_11
;
GPIO_InitStruct.
Mode
=LL_GPIO_MODE_ALTERNATE
;
GPIO_InitStruct.
Speed
=LL_GPIO_SPEED_FREQ_HIGH
;
GPIO_InitStruct.
OutputType
=LL_GPIO_OUTPUT_OPENDRAIN
;
GPIO_InitStruct.
Pull
=LL_GPIO_PULL_UP
;
GPIO_InitStruct.
Alternate
=LL_GPIO_AF_1
;
LL_GPIO_Init(
GPIOB
,
&GPIO_InitStruct);
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(
LL_APB1_GRP1_PERIPH_I2C2
);
// LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_SYSCLK);
LL_RCC_SetI2CClockSource(
LL_RCC_I2C1_CLKSOURCE_SYSCLK
);
/**I2C Initialization
*/
I2C_InitStruct.
PeripheralMode
=LL_I2C_MODE_I2C
;
I2C_InitStruct.
Timing
=0x2000090E
;
//0x00901850;//0x2000090E;
I2C_InitStruct.
AnalogFilter
=LL_I2C_ANALOGFILTER_DISABLE
;
//LL_I2C_ANALOGFILTER_ENABLE;
I2C_InitStruct.
DigitalFilter
=0
;
I2C_InitStruct.
OwnAddress1
=0
;
I2C_InitStruct.
TypeAcknowledge
=LL_I2C_ACK
;
I2C_InitStruct.
OwnAddrSize
=LL_I2C_OWNADDRESS1_7BIT
;
// LL_I2C_Disable(I2C2);
LL_I2C_Init(
I2C2
,
&I2C_InitStruct);
//
LL_I2C_EnableAutoEndMode(
I2C2
);
LL_I2C_SetOwnAddress2(
I2C2
,
0
,
LL_I2C_OWNADDRESS2_NOMASK
);
LL_I2C_DisableOwnAddress2(
I2C2
);
}int
main(void
){ LL_Init();
SystemClock_Config()
;
MX_GPIO_Init()
;
MX_I2C2_Init()
;
i2c_transfer_init(
0xBB
);
}void
i2c_transfer_init(
uint32_t
slave_addr)
{uint8_t
test[
10
] = {
0xAA
}
;
LL_I2C_HandleTransfer(
I2C2
,
slave_addr
,
LL_I2C_ADDRSLAVE_7BIT
,
2
,
LL_I2C_MODE_AUTOEND
,
LL_I2C_GENERATE_START_WRITE
)
;
// while(!(LL_I2C_IsActiveFlag_TXE(I2C2))); // waits forever
LL_I2C_TransmitData8(
I2C2
,
test[
0
])
;
LL_I2C_TransmitData8(
I2C2
,
test[
0
])
;
}I am attaching oscillograms which shows that only address is being send.
Thanks in advanced for help!
#i2c-problem #nucleo-f072 #stm32f0722017-12-21 05:18 AM
Signal is very ugly, rising edges are too weak. Check pull-up resistors. it is likely that the slave devices does not answer at all because it is unable to recognize its address.
When this will be fixed, double check that the address send for the transfer is really 0xBB. This 0xbb looks like a seven bit address already shifted left by one bit, make sure that the transfer function does not shift once again.
2018-01-02 05:41 AM
He is right. The rising edges are not sharp enough. Pullup resistors are either too large or non-existent. Signals don't need to be square but the tops should start to flatten out. Byte being sent is a write to 0xBA. On the 9th clock is the ACK (acknowledge) bit is 1 (NAK'd) meaning that the slave is not present, the signals are not good enough, or the address (0xBA) is incorrect. Some manufacturers specify the 7-bit address right justified (shifted) which is confusing. Sometimes you have to look at the timing diagrams in the datasheet to know for sure which they mean.