Запись и чтение FRAM (FM24)

RS72
Offline
Зарегистрирован: 19.01.2021

Здравствуйте. Подскажите как решить такую задачу: хочу сохранять в памяти FM24CL64 имя пользователя и номер карты. С числами все понятно, они нормально сохраняются и читаются, а вот если записывать структуру со смешанными данными, то читает не то, что пишет. И вообще, правильно ли я мыслю: под номер выделяем например int (2 байта), под имя (например 10 букв требуется 20 байт(?)), соответственно первая запись в 0*22 ячейку, следующая в i*22 ячейку. Но ведь имя может быть короче, каким образом это решается, как мы должны понимать при чтении, что имя кончилось, а дальше не нужная информация?

#include <Wire.h>

#define FM24C 0x50 //Адрес устройства
struct program_data {
  byte thing1;
  char thing2[30];
  int thing3;
} dataBase;

void save_data(struct program_data *data_ptr) {
  byte *ptr = (byte *)data_ptr;

  for (size_t i = 0; i < sizeof(struct program_data); i++)
    EEPROM_WriteByte(i, ptr[i]);
}
void restore_data(struct program_data *data_ptr) {
  byte *ptr = (byte *)data_ptr;

  for (size_t i = 0; i < sizeof(struct program_data); i++)
    ptr[i] = EEPROM_ReadByte(i);
}

void EEPROM_WriteByte(byte Address, byte data)
{
  Wire.beginTransmission(FM24C);
  Wire.write((int)(Address >> 8));       // MSB
  Wire.write((int)(Address & 0xFF));     // LSB
  Wire.write(data);
  delay(5);
  Wire.endTransmission();
}

byte EEPROM_ReadByte(byte Address) {
  byte rdata = 0xFF;
  Wire.beginTransmission(FM24C);
  Wire.write((int)(Address >> 8));       // MSB
  Wire.write((int)(Address & 0xFF));     // LSB
  Wire.requestFrom(FM24C, 1);
  if (Wire.available()) rdata = Wire.read();
  Wire.endTransmission();
  return rdata;
}

void setup() {
  Wire.begin();
  delay(500);
  SerialUSB.begin(115200);
  SerialUSB.println("Serial...");
  delay(500);
}

void loop() {
  dataBase.thing1 = 111;
  strcpy(dataBase.thing2, "Admin");
  dataBase.thing3 = 22222;
  save_data(&dataBase);
  SerialUSB.println("Save...");
  delay(10000);
  
  restore_data(&dataBase);
  SerialUSB.println("Load...");
  SerialUSB.println(dataBase.thing1);
  SerialUSB.println(dataBase.thing2);
  SerialUSB.println(dataBase.thing3);
  delay(10000);
}

 

-Nord_Air-
Offline
Зарегистрирован: 21.08.2021

Когда строчные символы заканчиваются, ставится \0 Нуль символ. Он и определяет конец строки.  В случае с ардуино....   Мне приходилось порой нуль  проставлять "вручную"  чтобы потом функцией чтения его искать.

 Но то было давно, я был маленьким и глупым... Может оно всё как-то иначе.

rkit
Offline
Зарегистрирован: 23.11.2016

Забыл завершить первую передачу в EEPROM_ReadByte

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Писать во ФРАМ любые структуры по принципу (адрес данных, размер (в байтах) данных) не? Могу готовый код конкретно для ФРАМ кинуть, если сам не справишься

-Nord_Air-
Offline
Зарегистрирован: 21.08.2021

В EEPROM разумнее побайтно писать и читать так же. А пилить туда строку, а потом искать её конец.... Ну хз...

-Nord_Air-
Offline
Зарегистрирован: 21.08.2021

Rumata пишет:

Писать во ФРАМ любые структуры по принципу (адрес данных, размер (в байтах) данных) не? Могу готовый код конкретно для ФРАМ кинуть, если сам не справишься

 

 Дык размер заранее неизвестен, строка...

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

-Nord_Air- пишет:

 Дык размер заранее неизвестен, строка...

терминатор?

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

-Nord_Air- пишет:
В EEPROM разумнее побайтно писать и читать так же. А пилить туда строку, а потом искать её конец.... Ну хз...

Писать в АТ24 побайтно устанешь. По 5 миллис на транзакцию записи. С FM24 быстрее, то тоже так себе идея

-Nord_Air-
Offline
Зарегистрирован: 21.08.2021

Rumata пишет:

-Nord_Air- пишет:
В EEPROM разумнее побайтно писать и читать так же. А пилить туда строку, а потом искать её конец.... Ну хз...

Писать в АТ24 побайтно устанешь. По 5 миллис на транзакцию записи. С FM24 быстрее, то тоже так себе идея

 

 Побайтно, это организация записи.  Слать их можно пачкой.  Нужно просто заранее определиться с её длинной.

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

-Nord_Air- пишет:

 Побайтно, это организация записи.  Слать их можно пачкой.  Нужно просто заранее определиться с её длинной.

Блджад, ты о чем тогда до этого? Определи размер и пиши. В чем проблема то? 

-Nord_Air-
Offline
Зарегистрирован: 21.08.2021

Rumata пишет:

-Nord_Air- пишет:

 Побайтно, это организация записи.  Слать их можно пачкой.  Нужно просто заранее определиться с её длинной.

Блджад, ты о чем тогда до этого? Определи размер и пиши. В чем проблема то? 

Ну видимо в отсутствии функции, которая будет определять длину строки?

Хотя полагаю наперед, в динамическом изменении поля структуры, которое должно заноситься в ЕРРROM?

Ну посчитали мы. Одна строка 25 байт, следующая 38, следующая 5.
У человека вопрос. Как писать, ну абы как это понятно. Но вот как читать это из EPPROM вопрос первый. А как читать это цифровой шлак правильно, это уже вопрос второй ;)

Скажу заранее человек ждет заветных строчек кода, а не разглагольства.

Я не знаю, я не сталкивался :)))

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

-Nord_Air- пишет:
Как писать, ну абы как это понятно. Но вот как читать это из EPPROM вопрос первый. А как читать это цифровой шлак правильно, это уже вопрос второй ;)

А запомнить для потомков куда чО записал нужна особая одаренность? Ну, в смысле, адреса шлака хранить? Или Губернатор в крайнем случае...

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

пишите так, первый байт длина, за ним сама строка и т.д.

не хватит длины 255 символов, переходите на два байта, но это вряд ли.

-Nord_Air-
Offline
Зарегистрирован: 21.08.2021

Если всё организовано побайтно, то вопросов нет. Если в случае со строкой, кол-во байтов изменяется динамически, в зависимости от длинны строки. И ловить где там начало одной фамилии, а где конец другой, думаю будет проблематично или как минимум затруднительно.
Не знаю... Возможно потребуется применять кодировку. Например в первом байте указывать длину фамилии, кол-ве символов.... Не знаю

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

-Nord_Air- пишет:

Ну видимо в отсутствии функции, которая будет определять длину строки? [/quote]

 

А что strlen() уже тоже запретили?