0

Hello I have two simple function to write value to EEPROM, but this don't work correctly. What am i doing wrong something with the conversion?

HAL_StatusTypeDef writeEEPROMByte(uint32_t address, uint8_t data) {
  HAL_StatusTypeDef  status;
  address = address + EEPROM_BASE_ADDRESS;
  HAL_FLASHEx_DATAEEPROM_Unlock();  //Unprotect the EEPROM to allow writing
  status = HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_BYTE, address, data);
  HAL_FLASHEx_DATAEEPROM_Lock();  // Reprotect the EEPROM
  return status;
  }

uint8_t readEEPROMByte(uint32_t address) {
  uint8_t data = 0;
  address = address + EEPROM_BASE_ADDRESS;
  data = *(__IO uint32_t*)address;
  return data;
  }

void saveToEEPROM (uint32_t address, float data)
{
    uint8_t *array;
    array = (uint8_t*)(&data);
    for(uint32_t i=0;i<4;i++) //float to array of uint8_t
    {
        writeEEPROMByte(address, array[i]);
    }
}

float loadFromEEPROM (uint32_t address)
{
    float value = 0;
    uint8_t data[3];
    for(uint32_t i=0;i<4;i++) //float to array of uint8_t
    {
        data[i] = readEEPROMByte(i+address);
    }
    value = *(float *)(&data);
    return value;
}

Output for float is 64.00 or 65-70 for bigger numbers

Thanks for answers. I edited functions and change to double precision because I using atof(). But still I don't have good readout, data[7-i] = readEEPROMByte(i+address); Give better results e.g. save - read 2 - 64, 3 - 2112, 4 - 4160,

void saveConfigToEEPROM (uint32_t address, double data)
{
    uint8_t *array;
    array = (uint8_t*)(&data);
    for(int i=0;i<8;i++) //float to array of uint8_t
    {
        writeEEPROMByte(address+i, array[i]);
    }
}

double loadConfigFromEEPROM (uint32_t address)
{
    double value = 0;
    uint8_t data[8];
    for(int i=0;i<8;i++) //float to array of uint8_t
    {
        data[i] = readEEPROMByte(address+i);
    }
    value = *(double *)(&data);
    return value;
}
dmvs
  • 1
  • 2
  • (1) The code always write to the same EEPROM address but reads form different addresses. (2) 4 bytes are read but stored in a buffer of 3 bytes. (3) Pointer is taken from a byte aligned buffer. But several ARM cpus required floats to be double word aligned. – Codo Apr 17 '21 at 19:06

1 Answers1

0

In the loop in function saveToEEPROM you overwrite the same address repeatedly.

In the loop in loadFromEEPROM you read 4 bytes from 4 different addresses but try to save them in a buffer 3 bytes long.

Also, in readEEPROMByte you cast the address to uint32_t pointer, read a uint32_t and then return it as a uint8_t. This could be a misaligned read, which might be fine on this platform (you don't specify exactly which part you are using) but to be on the safe side and to make the code easier to read I would just do a byte read (cast to uint8_t pointer).

Similarly casting the array of bytes to float pointer in loadFromEEPROM is not good practice, but again might still be alright.

Tom V
  • 4,827
  • 2
  • 5
  • 22