Страница EEPROM вращается при записи на нее

Следующий код предназначен для чтения из последовательного порта и записи данных байт за байтом в 24LC01B EEPROM.

// 24LC01B PINS
// Контакт 1, A0: с плавающей запятой
// Контакт 2, A1: с плавающей запятой
// Контакт 3, A2: с плавающей запятой
// Контакт 4, VSS: GND
// Контакт 5, SDA: Arduino A4
// Пин 6, SCL: Arduino A5
// Контакт 7, WP: Запись/Защита = GND
// Контакт 8, VCC: +5


#include <Arduino.h>
#include <Wire.h>

// адрес шины I2C 24LC256 EEPROM;
// если более одного eeprom, то они будут иметь разные адреса (h/w настроены);
#define EEPROM_ADDR 0x50
byte m_addr = 0;

#define MAX_ADDRESS 128


byte eeprom_write(byte address, byte *data, byte len)
{  
    byte r = 0;
    for(byte i=0; i<len; )
    {
        Wire.beginTransmission(EEPROM_ADDR | m_addr);
        Wire.write(address + i); 
        byte l = len > 8 ? 8 : l;
        Wire.write(data+i, l);
        r |= Wire.endTransmission();
        delay(3);
        i += l;
    }
    return r;
}

byte eeprom_read(byte address, byte *data, byte len)
{
    Wire.beginTransmission(EEPROM_ADDR | m_addr);
    Wire.write(address);
    byte tr = Wire.endTransmission();
    if(tr)
        return tr;

    Wire.requestFrom((uint8_t)(EEPROM_ADDR | m_addr), len);
    byte avail = Wire.available();
    if(avail < len)
        return 0xFF;

    for(int i=0; i < len; i++)
    {
        // сохраняем данные в необработанном формате bcd
        data[i] = Wire.read();
    }
    return 0;
}

void setup()
{
    Wire.begin();
    Serial.begin(9600);
    delay(500);
    Serial.println("Type something to store in EEPROM");
}

byte i = 0;

void loop()
{
    if(Serial.available())
    {
        byte data = Serial.read();
        int rc = eeprom_write(i, &data, 1);
        if(rc==0)
        {
            Serial.print("EEPROM[0x");
            Serial.print(i, HEX);
            Serial.print("] = 0x");
            Serial.print(data, HEX);
            Serial.print(" (");
            Serial.print((char)data);
            Serial.print(")");
            Serial.println();

            Serial.println("Reading from EEPROM:");
            for(byte j=0;j<MAX_ADDRESS;j++)
            {
                if(byte rc=eeprom_read(j, &data, 1))
                {
                    Serial.print("Error in reading from EEPROM (rc=0x");
                    Serial.print(rc, HEX);
                    Serial.println(")");
                }
                else
                {
                    Serial.print(data, HEX);
                    Serial.print(' ');
                    if((j + 1) % 8 == 0 && j != MAX_ADDRESS - 1)
                        Serial.print("| ");
                }
            }
            Serial.println("");
        }
        else
        {
            Serial.println("Write error.");
        }
        i++;
    }
}

Каждый раз, когда я записываю один байт в EEPROM, я считываю данные из него. Результат меня немного разочаровал. Я понимаю, что 24LC01B имеет размер страницы 8 байт. Но мне непонятно, почему байты на странице чередуются каждый раз, когда я пишу в нее

Type something to store in EEPROM
EEPROM[0x0] = 0x61 (a)
Reading from EEPROM:
61 4 4F 0 80 0 80 4 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x1] = 0x62 (b)
Reading from EEPROM:
4 62 4 4F 0 80 0 80 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x2] = 0x63 (c)
Reading from EEPROM:
80 4 63 4 4F 0 80 0 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x3] = 0x64 (d)
Reading from EEPROM:
0 80 4 64 4 4F 0 80 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x4] = 0x65 (e)
Reading from EEPROM:
80 0 80 4 65 4 4F 0 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x5] = 0x66 (f)
Reading from EEPROM:
0 80 0 80 4 66 4 4F | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x6] = 0x67 (g)
Reading from EEPROM:
4F 0 80 0 80 4 67 4 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x7] = 0x68 (h)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x8] = 0x69 (i)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 69 4 4F 0 80 0 80 4 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x9] = 0x6A (j)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 6A 4 4F 0 80 0 80 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0xA] = 0x6B (k)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 80 4 6B 4 4F 0 80 0 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0xB] = 0x6C (l)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 0 80 4 6C 4 4F 0 80 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0xC] = 0x6D (m)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 80 0 80 4 6D 4 4F 0 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0xD] = 0x6E (n)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 0 80 0 80 4 6E 4 4F | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0xE] = 0x6F (o)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4F 0 80 0 80 4 6F 4 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0xF] = 0x70 (p)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 4F 0 80 0 80 4 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x10] = 0x71 (q)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 4F 0 80 0 80 4 70 | 71 4 4F 0 80 0 80 4 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 
EEPROM[0x11] = 0x72 (r)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 4F 0 80 0 80 4 70 | 4 72 4 4F 0 80 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF 

, 👍0

Обсуждение

Чтение кода и спецификаций последовательного EEPROM занимает много времени. Попробуйте это, и если это сработает, я дам более полный ответ: напишите все 8 байтов на странице., @st2000

@ st2000, на самом деле я пробовал записывать 8-байтовые данные, и все работало нормально. Нет проблем с этим. Проблема возникает, когда вы пишете меньше страницы (8 байт). Соответствует ли минимальный размер записи размеру страницы стандартным требованиям для EEPROM? Я не видел ничего подобного в даташитах., @ar2015

Неважно, пишете ли вы 1 байт или целую страницу. единственное, что важно, это то, что вы не пересекаете границу страницы во время письма., @theSealion


2 ответа


1

Глобальная переменная data — это байтовая переменная. Но в функции чтения и записи вы используете его как массив байтов (data[i] или 'data +i'). Это не нормально, но и не является ошибкой, если вы используете длину 1 ;-).

В вашей функции чтения вы выполнили так называемое действие случайного чтения, которое должно быть завершено сигналом STOP на шине I2C. Это может быть вызвано:

// ...

for(int i=0; i < len; i++)
{
    // сохраняем данные в необработанном формате bcd
    data[i] = Wire.read();
}

Wire.endTransmission(true);

return 0;

// ...

Это всего лишь предположение.

Запись отдельных байтов также должна заканчиваться условием STOP, но вы использовали

r |= Wire.endTransmission();

который не отправляет сигнал STOP.

Опять же вы можете форсировать это с помощью:

r |= Wire.endTransmission( true );

Я не мастер библиотеки Wire, поэтому я прочитал документацию по Arduino. Надеюсь, я правильно понял.

,

0

Ваша проблема

byte l = len > 8 ? 8 : л;

в функции eeprom_write().

Вы написали byte NumberOfBytes = len > 8 ? 8 : NumberOfBytes; и это приведет к неопределенному поведению.

И на будущее, если вы хотите записать более 1 байта, не важно, сколько байт вы записываете в блок, важно, чтобы все адреса находились на одной и той же странице eeprom.

((адрес / размер страницы) == ((адрес + длина) / размер страницы) должно быть true

,