Советую детальку (eeprom fram)

Тема в разделе "Посоветуйте детальки", создана пользователем ostrov, 10 ноя 2018.

  1. ostrov

    ostrov Гуру

    На а, если что, всегда под рукой должно быть такое.
     
  2. save.l

    save.l Гик

    разбил чтение\запись на блоки:
    Код (C++):

    void Fun_FM24C_write(byte disk, byte startAddress, void *data, unsigned int len) {
      byte buf = 32;
      byte count_blok = len / buf;
      byte ostat_blok = len % buf;
      // производим запись блоками размерностью buf
      for(int i = startAddress; i < count_blok; i++){        
            Wire.beginTransmission(disk);
            Wire.write(i * buf);
            Wire.write(((byte*)data + (i * buf)), buf);
            Wire.endTransmission();
            delay(1);
      }
      // производим запись остатка
      if (ostat_blok > 0){
            Wire.beginTransmission(disk);
            Wire.write(count_blok * buf);
            Wire.write(((byte*)data + (count_blok * buf)), ostat_blok);
            Wire.endTransmission();
            delay(1);
      }
    }

    int Fun_FM24C_read(byte disk, byte startAddress, void *data, unsigned int len) { // возвращаем кол-во считанных байт
      byte rdata;
      byte *p;
      byte buf = 32;
      byte count_blok = len / buf;
      byte ostat_blok = len % buf;
      // производим чтение блоками размерностью buf
      for(int i = startAddress; i < count_blok; i++){
            Wire.beginTransmission(disk);
            Wire.write(i * buf);
            Wire.endTransmission();
            Wire.requestFrom(disk, buf);
            for (rdata = i * buf, p = ((byte*)data + (i * buf)); Wire.available() && rdata < len; rdata++, p++) {
              *p = Wire.read();
            }
      }
      // производим чтение остатка
        if (ostat_blok > 0){
            Wire.beginTransmission(disk);
            Wire.write(count_blok * buf);
            Wire.endTransmission();
            Wire.requestFrom(disk, ostat_blok);
            for (rdata = count_blok * buf, p = ((byte*)data + (count_blok * buf)); Wire.available() && rdata < len; rdata++, p++) {
              *p = Wire.read();
            }
      }
      return (rdata);
    }
     
     
    Последнее редактирование: 13 окт 2019
    ostrov и Андрей Ерошин нравится это.
  3. b707

    b707 Гуру

    а зачем? - эта память поддерживает последовательную запись и чтение, нет никакого смысла разбивать поток на блоки. А делать каждый раз BeginTransmission() и End - вообще пустой расход тактов процессора
     
  4. save.l

    save.l Гик

    затем что, i2c не позволяет записать\считать разом, например структуру размером более 32 байт
     
  5. b707

    b707 Гуру

    ну так во-первых - 32 байта, а не 16, а во-вторых размер буфера i2c можно увеличить

    В общем, если б Вы в коде вместо жестко забитой цифры 16 использовали константу размер буфера - он был бы более логичным. Но в принципе, я вообще не понимаю, зачем такое выкладывать - это частное решение конкретно под ваши нужды, кому нужно, он для себя напишет сам
     
  6. save.l

    save.l Гик

    сколько не читал, такой подход не советуют
    изменил

    ни на что не претендую. как новичок столкнулся с этой задачей. поделился
     
    Последнее редактирование: 13 окт 2019
  7. Не совсем понятно зачем делать
    Код (C++):
    Wire.write(count_blok * buf);
    перед
    Код (C++):
    Wire.requestFrom(disk, ostat_blok);
    .

    Может кто пояснить?
     
  8. b707

    b707 Гуру

    это адрес стартовой ячейки, откуда начинается чтение.
    Вы бы сначала всю ветку прочитали, она не такая большая. Тут на все "почему" есть ответы
     
  9. Otto

    Otto Нерд

    Здравствуйте. Разбираюсь как работает структура памяти в FRAM. И дорабатываю для себя библиотеку одного человека с гитхаба для микросхемки: FM24C04B-G с памятью 4-Kbit (512x8). И вот правильно ли я понимаю следующее определение:

    Пример использования библиотеки FRAM на микросхеме: FM24C04B-G
    Микросхема имеет на борту 4-Kbit(512 x 8).
    Другими словами, имеем 512 ячеек памяти, по 8 бит данных в каждой ячейке.
    I2C адреса страниц выставляются комбинированием контактов A1 и A2 (смотреть в даташите).

    Возможные комбинации адресов:
    Страница1 0x50 // первая страницы FM24C04B-G
    Страница2 0x51 // вторая страницы FM24C04B-G
    Страница3 0x52 //...
    Страница4 0x53
    Страница5 0x54
    Страница6 0x55
    Страница7 0x56
    Страница8 0x57

    Адрес страницы 1-битный(8бит), поэтому есть 2 страницы из 256 локаций.
    Итого получается 512 ячеек на каждую страницу, а страниц у нас 8.
     

    Вложения:

    • FM24C04B-G.pdf
      Размер файла:
      467,4 КБ
      Просмотров:
      172
  10. b707

    b707 Гуру

    все перепутали
    Правильно - адрес ячейки на странице 1-байтный, (а не 1битный) поэтому число ячеекк на странице - 256
    Обьем памяти у вас 4кбит, что тоже самое как 512 байт. Соответственно у вас память организована из двух страниц (512/ 256 = равно 2)
     
  11. Otto

    Otto Нерд

    Про "1-битный(8бит)...." - это я незаметил и перепутал слова, но подразумевал как раз однобайтный :) Спасибо за замечания!

    Получается так, что по этой микросхеме имеем 8 комбинаций с I2C адресами, но независимо какой адрес мы выберем (к примеру 0x50 или 0x55), имеем во всех случаях всего 2 страницы по 256 байт на каждой.

    Правильно ли я понимаю данный пример:
    Если запишем по I2C адресу 0x50 байтовое число , например "11" на первую страницу и в первый сектор, сменим перемычкой I2C адрес к примеру на 0x55 и прочитаем с первой страницы и первого сектора байт, то получим то же самое число "11", что записали раньше?
     
  12. b707

    b707 Гуру

    неправильно.
    Комбинаций не 8, а только 4
    Каждая из страниц по 256 байт ИМЕЕТ СВОЙ АДРЕС.
    Соответвенно для ФРАМ емкостью 4к бит у нас есть только 4 варианта адресов. а не восемь. смотрите в даташите - пинов для выбора адреса всего два А1 и А2. что дает 4 комбинации.
    Соответственно. вы можете выбрать 4 варианта адреса - 0х50, 0х52 0х54 и 0х56
    Это будет адрес первой страницы. Адрес второй получается автоматически прибавлением единицы к первому

    Совет - найдите даташит именно для своей микросхемы, иначе будете путаться, поскольку принцип выбора адресов для ФРАМ разного размера - разный
     
    Andrey12 нравится это.
  13. Otto

    Otto Нерд

    Теперь понял как это работает. Спасибо за разъяснения! И отпал вопрос почему I2C сканер находит 2 адреса на эту микросхему.
    В гугле не смог найти дельные статьи с объяснение как в этом разбираться или просто неправильно формулировал вопросы.
     
  14. Otto

    Otto Нерд

    Нашёл на гитхабе вот такую самопальную, простенькую библиотеку от автора B@tto.
    Эта библиотека мне понравилась простатой, удобством и написана конкретно под данную FRAM - FM24C04B, но там не было реализована возможность записывать и читать тип данных float. Добавил такую возможность, так же спасибо за помощь sadman41 с сайта arduino.ru.
    Библиотека умеет писать/читать следующие типы данных: Byte, Integer, Long, Float.

    За одно немного изучал принцип для понимания как работает FRAM и её объёмами, страница.....

    P.S. Библиотека не учитывает то, что было написано.
    Это означает, что, например, если вы напишете длинное число на странице = 0, адрес = 20, а после того, как вы напишете целое число на странице = 0 и адресе = 22, ваше длинное число будет повреждено, потому что вы перезаписали его последние два байта.

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

    Вложения:

    Последнее редактирование: 13 авг 2021
  15. Un_ka

    Un_ka Гуру

    А почему не на Гитхабе?
     
  16. Otto

    Otto Нерд

    Un_ka нравится это.