Example code:
/* Includes ------------------------------------------------------------------*/ #include "stm32F10x.h" #include "stm32f10x_i2c.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define ClockSpeed 400000 #define I2C_SLAVE_ADDRESS7 0x74 #define PCF8535_FLAG_TIMEOUT ((uint32_t)0x1000) #define PCF8535_LONG_TIMEOUT ((uint32_t)(10 * sEE_FLAG_TIMEOUT)) /* Private macro -------------------------------------------------------------*/ /* Private consts ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ u32 count = 0; GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; /* Private function prototypes -----------------------------------------------*/ int main(void) { /* Enable GPIOx Clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE); /* Initialise GPIO port */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Enables the specified I2C peripheral. */ I2C_Cmd(I2C1, ENABLE); /* Initialise I2C */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x78; I2C_InitStructure.I2C_Ack = I2C_Ack_Disable ; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = ClockSpeed; I2C_Init(I2C1, &I2C_InitStructure); while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, 0x78, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED )); I2C_SendData(I2C1, I2C_SLAVE_ADDRESS7); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED )); I2C_SendData(I2C1, 0x01); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED )); // I2C_SendData(I2C1, 0x20); // while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED )); // I2C_SendData(I2C1, 0x09); // while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED )); I2C_GenerateSTOP(I2C1, ENABLE); /* main while */ while(1) { } }
The program gets into an endless loop on the line: while (! I2C_CheckEvent (I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
Debugged on the simulator. In the define: "STM32F10X_MD, USE_STDPERIPH_DRIVER"
stm32f10x_stdperiph_lib version V3.4.0 Interrupts are not used. I looked through all the documentation, but was not able to run the I2C.
Sorry for bad English.
PS: The country Russia and the U.S. flag. I missed something?
Attention!
Found an error in stm32f10x_i2c.c version V3.4.0 of 10/15/2010!
Function void I2C_Init (I2C_TypeDef * I2Cx, I2C_InitTypeDef * I2C_InitStruct) incorrectly fills register I2C_OAR1 - and specifically the field of ADD Make no mistake: the 10-bit mode, the address is written to bits [0 .. 9], and in 7-bit - in bits [1 .. 7]. and the library is done as follows:
I2Cx-> OAR1 = (I2C_InitStruct-> I2C_AcknowledgedAddress | I2C_InitStruct-> I2C_OwnAddress1);
The address is written with 0 bits, without any verification regime addressing.
When forming the address coincidence circuit waits generated odresa and addresses OAR1. After that forms the flags. And as the address in OAR1 stuck with 0 bits rather than 1 (ie, shifted by 1 bit), then the flags properly generating addresses will never lift a. And everything hangs until timeout.
Hi Sergei Danilin,
sorry but I did not understand the answer. Could you please write a response to this thread, what is wrong with the library and what I must do to make it run.
I have an ic whose address is 0x90 and I am using 7bitadressing. I have same problem like your problem.
thanks in advance.
He said 7-bit addresses should be stored in "in bits [1 .. 7]."
Note that bit 0 then is unused - so the claim is probably that the library forgot to shift the address one step left - or expected that the user should have already given a shifted address.