Проблемы чтения и записи внешнего EEPROM: ненужные значения в коммуникации I2C
У меня есть контроллер ESP32, и я использую AT24C1024 для связи. В моём коде я пытаюсь обратиться к внешней памяти EEPROM в позициях записи данных от 0 до 10000, где данные позиции = '1'. Однако при чтении данных из позиции '1' иногда возникают ненужные значения, такие как 0, 255 или старые записанные значения. Я уже пробовал менять тактовую частоту с помощью Wire.setClock(100000) и несколько раз записывал данные в эту ячейку, но эти изменения не решили проблему.
#include <Wire.h>
#define EEPROM_ADDR 0x50
#define SDA_PIN 21
#define SCL_PIN 22
#define DATA_LIMIT 10000
#define VALUE 1
void setup() {
Serial.begin(115200);
// Wire.begin(SDA_PIN, SCL_PIN);
Wire.begin();
for (uint16_t i = 0; i < DATA_LIMIT; i++) {
writeEEPROM(i, VALUE);
}
for (uint16_t i = 0; i < DATA_LIMIT; i++) {
uint8_t value = readEEPROM(i);
Serial.print(i);
Serial.print(" -> ");
Serial.println(value);
delay(30);
}
Serial.println("End");
}
void loop() {
}
void writeEEPROM(uint16_t memAddress, uint8_t data) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write((int)(memAddress >> 8));
Wire.write((int)(memAddress & 0xFF));
Wire.write(data);
uint8_t result = Wire.endTransmission();
if (result != 0) {
Serial.print("'W'- F : ");
}
delay(10);
}
uint8_t readEEPROM(uint16_t memAddress) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write((int)(memAddress >> 8)); // MSB of memory address
Wire.write((int)(memAddress & 0xFF)); // LSB of memory address
Wire.endTransmission();
Wire.requestFrom(EEPROM_ADDR, 1);
if (Wire.available()) {
return Wire.read();
}
return 0;
}
@Gopal, 👍1
1 ответ
Wire.beginTransmission(EEPROM_ADDR);
Хотя этот код может работать при адресации первой страницы памяти, однако, если вы внимательно прочитаете техническое описание в разделе Адресация устройств и Рисунок 7 Адресация устройств,
| 1 | 0 | 1 | 0 | 0 | A1 | Pg | R/W |
MSB LSB
Адресация I2C включает бит адреса страницы памяти и состояние вывода A1. Поэтому, если предположить, что A1 равен 0 при внутреннем подтягивании вниз или отсутствии аппаратного обеспечения, правильная адресация должна быть такой.
Wire.beginTransmission((uint8_t)(EPROM_ADDR | (uint8_t) (dataAddress >> 16));
Сама библиотека Wire будет отвечать за преобразование 7-битной адресации I2C в 8-битную адресацию I2C и бит чтения/записи.
Кстати, хотя код типа Wire.write((int)(memAddress >> 8)); может быть использован компилятором, но поскольку Wire.write() принимает в качестве параметра аргумент uint8_t, преобразование типа должно быть (uint8_t) (memAddress >> 8) вместо (int) (memAddress >> 8).
- Как выбрать альтернативные контакты I2C на ESP32?
- I2C связь между Arduino Uno и Nodemcu32-s (ESP32)
- PN532 не обнаруживает RFID-карту при подключении к ESP32 в режиме I2C, но отлично работает с Arduino Uno
- Как закрыть/закончить Wire.begin()?
- Не могу отключить внутренний интерфейс I2C подтягиваний на ESP32
- Лучший способ отправки команд I2C между Arduino и ESP32
- ESP32: лучший способ встраивания сертификатов
- Как установить подсветку дисплея 16x2 LCD I2C?
Поскольку диапазон
memAddress— [0, 9999], все биты выше 2^13 равны нулю. Поэтому это не может быть причиной проблемы., @the busybee@thebusybee, в техническом описании (стр. 3) говорится, что память «внутренне организована как 512 страниц по 256 байт каждая»., @hcheung
Wire.beginTransmission ((uint8_t)(EPROM_ADDR | (uint8_t) (dataAddress >> 16));и(uint8_t) (memAddress >> 8). Я изменил эту конфигурацию, она верна, но теперь также данные с позиции 0 до 10000 записываются как «1», при этом появляется нежелательный символ (0, 255 и старые данные), только данные примерно 9500 верны, другие данные содержат нежелательный символ., @GopalВнесли ли вы соответствующие изменения в
readEEPROM(uint16_t memAddress)иWire.requestFrom(EEPROM_ADDR, 1);?, @hcheung"_512 страниц по 256 байт_" Да, и для 10 000 байт требуется 40 страниц. Поэтому номер страницы, вычисленный по
memAddress, никогда не изменит старший битP0, который всегда равен 0., @the busybee@hcheung, я уже изменил метод
readEEPROM(uint16_t memAddress), а также ссылку [AT24C1024_lib] (https://github.com/jwhiddon/AT24C1024/blob/master/AT24C1024.cpp), это также мусорное значение приходит, и мое соединение esp32 и AT24C1024[NC, A1, NC, GND, WP - GND ] [VCC - 5 В] [СКЛ - 22] [ПДД - 21], @Gopal