cancel
Showing results for 
Search instead for 
Did you mean: 

I need an example code for I2C programming to interface stm32f4 with at24c512 eeprom

Nirmalaa devi
Associate
Posted on April 03, 2017 at 08:53

#include 'stm32f4xx.h'

#include 'stdio.h'

#define SLAVE_ADDRESS 0xA0

unsigned char read;

char arr[3]= 'NV';

char data[3];

void delay_ms(int d)

{

int i,j;

for(i=0;i<d;i++)

for(j=0;j<32;j++);

}

void uart3_init()

{

RCC->AHB1ENR|=1<<1; // GPIOB clock enable for portB

RCC->APB1ENR|=1<<18; //USART3 clock enable

GPIOB->MODER|=1<<21|1<<23|1<<25; //Alternate func for Mode 10,11 &12

GPIOB->OTYPER|=0<<10|0<<11|0<<12; // output push_pull mode for 10,11,12

GPIOB->OSPEEDR|= 1<<18|1<<16; //1<<21|1<<23|1<<25; // fast speed mode 50MHz

GPIOB->PUPDR|= 1<<20|1<<22|1<<24; // pull_up mode for 10,11,12

GPIOB->AFR[1]|=1<<8|1<<9|1<<10|1<<13|1<<14|1<<12|1<<18|1<<17|1<<16; // alternate pin func for AF7 in usart3

USART3->CR1|=1<<13; // USART3 enable

USART3->BRR=0x16C; //115200

USART3->CR1|=1<<3|1<<2; // TX& RX enable for USART3

RCC->AHB1ENR |=1<<3; // GPIOD clk enable

GPIOD->MODER |= 1<<30|1<<28|1<<26|1<<24;

GPIOD->OSPEEDR |= 1<<31|1<<29|1<<27|1<<25;

}

/*========================================================================================*/

void I2C1_init()

{

RCC->APB1ENR |= ((uint32_t)0x00200000); //I2C1

RCC->AHB1ENR |= ((uint32_t)0x00000002); //GPIOB

GPIOB->MODER |=0x000A0280; //PB8& PB9

GPIOB->OTYPER|=0x00000300; // open drain

GPIOB->OSPEEDR|= 0x000A00C0; //0x00009000; //0x0000A0C0; // 50MHz speed

GPIOB->PUPDR |= 0x00050100; // pull_up

GPIOB->AFR[8 >> 0x03] |=0x004;

GPIOB->AFR[9 >> 0x03] |=0x040;

I2C1->CR1|= 0X405; // ACK& PE enable

I2C1->CR2 = 0X2A; // 42Mhz speed

I2C1->CCR = 0X8023; // Fast mode &dutycycle_2

I2C1->TRISE = 0x0D; // rise time

I2C1->OAR1 = 0X40A0 ; //ACK write mode

}

/*========================================================================================*/

void EEPROM_write(uint8_t addr)//,unsigned char data)

{

int i;

I2C1->CR1 |=((uint16_t)0x401); // send START condition

while((I2C1->SR2 &0x02)); /* While the bus is busy */

I2C1->CR1 |=((uint16_t)0x0100); // send START condition

delay_ms(5);

while(!((I2C1->SR1 & 0X01)&&(I2C1->SR2 & 0x03))); /* Test and clear in start condition,Busy flag and master mode */

I2C1->DR = SLAVE_ADDRESS; /* Send EEPROM address for write */

delay_ms(5);

while(!((I2C1->SR1 & 0x82)&&(I2C1->SR2 & 0x07))); /* Check Tx is empty or not 7 clear,Busy flag set and adrr byte for R/W */

I2C1->OAR1 |=0x00A0;

I2C1->DR = 0x00;

delay_ms(5);

for(i=0;i<3;i++)

{

while(!((I2C1->SR1 & 0x84)&&(I2C1->SR2 & 0x07))); /* master mode and Tx and Busy flag set and clear */

I2C1->DR = arr[i]; //data

delay_ms(5);

}

GPIOD->BSRRL|= 1<<12; // led 12

// I2C1->SR1 |= (uint16_t)~0x4000; //Clear AF flag

I2C1->CR1 =((uint16_t)0x0200); /*stop*/

//I2C1->CR1 = 0x601; /* I2C STOP condition*/

}

