Skip to main content
Graduate
December 6, 2024
Question

data saved on external EEPROM SPI 25LC020A are not read correctly

  • December 6, 2024
  • 1 reply
  • 707 views

I can write and read byte, float or text on the eeprom. And I was thinking that is Ok with the processes of wiriting and reading. But when I tried that with the group of data, it appeared that something is wrong. It means that when I first write goup of data, fx seven bytes and then I try read them, it appears that only about half of them are correct. Fx:

bytes written:

Test byte to write into EEPROM: spi_buf = 0xA0
Test byte to write into EEPROM: spi_buf = 0xA1
Test byte to write into EEPROM: spi_buf = 0xA2
Test byte to write into EEPROM: spi_buf = 0xA3
Test byte to write into EEPROM: spi_buf = 0xA4
Test byte to write into EEPROM: spi_buf = 0xA5
Test byte to write into EEPROM: spi_buf = 0xA6

Bytes read:

Test byte read: 0xA0
Test byte read: 0xAF
Test byte read: 0xA2
Test byte read: 0x0
Test byte read: 0xA4
Test byte read: 0xA4
Test byte read: 0xA6

 

The same concerns other type of data.

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

The code written under stm32CubeIDE, board F103C8T6.

SPI configuration:

Full-Duplex Master

NSS Signal Type

Data Size - 8 Bits

First Bit - MSB First

Prescaler(for baud rate) - 64 (Baud Rate = 1.125 Mbits/s)

CPOL - LOW

CPHA - 1 Edge

// EEPROM SPI 25LC020A is 8 bit adressing (as read in datasheet).

Changing clock frequency or inserting delays for CS or transmitting functions did not help.

Does anyone know how to fix this ????

 

 

 

 

 

 

 

 

void EEPROM_Write_Byte(uint16_t address, uint8_t data)
{
 EEPROM_Write_Enable();
 uint8_t cmd[3];
 cmd[0] = 0x02; // command Write
 cmd[1] = (address >> & 0xFF;
 cmd[2] = address & 0xFF;
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
 HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY);
 HAL_SPI_Transmit(&hspi1, &data, 1, HAL_MAX_DELAY);
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
 HAL_Delay(10);
 EEPROM_Wait_For_Ready();
}

uint8_t EEPROM_Read_Byte(uint16_t address)
{
 uint8_t data;
 uint8_t cmd[3];
 cmd[0] = 0x03; // command Read
 cmd[1] = (address >> & 0xFF;
 cmd[2] = address & 0xFF;
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
 HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY);
 HAL_SPI_Receive(&hspi1, &data, 1, HAL_MAX_DELAY);
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
 return data;
}

 

 

 

 

 

 

 

 

 

 

 

 

void EEPROM_Write_Enable(void)
{
 uint8_t cmd = 0x06; // command Write Enable
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
 HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); 
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
 HAL_Delay(5);
}
void EEPROM_Write_Float(uint16_t address, float data) 
{
 EEPROM_Write_Enable(); 
 uint8_t cmd[3];
 cmd[0] = 0x02; // command Write
 cmd[1] = (address >> & 0xFF;
 cmd[2] = address & 0xFF;
 uint8_t* dataBytes = (uint8_t*)&data;
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
 HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY); // sending command and adress
 HAL_SPI_Transmit(&hspi1, dataBytes, sizeof(float), HAL_MAX_DELAY); // data send
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
 HAL_Delay(10); 
}

float EEPROM_Read_Float(uint16_t address) 
{
 float data;
 uint8_t cmd[3];
 uint8_t* dataBytes = (uint8_t*)&data;
 cmd[0] = 0x03; // command Read
 cmd[1] = (address >> & 0xFF;
 cmd[2] = address & 0xFF;
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS low
 HAL_SPI_Transmit(&hspi1, cmd, 3, HAL_MAX_DELAY); // sending command and adress
 HAL_SPI_Receive(&hspi1, dataBytes, sizeof(float), HAL_MAX_DELAY); // data read
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS high
 return data;
}

void saveFloats() {
 for (uint16_t i = 0; i < 7; i++) {
 uint16_t address = i * sizeof(float); 
 float value = (i + 1) * 3.14f; // value to save
 EEPROM_Write_Float(address, value); 
 EEPROM_Wait_For_Ready();
 HAL_Delay(100); 
 printf("%2d: Adress: %3d, float to save: %6.3f\n", i, address, value);
 }
 printf("\n");
}

void readFloats() {
 uint16_t address;
 float readValue;
 for (uint16_t i = 0; i < 7; i++) {
 address = i * sizeof(float); 
 readValue = EEPROM_Read_Float(address); 
 EEPROM_Wait_For_Ready();
 HAL_Delay(100); 
 printf("%2d: Adress: %3d, read float: %6.3f\n", i, address, readValue); 
 }
 printf("\n");
}

void save_read_float()
 {
	for (uint16_t i = 0; i < 7; i++)
	{
		 uint16_t address = i * sizeof(float); 
		 float value = (i + 1) * 3.14159f; // value to save
		 EEPROM_Write_Float(address, value); 
		 HAL_Delay(10); 
		 printf("%2d: Adres: %3d, float to save: %6.3f\n",i, address, value);
		 float readValue = EEPROM_Read_Float(address);
		 printf("%2d: Adres: %3d, read float directly after 10ms: %6.3f\n",i, address, readValue); 
	}	printf("\n\n");
 }

int main() 
{
 save_read_float();

 saveFloats();
 HAL_Delay(1000);
 readFloats();
 
 return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

    This topic has been closed for replies.

    1 reply

    Graduate II
    December 6, 2024

    >>As it is seen some error. Why?

    The addressing isn't working?

    You're driving the CS high too early, perhaps use TransmitReceive rather the Transmit which returns as soon as the TXE is cleared and you stuff the data in.

    Look at the signals with a scope or logic analyzer, to understand / confirm what's happening.

    Perhaps read the data sheet, isn't the 25LC020A a 2Kbit device (256 Byte) with 8-bit addressing, not 16-bit?

     

    zomAuthor
    Graduate
    December 6, 2024

    Accordin datasheet EEPROM SPI 25LC020A is 8 bit addressing.

    I have noticed on the osciloscope that when read data is not correct the MOSI signal for the corresponding writing data is not as should be, so Im not suprised that I cannot obtain the right result. The IC signal is absolutly correct. So I dont know how to force MOSI signal to be right. Somebody knows how to do it ????