cancel
Showing results for 
Search instead for 
Did you mean: 

I2C protocol with STM32F303CB to interface EEPROM (AT24C512)

Vinod Kumar
Associate II

Hi,

I am using the STM32F303CB microcontroller and STM32CubeIDE (1.6.1) to write data in EEPROM - AT24C512 and read respectively.

I haven't used HAL libraries, I Wrote I2C_Init - To initialize I2C (Fast Mode 400 KHz), I2C Write and Read Functions.

Sometimes I see invalid data when read from EEPROM. I couldn't understand what went wrong (Initializing I2C, write and read).

Please help me to find where I went wrong.

Respective functions were attached.

Thanking you,

Vinod Kumar.

3 REPLIES 3
Sebastiaan
Senior

What exactly do you mean with "invalid data"? And which sequence leads to these issues? Your code does only show the interface but not the way you are using it. I didn't go through it in detail.

Did you make sure that your I2C reads and writes don't cross the 128-byte page boundaries? (see datasheets).

Also, do you take into account the eeprom write time (5 msec)?

Hi,

Usually, we reload runtime variables with values from EEPROM after a reset but very unfortunately expected values are not captured for all the variables. 80% of the data is valid and 20% of the reloaded values are invalid that's where I'm struct, this invalid data changes after each reset.

No, 128-byte boundaries are not crossed, I couldn't understand how does EEPROM write time effect as we handle transmit complete flag and stop flag while we write data to EEPROM.

I have added comments to my program which would help to understand my perception while programming

void I2C_Init(){
	RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;			// Enable I2C Peripheral
	RCC->AHBENR |= RCC_AHBENR_GPIOBEN;			// Enable Port B Clock
	RCC->CFGR3 |= RCC_CFGR3_I2C1SW_SYSCLK;		// System clock 72 Mhz
	GPIOB->MODER |= (uint32_t)((2<<12) | (2<<14));		// AF Mode for PB6 and PB7
 	GPIOB->AFR[0]|= (uint32_t)((4<<24) | (4<<28));		// I2C Function PB6 (SCL) and PB7 (SDA)
	GPIOB->OTYPER |= (uint32_t)((1<<6)|(1<<7));		// Output Open Drain
	GPIOB->OSPEEDR |= (uint32_t)((3<<12)|(3<<14));	// High Speed
	GPIOB->PUPDR |= (uint32_t)((1<<12)|(1<<14));		// Pull-Up Enable
 	I2C1->CR1 &= ~(I2C_CR1_PE);						// Disable I2C Peripheral
	Delay_ms(1);
	I2C1->CR1 |= I2C_CR1_ANFOFF;					// Disable ANF - Analog Noise Filter
	I2C1->CR1 &= (uint32_t)~(I2C_CR1_DNF_Msk);		// Disable DNF - Digital Noise Filter
	I2C1->CR1 &= ~(I2C_CR1_NOSTRETCH);				// Disable No Stretch
	I2C1->TIMINGR = 0x10EA142D;	                                // 72mhz (8 Mhz external crystal PLL_MUL9)
       I2C1->CR1 |= I2C_CR1_PE;						        // Enable I2C Peripheral
	UART3_SendString("I2C Initialized\n");
}

Hi Vinod,

I'm typically using the HAL drivers so I won't go through the whole read/write procedure. Given that most of the data is correct, you are probably using the correct procedure.

I think it would still be valuable to get better insight into which data is invalid... There should probably be some correlation or logic. For example, data that was last written, or last byte of the read/write transfer, or anything else. Is it always the same data that gets corrupted?

It should be easy to write a test program that starts with a random array, copies that array into eeprom, reads it out again and compares it with the default values.

Also, is the EEPROM effectively powered-down? If so, you must be fully sure that all writes have been stored (hence my question on e.g. 5 msec write time).