/*========================================================================================*/

void EEPROM_read(uint8_t addr)

{

int i=0;

I2C1->OAR1 |=0x00A1;

I2C1->CR1 |=((uint16_t)0x401); // send START condition

// uint8_t addrh=(addr&0xff00)>>8;

// uint8_t addrl= addr & 0x00ff;

while((I2C1->SR2 & 0x2)); /* While the bus is busy */

I2C1->CR1 |=((uint16_t)0x0100); // send START condition

delay_ms(5);

while(!((I2C1->SR1 & 0X01)&&(I2C1->SR2 & 0x03))); /* Test and clear in start condition,Busy flag and master mode */

I2C1->DR = SLAVE_ADDRESS; /* Send EEPROM address for write */

// delay_ms(5);

while(!((I2C1->SR1 & 0x82)&&(I2C1->SR2 & 0x07))); /* Check Tx is empty or not 7 clear,Busy flag set and adrr byte for R/W */

I2C1->DR = 0x00;

delay_ms(5);

while(!((I2C1->SR1 & 0x84)&&(I2C1->SR2 & 0x07))); /* master mode Tx and Busy flag set and clear */

I2C1->CR1 |=((uint16_t)0x0100); // send START condition

while(!((I2C1->SR1 & 0X01)&&(I2C1->SR2 & 0x03))); /* Test and clear in start condition,Busy flag and master mode */

// delay_ms(5);

I2C1->DR =0xA1;

while(!((I2C1->SR1 & 0X02)&&(I2C1->SR2 & 0x03))); /* Test and clear in start condition,Busy flag and master mode */

while(((I2C1->SR1 & 0x40)&&(I2C1->SR2 & 0x03)));/* Test and clear in start condition,Busy flag and master mode */

data[2]=I2C1->DR;

USART3->DR=I2C1->DR;

while(((I2C1->SR1 & 0x40)&&(I2C1->SR2 & 0x03))); /* Test and clear in start condition,Busy flag and master mode */

USART3->DR=I2C1->DR;

GPIOD->BSRRL |= 1<<14; //led 14

I2C1->CR1 &= (uint16_t)~((uint16_t)0x0400); /* Disable the acknowledgement */

I2C1->CR1 =((uint16_t)0x0200); /* Send STOP Condition */

}

/*========================================================================================*/

int main(void)

{

int i=0;

uart3_init();

printf('Init_Uart\r\n');

I2C1_init();

printf('I2C_Init..!\r\n');

EEPROM_write(0x00);

printf('I2C_write..!\r\n');

delay_ms(5);

EEPROM_read(0x00);

printf('I2C_read..!\r\n');

GPIOD->BSRRL |= 1<<15;//led 15

for(i=0;i<3;i++)

{

printf('%c',data[i]);

// while(!(USART3->SR & 0x80));

}

while(1)

{

// printf('Hello..!\r\n');

}

}

int fputc(int ch, FILE *f)

{

USART3->DR = ch;

while(!(USART3->SR & 0x80));

return ch;

}

#ifdef USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)

{while (1);}

#endif

============================================

this is my code but its not working i wont get any data 

1 REPLY 1
Imen.D
ST Employee
Posted on April 03, 2017 at 13:06

Hi,

You can find

I2C_EEPROM

example intheSTM32F4 standard peripheral package, that can help you:

STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Examples\I2C\I2C_EEPROM

Also, if you need HAL example within STM32CubeF4 firmware package, you have this running example showing how to use the I2C: STM32Cube_FW_F4_V1.0\Projects\STM32469I_EVAL\Examples\I2C\I2C_EEPROM

https://community.st.com/0D50X00009XkW1qSAF

Hope this helps you.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen