cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to perform read in AT24c256

Vishnudev  K
Associate II
Posted on April 08, 2018 at 12:36

Iam trying to write and read to eeprom . I think i have wrote , in the code i have commended out the write function.

Now am trying to read, but the rxne is alwys reset

Please tell the correct usage of the functions for read and write

/**********************************************

*/

/* Includes ------------------------------------------------------------------*/

#include 'main.h'

#include 'stm32f0xx_rcc.h'

#include 'stm32f0xx_gpio.h'

#include 'stm32f0xx_i2c.h'

/** @addtogroup STM32F0xx_StdPeriph_Templates

* @{

*/

/* Private typedef -----------------------------------------------------------*/

#define EEPROM_ADDRESS_R 0xA1

#define EEPROM_ADDRESS_W 0xA0

#define EE_WRITE_ADDRESS 0x52AB

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

uint8_t databuffer=0xAA;

char dataread;

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

/**

* @brief Main program.

* @param None

* @retval None

*/

int main(void)

{

/*!< At this stage the microcontroller clock setting is already configured,

this is done through SystemInit() function which is called from startup

file (startup_stm32f0xx.s) before to branch to application main.

To reconfigure the default setting of SystemInit() function, refer to

system_stm32f0xx.c file

*/

/* Add your application code here

*/

//clocks enable

RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC,ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;

GPIO_Init(GPIOC,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;

GPIO_Init(GPIOC,&GPIO_InitStructure);

I2C_DeInit(I2C2);

GPIO_InitTypeDef I2C_GPIO_CONGIG;

I2C_GPIO_CONGIG.GPIO_Pin=GPIO_Pin_10;

I2C_GPIO_CONGIG.GPIO_Mode=GPIO_Mode_AF;

I2C_GPIO_CONGIG.GPIO_OType=GPIO_OType_OD;

I2C_GPIO_CONGIG.GPIO_PuPd=GPIO_PuPd_NOPULL;

I2C_GPIO_CONGIG.GPIO_Speed=GPIO_Speed_2MHz;

GPIO_Init(GPIOB,&I2C_GPIO_CONGIG);

//SCL

I2C_GPIO_CONGIG.GPIO_Pin=GPIO_Pin_11;

GPIO_Init(GPIOB,&I2C_GPIO_CONGIG);

//SDA

GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_1);

GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_1);

//I2C config

I2C_InitTypeDef I2C_InitStructure;

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;

I2C_InitStructure.I2C_DigitalFilter = 0x00;

I2C_InitStructure.I2C_OwnAddress1 = 0x00;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_Timing = 0x00201D2B;

// I2C_InitStructure.I2C_Timing = 0x1042C3C7;

I2C_Init(I2C2,&I2C_InitStructure);

//I2c enable

I2C_Cmd(I2C2,ENABLE);

//I2C_GenerateSTART(I2C2,ENABLE);

while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) == SET)

{}

/* Configure slave address, nbytes, reload and generate start */

I2C_TransferHandling(I2C2, EEPROM_ADDRESS_W, 2, I2C_Reload_Mode, I2C_No_StartStop);

I2C_GenerateSTART(I2C2,ENABLE);

/* Wait until TXIS flag is set */

while(I2C_GetFlagStatus(I2C2, I2C_ISR_TXIS) == RESET)

{

}

/* Send MSB of memory address */

I2C_SendData(I2C2, (uint8_t)((EE_WRITE_ADDRESS & 0xFF00) >> 8));

/* Wait until TXIS flag is set */

while(I2C_GetFlagStatus(I2C2, I2C_ISR_TXIS) == RESET)

{

}

/* Send LSB of memory address */

I2C_SendData(I2C2, (uint8_t)(EE_WRITE_ADDRESS & 0x00FF));

/* Wait until TCR flag is set */

while(I2C_GetFlagStatus(I2C2, I2C_ISR_TCR) == RESET)

{GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET);

}GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET);

//WRITE

// I2C_TransferHandling(I2C2, EEPROM_ADDRESS_W, 1, I2C_SoftEnd_Mode, I2C_No_StartStop);

//

// while(I2C_GetFlagStatus(I2C2, I2C_ISR_TXIS) == RESET)

// {

//

// GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);

// }

// GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);

//

// I2C_SendData(I2C2, databuffer);

//

//READ

I2C_SlaveAddressConfig(I2C2,EEPROM_ADDRESS_W);

I2C_ReloadCmd(I2C2,DISABLE);

I2C_AutoEndCmd(I2C2,ENABLE);

I2C_NumberOfBytesConfig(I2C2,1);

I2C_MasterRequestConfig(I2C2,I2C_Direction_Receiver);

//Here i tried below function..it also didnt work//PLEASE HELP HERE

//I2C_TransferHandling(I2C2, EEPROM_ADDRESS_R, 1, I2C_SoftEnd_Mode, I2C_No_StartStop);

I2C_GenerateSTART(I2C2,ENABLE);

while(I2C_GetFlagStatus(I2C2, I2C_ISR_RXNE) == RESET)

{GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);

}

GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);

/* Read data from RXDR */

dataread= I2C_ReceiveData(I2C2);

I2C_GenerateSTOP(I2C2,ENABLE);

/* Wait until STOPF flag is set */

while(I2C_GetFlagStatus(I2C2, I2C_ISR_STOPF) == RESET)

{GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET);

} GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET);

/* Clear STOPF flag */

I2C_ClearFlag(I2C2, I2C_ICR_STOPCF);

while (1)

{

}

}

#ifdef USE_FULL_ASSERT

/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t* file, uint32_t line)

{

/* User can add his own implementation to report the file name and line number,

ex: printf('Wrong parameters value: file %s on line %d\r\n', file, line) */

/* Infinite loop */

while (1)

{

}

}

#endif

/**

* @}

*/

Note: this post was migrated and contained many threaded conversations, some content may be missing.
9 REPLIES 9
Posted on April 08, 2018 at 16:26

Can we please not open multiple threads on materially the same topic

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

Pretty sure the F0 doesn't require the address shift. The 0x50 looks to be appropriate. Review the EEPROM I2C example code provided in the F0 SPL

I would suggest using a scope or logic-analyzer and confirming the signalling of address on the bus, and if the device responds with an ACK.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 08, 2018 at 16:31

what do you mean by addres shifting?

Posted on April 08, 2018 at 16:44

Where the 7-bit Address is situated. On the bus it is the high order bits, ie 0xA0 == 0x50 << 1

The examples for the F0 use 0x50, other STM32 families require you shift this. If you don't see the ACK on the bus it indicates no device recognizes the address you are using.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 09, 2018 at 09:42

dont know , but i have given as A0..

Now am able to write and read, but i cannot perform read immediatly..but if i give a delay, it works.

can u tell which flag i have to check before reading

Posted on April 09, 2018 at 10:30

Now am able to write and read, but i cannot perform read immediatly..but if i give a delay, it works.

Of course, a write operation on EEPROM/Flash takes milliseconds.

can u tell which flag i have to check before reading

Consult the datasheet of the 24C256.

There used to be a status register with a busy flag, which you will need to read (via I2C access).

And since write (and erase) operations are tend to depend on temperature and the individula chip, don't use hard-coded delays.

Posted on April 09, 2018 at 10:40

Acknowledge Polling: Once the internally-timed write cycle has started and the EEPROM inputs are disabled,

acknowledge polling can be initiated. This involves sending a Start condition followed by the device address

word. The Read/Write bit is representative of the operation desired. Only if the internal write cycle has

completed will the EEPROM respond with a zero, allowing the read or write sequence to continue.

This is what i saw in datasheet. So after writing data , i got the stop bit.. You are telling that , after getting stop, still internaly eeprom is busy writing??

Can you tell how to check that, from the details i gave from datasheet.

Posted on April 09, 2018 at 10:56

This the code used.. But its going infinite

//for checking wheather eeprom has completed writing

I2C_TransferHandling(I2C2, EEPROM_ADDRESS_W, 0, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);

do

{

/* Clear NACKF */

I2C_ClearFlag(I2C2, I2C_ICR_NACKCF | I2C_ICR_STOPCF);

/* Generate start */

I2C_GenerateSTART(I2C2, ENABLE);

}

while(I2C_GetFlagStatus(I2C2, I2C_ISR_NACKF) != RESET);

/* Clear STOPF */

I2C_ClearFlag(I2C2, I2C_ICR_STOPCF);
Posted on April 09, 2018 at 11:09

Seems this part is old-school, and has no status register.

Acknowledge polling then means, the device will only return a (positive) acknowledge if the write operation finished.

I don't do Cube code, but it shouldn't be difficult.

Just cycle for an acknowledge after the write had been started.

I would use a read, perhaps on the address written.

Some kind of time-out might be helpful, in case of errors.

Posted on April 09, 2018 at 11:14

I dont use cubex ..This is some basic library function.

Its going in infinite..

Can you tell how to start addressing and all, if u not using cubemx functions