AnsweredAssumed Answered

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

Question asked by kandaraj.Nirmalaa on Apr 3, 2017
Latest reply on Apr 3, 2017 by Imen D

#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 

Outcomes