使用ESP32的I2C EEPROM页面写入问题

时间:2018-08-14 17:42:55

标签: c i2c eeprom esp32

我无法使用ESP32将多个字节写入24LC256 EEPROM。

以下功能是负责读写EEPROM的功能。 (我知道使用此EEPROM只能将页面写入限制为64个字节,此代码仅用于测试)

EEPROM写入功能

esp_err_t eeprom_write(uint8_t deviceaddress, uint16_t eeaddress, uint8_t* data, size_t size) {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_WRITE_ADDR, 1);
    i2c_master_write_byte(cmd, eeaddress>>8, 1);
    i2c_master_write_byte(cmd, eeaddress&0xFF, 1);

    i2c_master_write(cmd, data, size, 1);   // Start page write

    i2c_master_stop(cmd);    // Call stop command
    esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000/portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

EEPROM读取功能

esp_err_t eeprom_read(uint8_t deviceaddress, uint16_t eeaddress, uint8_t* data, size_t size) {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (deviceaddress<<1)|EEPROM_WRITE_ADDR, 1);
    i2c_master_write_byte(cmd, eeaddress<<8, 1);
    i2c_master_write_byte(cmd, eeaddress&0xFF, 1);
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (deviceaddress<<1)|EEPROM_READ_ADDR, 1);

    // Sequential read support
    if (size > 1) {
        i2c_master_read(cmd, data, size-1, 0);  // Send ack for these bytes
                                            // as part of a sequential read
    }
    i2c_master_read_byte(cmd, data+size-1, 1);  // Do not ack the last byte
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000/portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

奇怪的是,我能够向EEPROM写13个字节,一切似乎都很好。

eeprom_write(0x50, 0x0000, data_wr, 13);   // Returns ESP_OK
eeprom_read(0x50, 0x0000, data_rd, 64);    // Returns ESP_OK

但是,当向EEPROM写入超过13个字节时,顺序读取功能会出错。

eeprom_write(0x50, 0x0000, data_wr, 14);   // Returns ESP_OK
eeprom_read(0x50, 0x0000, data_rd, 64);    // Return ESP_FAIL

我确定我所做的一切都遵循24LC256数据表的读写规则。有什么我想念的吗?

1 个答案:

答案 0 :(得分:0)

显然,两个调用之间需要的只是短暂的延迟。在ESP32再次调用之前,EEPROM需要一些时间才能将页面缓冲区写入存储单元。

eeprom_write(0x50, 0x0000, data_wr, 64);   // ESP_OK
vTaskDelay(20/portTICK_PERIOD_MS);
eeprom_read(0x50, 0x0000, data_rd, 64);    // ESP_OK

现在一切正常。