2016-01-05 12:18 AM
Hello!!
I test an access to eeprom by I2C Fastmode(polling) like following programs.But when writing a block to eeprom, it happens an I2C error.So I insert a delay time(1ms : _delay_ms(I2C_DLY)), and then it operates properly.I want to delete this delay time to get the best performance of I2C.How can I do it????void I2C_LowLevel_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; /* RCC Configuration */ /*I2C Peripheral clock enable */ RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE); /*SDA GPIO clock enable */ RCC_AHB1PeriphClockCmd(I2Cx_SDA_GPIO_CLK, ENABLE); /*SCL GPIO clock enable */ RCC_AHB1PeriphClockCmd(I2Cx_SCL_GPIO_CLK, ENABLE); /* Reset I2Cx IP */ RCC_APB1PeriphResetCmd(I2Cx_CLK, ENABLE); /* Release reset signal of I2Cx IP */ RCC_APB1PeriphResetCmd(I2Cx_CLK, DISABLE); /* GPIO Configuration */ /*Configure I2C SCL pin */ GPIO_InitStructure.GPIO_Pin = I2Cx_SCL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStructure); /*Configure I2C SDA pin */ GPIO_InitStructure.GPIO_Pin = I2Cx_SDA_PIN; GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStructure); /* Connect PXx to I2C_SCL */ GPIO_PinAFConfig(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_SOURCE, I2Cx_SCL_AF); /* Connect PXx to I2C_SDA */ GPIO_PinAFConfig(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_SOURCE, I2Cx_SDA_AF); /*I2C Struct Initialize */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE; I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /*I2C Initialize */ I2C_Init(I2Cx, &I2C_InitStructure); /* I2C ENABLE */ I2C_Cmd(I2Cx, ENABLE);}#define I2C_DLY 1000U8 I2C_Write(I2C_TypeDef *I2Cn, U8* buf, U32 nbyte){ __IO U32 Timeout = 0; /* Enable Error IT (used in all modes: DMA, Polling and Interrupts */ // I2Cx->CR2 |= I2C_IT_ERR; if (nbyte) {_delay_us(I2C_DLY);
Timed(I2C_GetFlagStatus(I2Cn, I2C_FLAG_BUSY)); // Intiate Start Sequence I2C_GenerateSTART(I2Cn, ENABLE); Timed(!I2C_CheckEvent(I2Cn, I2C_EVENT_MASTER_MODE_SELECT)); // Send Address EV5 I2C_Send7bitAddress(I2Cn, I2C_SLAVE_ADDRESS7, I2C_Direction_Transmitter); Timed(!I2C_CheckEvent(I2Cn, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // EV6 // Write first byte EV8_1 I2C_SendData(I2Cn, *buf++); while (--nbyte) { // wait on BTF Timed(!I2C_GetFlagStatus(I2Cn, I2C_FLAG_BTF)); I2C_SendData(I2Cn, *buf++); } Timed(!I2C_GetFlagStatus(I2Cn, I2C_FLAG_BTF)); I2C_GenerateSTOP(I2Cn, ENABLE);_delay_us(I2C_DLY);
Timed(I2C_GetFlagStatus(I2Cn, I2C_FLAG_STOPF));_delay_us(I2C_DLY);
} return TRUE; errReturn: return FALSE;}#ifdef FAST_I2C_MODE #define I2C_SPEED 400000 #define I2C_DUTYCYCLE I2C_DutyCycle_16_9 #else /* STANDARD_I2C_MODE*/ #define I2C_SPEED 100000 #define I2C_DUTYCYCLE I2C_DutyCycle_2#endif /* FAST_I2C_MODE*/The error happens when checking I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED.#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */2016-01-07 04:15 AM
I have solved this problem.
The slave device of I2C is AT24C1024 EEPROM.This device need the write cycle timing from a valid stop condition of a write sequence to the end of the internal clear/write cycle(max 10ms).So I insert a delay time(5ms) between a write access and the next access.Then I2C Communication is ok!!.Thanks